more module updates

This commit is contained in:
Bachir Soussi Chiadmi
2015-04-20 18:02:17 +02:00
parent 37fbabab56
commit 7c85261e56
100 changed files with 6518 additions and 913 deletions

View File

@@ -0,0 +1,27 @@
diff --git a/rules.module b/rules.module
index 719852c..9e4ec8f 100644
--- a/rules.module
+++ b/rules.module
@@ -8,6 +8,22 @@
// hook_init().
require_once dirname(__FILE__) . '/modules/events.inc';
+/** Rules >=2.4 introduces a class called 'RulesEventHandlerEntityBundle' found in
+ * 'includes/rules.event.inc', so we include this file for versions older than 2.4
+ * in order to prevent a bug at node/2090511.
+ */
+$result = db_query("SELECT schema_version FROM {system} WHERE name = :name", array(
+ ':name' => 'rules',
+));
+
+if ($result) {
+ while ($row = $result->fetchAssoc()) {
+ if ($row['schema_version'] <7210) {
+ require_once dirname(__FILE__) . '/includes/rules.event.inc';
+ }
+ }
+}
+
/**
* Implements hook_module_implements_alter().
*/

View File

@@ -0,0 +1,411 @@
<?php
/**
* @file
* Contains event handler interface and base classes.
*/
/**
* Interface for handling rules events.
*
* Configurable events (i.e. events making use of settings) have a custom
* event suffix, which gets appended to the base event name. The configured
* event name of, e.g. the event for viewing an article node, would be
* node_view--article, whereas "node_view" is the base event name and "article"
* the event suffix as returned from
* RulesEventHandlerInterface::getEventNameSuffix(). The event suffix is
* generated based upon the event settings and must map to this settings, i.e.
* each set of event settings must always generate the same suffix.
* For a configurable event to be invoked, rules_invoke_event() has to be called
* with the configured event name, e.g.
* @code
* rules_invoke_event('node_view--' . $node->type, $node, $view_mode);
* @endcode
* If the event settings are optional, both events have to be invoked whereas
* usually the more general event is invoked last. E.g.:
* @code
* rules_invoke_event('node_view--' . $node->type, $node, $view_mode);
* rules_invoke_event('node_view', $node, $view_mode);
* @endcode
*
* Rules event handlers have to be declared using the 'class' key in
* hook_rules_event_info(), or may be discovered automatically, see
* rules_discover_plugins() for details.
*
* @see RulesEventHandlerBase
* @see RulesEventDefaultHandler
*/
interface RulesEventHandlerInterface {
/**
* Constructs the event handler.
*
* @param string $event_name
* The base event string.
* @param array $info
* The event info of the given event.
*/
public function __construct($event_name, $info);
/**
* Sets the event settings.
*
* @param array $settings
* An array of settings to set.
*
* @return RulesEventHandlerInterface
* The handler itself for chaining.
*/
public function setSettings(array $settings);
/**
* Gets the event settings.
*
* @return array
* The array of settings.
*/
public function getSettings();
/**
* Returns an array of default settings.
*
* @return array
*/
public function getDefaults();
/**
* Returns a user-facing summary of the settings.
*
* @return string
* The summary in HTML, i.e. properly escaped or filtered.
*/
public function summary();
/**
* Builds the event settings form.
*
* @param array $form_state
* An associative array containing the current state of the form.
*
* @return array
* The form structure.
*/
public function buildForm(array &$form_state);
/**
* Validate the event settings independent from a form submission.
*
* @throws RulesIntegrityException
* In case of validation errors, RulesIntegrityExceptions are thrown.
*/
public function validate();
/**
* Extract the form values and update the event settings.
*
* @param array $form
* An associative array containing the structure of the form.
* @param array $form_state
* An associative array containing the current state of the form.
*/
public function extractFormValues(array &$form, array &$form_state);
/**
* Returns the suffix to be added to the base event named based upon settings.
*
* If event settings are used, the event name Rules uses for the configured
* event is {EVENT_NAME}--{SUFFIX}.
*
* @return string
* The suffix string. Return an empty string for not appending a suffix.
*/
public function getEventNameSuffix();
/**
* Returns info about the variables provided by this event.
*
* @return array
* An array of provided variables, keyed by variable names and with the
* variable info array as value.
*/
public function availableVariables();
/**
* Returns the base name of the event the event handler belongs to.
*
* @return string
* The name of the event the event handler belongs to.
*/
public function getEventName();
/**
* Returns the info array of the event the event handler belongs to.
*
* @return string
* The info array of the event the event handler belongs to.
*/
public function getEventInfo();
}
/**
* Interface for event dispatchers.
*/
interface RulesEventDispatcherInterface extends RulesEventHandlerInterface {
/**
* Starts the event watcher.
*/
public function startWatching();
/**
* Stops the event watcher.
*/
public function stopWatching();
/**
* Returns whether the event dispatcher is currently active.
*
* @return bool
* TRUE if the event dispatcher is currently active, FALSE otherwise.
*/
public function isWatching();
}
/**
* Base class for event handler.
*/
abstract class RulesEventHandlerBase implements RulesEventHandlerInterface {
/**
* The event name.
*
* @var string
*/
protected $eventName;
/**
* The event info.
*
* @var array
*/
protected $eventInfo;
/**
* The event settings.
*
* @var array
*/
protected $settings = array();
/**
* Implements RulesEventHandlerInterface::__construct()
*/
public function __construct($event_name, $info) {
$this->eventName = $event_name;
$this->eventInfo = $info;
$this->settings = $this->getDefaults();
}
/**
* Implements RulesEventHandlerInterface::getSettings()
*/
public function getSettings() {
return $this->settings;
}
/**
* Implements RulesEventHandlerInterface::setSettings()
*/
public function setSettings(array $settings) {
$this->settings = $settings + $this->getDefaults();
return $this;
}
/**
* Implements RulesEventHandlerInterface::validate()
*/
public function validate() {
// Nothing to check by default.
}
/**
* Implements RulesEventHandlerInterface::extractFormValues()
*/
public function extractFormValues(array &$form, array &$form_state) {
foreach ($this->getDefaults() as $key => $setting) {
$this->settings[$key] = isset($form_state['values'][$key]) ? $form_state['values'][$key] : $setting;
}
}
/**
* Implements RulesEventHandlerInterface::availableVariables()
*/
public function availableVariables() {
return isset($this->eventInfo['variables']) ? $this->eventInfo['variables'] : array();
}
/**
* Implements RulesEventHandlerInterface::getEventName()
*/
public function getEventName() {
return $this->eventName;
}
/**
* Implements RulesEventHandlerInterface::getEventInfo()
*/
public function getEventInfo() {
return $this->eventInfo;
}
}
/**
* A handler for events having no settings. This is the default handler.
*/
class RulesEventDefaultHandler extends RulesEventHandlerBase {
/**
* Implements RulesEventHandlerInterface::buildForm()
*/
public function buildForm(array &$form_state) {
return array();
}
/**
* Implements RulesEventHandlerInterface::getConfiguredEventName()
*/
public function getEventNameSuffix() {
return '';
}
/**
* Implements RulesEventHandlerInterface::summary()
*/
public function summary() {
return check_plain($this->eventInfo['label']);
}
/**
* Implements RulesEventHandlerInterface::getDefaults()
*/
public function getDefaults() {
return array();
}
/**
* Implements RulesEventHandlerInterface::getSettings()
*/
public function getSettings() {
return NULL;
}
}
/**
* Exposes the bundle of an entity as event setting.
*/
class RulesEventHandlerEntityBundle extends RulesEventHandlerBase {
protected $entityType, $entityInfo, $bundleKey;
/**
* Implements RulesEventHandlerInterface::__construct()
*/
public function __construct($event_name, $info) {
parent::__construct($event_name, $info);
// Cut off the suffix, e.g. remove 'view' from node_view.
$this->entityType = implode('_', explode('_', $event_name, -1));
$this->entityInfo = entity_get_info($this->entityType);
if (!$this->entityInfo) {
throw new InvalidArgumentException('Unsupported event name passed.');
}
}
/**
* Implements RulesEventHandlerInterface::summary()
*/
public function summary() {
$bundle = &$this->settings['bundle'];
$bundle_label = isset($this->entityInfo['bundles'][$bundle]['label']) ? $this->entityInfo['bundles'][$bundle]['label'] : $bundle;
$suffix = isset($bundle) ? ' ' . t('of @bundle-key %name', array('@bundle-key' => $this->getBundlePropertyLabel(), '%name' => $bundle_label)) : '';
return check_plain($this->eventInfo['label']) . $suffix;
}
/**
* Implements RulesEventHandlerInterface::buildForm()
*/
public function buildForm(array &$form_state) {
$form['bundle'] = array(
'#type' => 'select',
'#title' => t('Restrict by @bundle', array('@bundle' => $this->getBundlePropertyLabel())),
'#description' => t('If you need to filter for multiple values, either add multiple events or use the "Entity is of bundle" condition instead.'),
'#default_value' => $this->settings['bundle'],
'#empty_value' => '',
);
foreach ($this->entityInfo['bundles'] as $name => $bundle_info) {
$form['bundle']['#options'][$name] = $bundle_info['label'];
}
return $form;
}
/**
* Returns the label to use for the bundle property.
*
* @return string
*/
protected function getBundlePropertyLabel() {
return $this->entityInfo['entity keys']['bundle'];
}
/**
* Implements RulesEventHandlerInterface::extractFormValues()
*/
public function extractFormValues(array &$form, array &$form_state) {
$this->settings['bundle'] = !empty($form_state['values']['bundle']) ? $form_state['values']['bundle'] : NULL;
}
/**
* Implements RulesEventHandlerInterface::validate()
*/
public function validate() {
if ($this->settings['bundle'] && empty($this->entityInfo['bundles'][$this->settings['bundle']])) {
throw new RulesIntegrityException(t('The @bundle %bundle of %entity_type is not known.',
array(
'%bundle' => $this->settings['bundle'],
'%entity_type' => $this->entityInfo['label'],
'@bundle' => $this->getBundlePropertyLabel(),
)), array(NULL, 'bundle'));
}
}
/**
* Implements RulesEventHandlerInterface::getConfiguredEventName()
*/
public function getEventNameSuffix() {
return $this->settings['bundle'];
}
/**
* Implements RulesEventHandlerInterface::getDefaults()
*/
public function getDefaults() {
return array(
'bundle' => NULL,
);
}
/**
* Implements RulesEventHandlerInterface::availableVariables()
*/
public function availableVariables() {
$variables = $this->eventInfo['variables'];
if ($this->settings['bundle']) {
// Add the bundle to all variables of the entity type.
foreach ($variables as $name => $variable_info) {
if ($variable_info['type'] == $this->entityType) {
$variables[$name]['bundle'] = $this->settings['bundle'];
}
}
}
return $variables;
}
}

View File

@@ -0,0 +1,134 @@
<?php
/**
* @file
* Rules module drush integration.
*/
/**
* Implements hook_drush_command().
*
* @return
* An associative array describing your command(s).
*
* @see drush_parse_command()
*/
function rules_drush_command() {
$items = array();
$items['rules-list'] = array(
'description' => "List all the active and inactive rules for your site.",
'drupal dependencies' => array('rules'),
'aliases' => array('rules'),
);
$items['rules-enable'] = array(
'description' => "Enable a rule on your site.",
'arguments' => array(
'rule' => 'Rule name to enable.',
),
'drupal dependencies' => array('rules'),
'aliases' => array('re'),
);
$items['rules-disable'] = array(
'description' => "Disable a rule on your site.",
'arguments' => array(
'rule' => 'Rule name to export.',
),
'drupal dependencies' => array('rules'),
'aliases' => array('rd'),
);
return $items;
}
/**
* Implements hook_drush_help().
*/
function rules_drush_help($section) {
switch ($section) {
case 'drush:rules':
return dt("List all the rules on your site.");
case 'drush:rules-enable':
return dt("Enable/activate a rule on your site.");
case 'drush:rules-disable':
return dt("Disable/deactivate a rule on your site.");
}
}
/**
* Get a list of all rules.
*/
function drush_rules_list() {
$rules = rules_config_load_multiple(FALSE);
$rows = array(array(dt('Rule'), dt('Label'), dt('Event'), dt('Active'), dt('Status')));
foreach ($rules as $rule) {
if (!empty($rule->name) && !empty($rule->label)) {
$events = array();
$event_info = rules_fetch_data('event_info');
if ($rule instanceof RulesTriggerableInterface) {
foreach ($rule->events() as $event_name) {
$event_info += array($event_name => array('label' => dt('Unknown event "!event_name"', array('!event_name' => $event_name))));
$events[] = check_plain($event_info[$event_name]['label']);
}
}
$rows[] = array(
$rule->name,
$rule->label,
implode(', ', $events),
$rule->active ? dt('Enabled') : dt('Disabled'),
$rule->status ? theme('entity_status', array('status' => $rule->status, 'html' => FALSE)) : '',
);
}
}
drush_print_table($rows, TRUE);
}
/**
* Enable a rule on the site.
*/
function drush_rules_enable() {
$args = func_get_args();
$rule_name = (!empty($args) && is_array($args)) ? array_shift($args) : '';
if (empty($rule_name)) {
return drush_set_error('', 'No rule name given.');
}
$rule = rules_config_load($rule_name);
if (empty($rule)) {
return drush_set_error('', dt('Could not load rule named "!rule-name".', array('!rule-name' => $rule_name)));
}
if (empty($rule->active)) {
$rule->active = TRUE;
$rule->save();
drush_log(dt('The rule "!name" has been enabled.', array('!name' => $rule_name)), 'success');
}
else {
drush_log(dt('The rule "!name" is already enabled.', array('!name' => $rule_name)), 'warning');
}
}
/**
* Disable a rule on the site.
*/
function drush_rules_disable() {
$args = func_get_args();
$rule_name = (!empty($args) && is_array($args)) ? array_shift($args) : '';
if (empty($rule_name)) {
return drush_set_error('', 'No rule name given.');
}
$rule = rules_config_load($rule_name);
if (empty($rule)) {
return drush_set_error('', dt('Could not load rule named "!rule-name".', array('!rule-name' => $rule_name)));
}
if (!empty($rule->active)) {
$rule->active = FALSE;
$rule->save();
drush_log(dt('The rule "!name" has been disabled.', array('!name' => $rule_name)), 'success');
}
else {
drush_log(dt('The rule "!name" is already disabled.', array('!name' => $rule_name)), 'warning');
}
}

View File

@@ -0,0 +1,99 @@
<?php
/**
* Default scheduled task handler.
*/
class RulesSchedulerDefaultTaskHandler implements RulesSchedulerTaskHandlerInterface {
/**
* The task array.
*
* @var array
*/
protected $task;
/**
* Constructs a repetitive task handler object.
*/
public function __construct(array $task) {
$this->task = $task;
}
/**
* Implements RulesSchedulerTaskHandlerInterface::runTask().
*/
public function runTask() {
if ($component = rules_get_cache('comp_' . $this->task['config'])) {
$replacements = array('%label' => $component->label(), '%plugin' => $component->plugin());
$replacements['%identifier'] = $this->task['identifier'] ? $this->task['identifier'] : t('without identifier');
rules_log('Scheduled evaluation of %plugin %label, task %identifier.', $replacements, RulesLog::INFO, $component, TRUE);
$state = unserialize($this->task['data']);
$state->restoreBlocks();
// Block the config to prevent any future recursion.
$state->block($component);
// Finally evaluate the component with the given state.
$component->evaluate($state);
$state->unblock($component);
rules_log('Finished evaluation of %plugin %label, task %identifier.', $replacements, RulesLog::INFO, $component, FALSE);
$state->cleanUp();
}
}
/**
* Implements RulesSchedulerTaskHandlerInterface::afterTaskQueued().
*/
public function afterTaskQueued() {
// Delete the task from the task list.
db_delete('rules_scheduler')
->condition('tid', $this->task['tid'])
->execute();
}
/**
* Implements RulesSchedulerTaskHandlerInterface::getTask().
*/
public function getTask() {
return $this->task;
}
}
/**
* Interface for scheduled task handlers.
*
* Task handlers control the behavior of a task when it's queued or executed.
* Unless specified otherwise, the RulesSchedulerDefaultTaskHandler task handler
* is used.
*
* @see rules_scheduler_run_task()
* @see rules_scheduler_cron()
* @see RulesSchedulerDefaultTaskHandler
*/
interface RulesSchedulerTaskHandlerInterface {
/**
* Processes a queue item.
*
* @throws RulesEvaluationException
* If there are any problems executing the task.
*
* @see rules_scheduler_run_task()
*/
public function runTask();
/**
* Processes a task after it has been queued.
*
* @see rules_scheduler_cron()
*/
public function afterTaskQueued();
/**
* Returns the task associated with the task handler.
*
* @return array
* The task (queue item) array.
*/
public function getTask();
}

View File

@@ -0,0 +1,81 @@
<?php
/**
* @file
* Rules Scheduler Drush integration.
*/
/**
* Implements hook_drush_command().
*/
function rules_scheduler_drush_command() {
$items = array();
$items['rules-scheduler-tasks'] = array(
'description' => 'Checks for scheduled tasks to be added to the queue.',
'options' => array(
'claim' => 'Optionally claim tasks from the queue to work on. Any value set will override the default time spent on this queue.',
),
'drupal dependencies' => array('rules', 'rules_scheduler'),
'aliases' => array('rusch'),
'examples' => array(
'drush rusch' => 'Add scheduled tasks to the queue.',
'drush rusch --claim' => 'Add scheduled tasks to the queue and claim items for the default amount of time.',
'drush rusch --claim=30' => 'Add schedules tasks to the queue and claim items for 30 seconds.',
),
);
return $items;
}
/**
* Implements hook_drush_help().
*/
function rules_scheduler_drush_help($section) {
switch ($section) {
case 'drush:rules-scheduler-tasks':
return dt('Checks for scheduled tasks to be added the queue. Can optionally claim tasks from the queue to work on.');
}
}
/**
* Command callback for processing the rules_scheduler_tasks queue.
*
* @see rules_scheduler_cron_queue_info().
* @see rules_scheduler_cron().
*/
function drush_rules_scheduler_tasks() {
if (rules_scheduler_queue_tasks()) {
// hook_exit() is not invoked for drush runs, so register it as shutdown
// callback for logging the rules log to the watchdog.
drupal_register_shutdown_function('rules_exit');
// Clear the log before running tasks via the queue to avoid logging
// unrelated logs from previous operations.
RulesLog::logger()->clear();
drush_log(dt('Added scheduled tasks to the queue.'), 'success');
}
$claim = drush_get_option('claim', FALSE);
if ($claim) {
// Fetch the queue information and let other modules alter it.
$queue_name = 'rules_scheduler_tasks';
$info = module_invoke('rules_scheduler', 'cron_queue_info');
drupal_alter('cron_queue_info', $info);
$function = $info[$queue_name]['worker callback'];
// The drush option can override the default process time.
$time = is_numeric($claim) ? (int) $claim : $info[$queue_name]['time'];
$end = time() + $time;
// Claim items and process the queue.
$queue = DrupalQueue::get($queue_name);
$claimed = 0;
while (time() < $end && ($item = $queue->claimItem())) {
$function($item->data);
$queue->deleteItem($item);
$claimed++;
}
if ($claimed) {
drush_log(dt('Claimed and worked on !claimed scheduled tasks for up to !time seconds.', array('!claimed' => $claimed, '!time' => $time)), 'success');
}
}
}

View File

@@ -0,0 +1,24 @@
<?php
/**
* @file
* Include file for Rules Scheduler tests.
*/
/**
* Test task handler class.
*/
class RulesTestTaskHandler extends RulesSchedulerDefaultTaskHandler {
/**
* Overrides RulesSchedulerDefaultTaskHandler::runTask().
*/
public function runTask() {
$task = $this->getTask();
$data = unserialize($task['data']);
// Set the variable defined in the test to TRUE.
variable_set($data['variable'], TRUE);
}
}

View File

@@ -0,0 +1,13 @@
name = "Rules Scheduler Tests"
description = "Support module for the Rules Scheduler tests."
package = Testing
core = 7.x
files[] = rules_scheduler_test.inc
hidden = TRUE
; Information added by Drupal.org packaging script on 2015-03-16
version = "7.x-2.9"
core = "7.x"
project = "rules"
datestamp = "1426527210"

View File

@@ -0,0 +1,6 @@
<?php
/**
* @file
* Rules Scheduler test module.
*/

View File

@@ -0,0 +1,12 @@
name = "Rules Test invocation"
description = "Helper module to test Rules invocations."
package = Testing
core = 7.x
hidden = TRUE
; Information added by Drupal.org packaging script on 2015-03-16
version = "7.x-2.9"
core = "7.x"
project = "rules"
datestamp = "1426527210"

View File

@@ -0,0 +1,13 @@
<?php
/**
* @file
* Helper module for Rules invocation testing.
*/
/**
* Implements hook_node_load().
*/
function rules_test_invocation_node_load($nodes, $types) {
rules_invoke_event('rules_test_event');
}