updated webform, webform_localization, profile2, term_merge, search_api_saved_pages, rules, redirect, overide_node_options

This commit is contained in:
2019-05-13 18:47:27 +02:00
parent 58cd990c8c
commit 9adc940a67
281 changed files with 28658 additions and 7138 deletions

View File

@@ -81,7 +81,7 @@ Drupal.rules = Drupal.rules || {};
this.jqObject.bind("autocompleteselect", function(event, ui) {
// If a group was selected then set the groupSelected to true for the
// overriden close function from jquery autocomplete.
// overridden close function from jquery autocomplete.
if (ui.item.value.substring(ui.item.value.length - 1, ui.item.value.length) == ":") {
instance.groupSelected = true;
}
@@ -103,14 +103,18 @@ Drupal.rules = Drupal.rules || {};
});
});
// Newer versions of jQuery UI use element.data('ui-autocomplete'), older
// versions use element.data('autocomplete').
var autocompleteDataKey = typeof(this.jqObject.data('autocomplete')) === 'object' ? 'autocomplete' : 'ui-autocomplete';
// Since jquery autocomplete by default strips html text by using .text()
// we need our own _renderItem function to display html content.
this.jqObject.data("autocomplete")._renderItem = function(ul, item) {
this.jqObject.data(autocompleteDataKey)._renderItem = function(ul, item) {
return $("<li></li>").data("item.autocomplete", item).append("<a>" + item.label + "</a>").appendTo(ul);
};
// Override close function
this.jqObject.data("autocomplete").close = function (event) {
this.jqObject.data(autocompleteDataKey).close = function (event) {
var value = this.element.val();
// If the selector is not a group, then trigger the close event an and
// hide the menu.
@@ -119,7 +123,10 @@ Drupal.rules = Drupal.rules || {};
if (this.menu.element.is(":visible")) {
this._trigger("close", event);
this.menu.element.hide();
this.menu.deactivate();
// Use deactivate for older versions of jQuery UI.
if (typeof(this.menu.deactivate) === 'function') {
this.menu.deactivate();
}
}
}
else {
@@ -173,7 +180,7 @@ Drupal.rules = Drupal.rules || {};
};
/**
* Toogle the autcomplete window.
* Toggle the autocomplete window.
*/
Drupal.rules.autocomplete.prototype.toggle = function() {
if (this.jqObject.autocomplete("widget").is(":visible")) {

View File

@@ -1,10 +1,12 @@
@CHARSET "UTF-8";
@charset "utf-8";
.rules-show-js, html.js .rules-hide-js {
.rules-show-js,
html.js .rules-hide-js {
display: none;
}
.rules-hide-js, html.js .rules-show-js {
.rules-hide-js,
html.js .rules-show-js {
display: block;
}
@@ -58,7 +60,8 @@ ul.rules-operations-add li {
right: 0px;
}
.rules-elements-table caption, .rules-overview-table caption {
.rules-elements-table caption,
.rules-overview-table caption {
font-size: 110%;
font-weight: bold;
padding-bottom: 0.5em;
@@ -85,8 +88,7 @@ ul.rules-operations-add li {
.rules-debug-collapsible-link {
position: relative;
cursor: pointer;
/* The span element with the icon which opens the log, has a whitepsace.
/* The span element with the icon which opens the log, has a whitespace.
Since we don't want the user to mark this white space, we prevent this
using the this code.*/
-moz-user-select: -moz-none;
@@ -191,6 +193,6 @@ ul.rules-autocomplete .ui-corner-all {
}
/* IE 6 hack for max-height. */
* html ul.rule-autocomplete{
* html ul.rule-autocomplete {
height: 23em;
}

View File

@@ -1,7 +1,8 @@
<?php
/**
* @file Contains the UI controller for Rules.
* @file
* Contains the UI controller for Rules.
*/
/**
@@ -35,8 +36,8 @@ class RulesUIController {
);
$items[$base_path . '/manage/%rules_config/add/%rules_element'] = array(
// Adding another part to the path would hit the menu path-part-limit
// for base paths like admin/config/workflow/rules. Therefor we have to
// use this fugly way for setting the title.
// for base paths like admin/config/workflow/rules. Therefore we have to
// use this ugly way for setting the title.
'title callback' => 'rules_menu_add_element_title',
// Wrap the integer in an array, so it is passed as is.
'title arguments' => array(array($base_count + 4)),
@@ -52,7 +53,7 @@ class RulesUIController {
'title callback' => 'rules_get_title',
'title arguments' => array('Adding event to !plugin "!label"', $base_count + 1),
'page callback' => 'drupal_get_form',
'page arguments' => array('rules_ui_add_event', $base_count + 1, $base_path),
'page arguments' => array('rules_ui_add_event_page', $base_count + 1, $base_path),
'access callback' => 'rules_config_access',
'access arguments' => array('update', $base_count + 1),
'load arguments' => array($base_count + 1),
@@ -60,7 +61,7 @@ class RulesUIController {
'file path' => drupal_get_path('module', 'rules'),
);
$items[$base_path . '/manage/%rules_config/delete/event'] = array(
//@todo: improve title.
// @todo Improve title.
'title' => 'Remove event',
'page callback' => 'drupal_get_form',
'page arguments' => array('rules_ui_remove_event', $base_count + 1, $base_count + 4, $base_path),
@@ -157,8 +158,10 @@ class RulesUIController {
}
/**
* Generates the render array for a overview configuration table for arbitrary
* rule configs that match the given conditions.
* Generates the render array for an overview configuration table.
*
* Generates the render array for an overview configuration table for
* arbitrary rule configs that match the given conditions.
*
* Note: The generated overview table contains multiple links for editing the
* rule configurations. For the links to properly work use
@@ -182,7 +185,7 @@ class RulesUIController {
* currently set RulesPluginUI::$basePath. If no base path has been set
* yet, the current path is used by default.
*
* @return Array
* @return array
* A renderable array.
*/
public function overviewTable($conditions = array(), $options = array()) {
@@ -192,10 +195,14 @@ class RulesUIController {
'show events' => isset($conditions['plugin']) && $conditions['plugin'] == 'reaction rule',
'show execution op' => !(isset($conditions['plugin']) && $conditions['plugin'] == 'reaction rule'),
);
// By default show only configurations owned by rules.
$conditions += array(
'owner' => 'rules',
);
if (!empty($options['base path'])) {
RulesPluginUI::$basePath = $options['base path'];
}
else if (!isset(RulesPluginUI::$basePath)) {
elseif (!isset(RulesPluginUI::$basePath)) {
// Default to the current path, only if no path has been set yet.
RulesPluginUI::$basePath = current_path();
}
@@ -237,7 +244,7 @@ class RulesUIController {
$table['#attributes']['class'][] = 'rules-overview-table';
$table['#attached']['css'][] = drupal_get_path('module', 'rules') . '/ui/rules.ui.css';
// TODO: hide configs where access() is FALSE.
// @todo Hide configs where access() is FALSE.
return $table;
}
@@ -257,8 +264,8 @@ class RulesUIController {
$events = array();
if ($config instanceof RulesTriggerableInterface) {
foreach ($config->events() as $event_name) {
$this->event_info += array($event_name => array('label' => t('Unknown event "!event_name"', array('!event_name' => $event_name))));
$events[] = check_plain($this->event_info[$event_name]['label']);
$event_handler = rules_get_event_handler($event_name, $config->getEventSettings($event_name));
$events[] = $event_handler->summary();
}
}
$row[] = implode(", ", $events);
@@ -275,12 +282,16 @@ class RulesUIController {
// Add operations depending on the options and the exportable status.
if (!$config->hasStatus(ENTITY_FIXED)) {
$row[] = l(t('edit'), RulesPluginUI::path($name), array('attributes' => array('class' => array('edit', 'action'))));
$row[] = l(t('translate'), RulesPluginUI::path($name, 'translate'), array('attributes' => array('class' => array('translate', 'action'))));
$row[] = l(t('edit'), RulesPluginUI::path($name), array('attributes' => array('class' => array('edit', 'action'))));
if (module_exists('rules_i18n')) {
$row[] = l(t('translate'), RulesPluginUI::path($name, 'translate'), array('attributes' => array('class' => array('translate', 'action'))));
}
}
else {
$row[] = '';
$row[] = '';
if (module_exists('rules_i18n')) {
$row[] = '';
}
}
if (!$options['hide status op']) {
@@ -313,4 +324,5 @@ class RulesUIController {
$row[] = l(t('export'), RulesPluginUI::path($name, 'export'), array('attributes' => array('class' => array('export', 'action'))));
return $row;
}
}

View File

@@ -1,7 +1,8 @@
<?php
/**
* @file Contains core ui functions.
* @file
* Contains core Rules UI functions.
*/
/**
@@ -10,9 +11,10 @@
interface RulesPluginUIInterface {
/**
* Adds the whole configuration form of this rules configuration. For rule
* elements that are part of a configuration this method just adds the
* elements configuration form.
* Adds the whole configuration form of this rules configuration.
*
* For rule elements that are part of a configuration this method just adds
* the elements configuration form.
*
* @param $form
* The form array where to add the form.
@@ -37,8 +39,7 @@ interface RulesPluginUIInterface {
* - 'restrict events': Optionally set an array of event names to restrict
* the events that are available for adding.
*
* @todo
* Implement the 'restrict *' options.
* @todo Implement the 'restrict *' options.
*/
public function form(&$form, &$form_state, $options = array());
@@ -51,6 +52,8 @@ interface RulesPluginUIInterface {
public function form_validate($form, &$form_state);
/**
* Form submit handler for the element configuration form.
*
* Submit the configuration form of this rule element. This makes sure to
* put the updated configuration in the form state. For saving changes
* permanently, just call $config->save() afterwards.
@@ -135,11 +138,13 @@ class RulesElementMap {
}
return isset($this->index[$id]) ? $this->index[$id] : FALSE;
}
}
/**
* Faces UI extender for all kind of Rules plugins. Provides various useful
* methods for any rules UI.
* Faces UI extender for all kind of Rules plugins.
*
* Provides various useful methods for any rules UI.
*/
class RulesPluginUI extends FacesExtender implements RulesPluginUIInterface {
@@ -149,10 +154,11 @@ class RulesPluginUI extends FacesExtender implements RulesPluginUIInterface {
protected $element;
/**
* The base path determines where a Rules overview UI lives. All forms that
* want to display Rules (overview) forms need to set this variable. This is
* necessary in order to get correct operation links, paths, redirects, bread
* crumbs etc. for the form() and overviewTable() methods.
* The base path determines where a Rules overview UI lives.
*
* All forms that want to display Rules (overview) forms need to set this
* variable. This is necessary in order to get correct operation links,
* paths, redirects, breadcrumbs etc. for the form() and overviewTable() methods.
*
* @see RulesUIController
* @see rules_admin_reaction_overview()
@@ -193,8 +199,7 @@ class RulesPluginUI extends FacesExtender implements RulesPluginUIInterface {
}
/**
* Implements RulesPluginUIInterface.
* Generates the element edit form.
* Implements RulesPluginUIInterface. Generates the element edit form.
*
* Note: Make sure that you set RulesPluginUI::$basePath before using this
* method, otherwise paths, links, redirects etc. won't be correct.
@@ -257,7 +262,7 @@ class RulesPluginUI extends FacesExtender implements RulesPluginUIInterface {
);
}
if (!empty($form['provides'])) {
$help = '<div class="description">' . t('Adjust the names and labels of provided variables, but note that renaming of already utilizied variables invalidates the existing uses.') . '</div>';
$help = '<div class="description">' . t('Adjust the names and labels of provided variables, but note that renaming of already utilized variables invalidates the existing uses.') . '</div>';
$form['provides'] += array(
'#tree' => TRUE,
'#prefix' => '<h4 class="rules-form-heading">' . t('Provided variables') . '</h4>' . $help,
@@ -304,8 +309,8 @@ class RulesPluginUI extends FacesExtender implements RulesPluginUIInterface {
}
// For translatable parameters, pre-populate an internal translation source
// key so data type forms or input evaluators (i18n) may produce suiting
// help.
// key so data type forms or input evaluators (i18n) may show a suitable
// help message.
if (drupal_multilingual() && !empty($info['translatable'])) {
$parameter = $this->element->pluginParameterInfo();
$info['custom translation language'] = !empty($parameter['language']);
@@ -320,7 +325,7 @@ class RulesPluginUI extends FacesExtender implements RulesPluginUIInterface {
}
// Add a link for switching the input mode when JS is enabled and a button
// to switch it without javascript, in case switching is possible.
// to switch it without JavaScript, in case switching is possible.
if ($supports_input_mode && empty($info['restriction'])) {
$value = $mode == 'selector' ? t('Switch to the direct input mode') : t('Switch to data selection');
@@ -420,6 +425,8 @@ class RulesPluginUI extends FacesExtender implements RulesPluginUIInterface {
'#required' => TRUE,
'#weight' => -5,
);
// @todo For Drupal 8 use "owner" for generating machine names and
// module only for the modules providing default configurations.
if (!empty($this->element->module) && !empty($this->element->name) && $this->element->module == 'rules' && strpos($this->element->name, 'rules_') === 0) {
// Remove the Rules module prefix from the machine name.
$machine_name = substr($this->element->name, strlen($this->element->module) + 1);
@@ -455,7 +462,7 @@ class RulesPluginUI extends FacesExtender implements RulesPluginUIInterface {
$description = t('The variables used by the component. They can not be edited for configurations that are provided in code.');
}
else {
$description = t('Variables are normally input <em>parameters</em> for the component data that should be available for the component to act on. Additionaly, action components may <em>provide</em> variables back to the caller. Each variable must have a specified data type, a label and a unique machine readable name containing only lowercase alphanumeric characters and underscores. See <a href="@url">the online documentation</a> for more information about variables.',
$description = t('Variables are normally input <em>parameters</em> for the component data that should be available for the component to act on. Additionally, action components may <em>provide</em> variables back to the caller. Each variable must have a specified data type, a label and a unique machine readable name containing only lowercase alphanumeric characters and underscores. See <a href="@url">the online documentation</a> for more information about variables.',
array('@url' => rules_external_help('variables'))
);
}
@@ -500,7 +507,7 @@ class RulesPluginUI extends FacesExtender implements RulesPluginUIInterface {
'#type' => 'checkbox',
'#title' => t('Configure access for using this component with a permission.'),
'#default_value' => !empty($this->element->access_exposed),
'#description' => t('By default, the @plugin-type for using this component may be only used by users that have access to configure the component. If checked, access is determined by a permission instead.', array('@plugin-type' => $plugin_type))
'#description' => t('By default, the @plugin-type for using this component may be only used by users that have access to configure the component. If checked, access is determined by a permission instead.', array('@plugin-type' => $plugin_type)),
);
$form['settings']['access']['permissions'] = array(
'#type' => 'container',
@@ -514,7 +521,7 @@ class RulesPluginUI extends FacesExtender implements RulesPluginUIInterface {
}
}
// TODO: Attach field form thus description.
// @todo Attach field form thus description.
}
/**
@@ -565,11 +572,11 @@ class RulesPluginUI extends FacesExtender implements RulesPluginUIInterface {
$form_values = RulesPluginUI::getFormStateValues($form['settings'], $form_state);
$this->element->label = $form_values['label'];
// If the name was changed we have to redirect to the URL that contains
// the new name, instead of rebuilding on the old URL with the old name
// the new name, instead of rebuilding on the old URL with the old name.
if ($form['settings']['name']['#default_value'] != $form_values['name']) {
$module = isset($this->element->module) ? $this->element->module : 'rules';
$this->element->name = $module . '_' . $form_values['name'];
$form_state['redirect'] = RulesPluginUI::path($this->element->name);
$form_state['redirect'] = RulesPluginUI::path($this->element->name, 'edit', $this->element);
}
$this->element->tags = empty($form_values['tags']) ? array() : drupal_explode_tags($form_values['tags']);
@@ -667,22 +674,28 @@ class RulesPluginUI extends FacesExtender implements RulesPluginUIInterface {
* Returns the name of class for the given data type.
*
* @param $data_type
* The name of the data typ
* The name of the data type
* @param $parameter_info
* (optional) An array of info about the to be configured parameter.
* (optional) An array of info about the to be configured parameter. If
* given, this array is complemented with data type defaults also.
*/
public function getDataTypeClass($data_type, $parameter_info = array()) {
if (!empty($parameter_info['ui class'])) {
return $parameter_info['ui class'];
}
public function getDataTypeClass($data_type, &$parameter_info = array()) {
$cache = rules_get_cache();
$data_info = $cache['data_info'];
return (is_string($data_type) && isset($data_info[$data_type]['ui class'])) ? $data_info[$data_type]['ui class'] : 'RulesDataUI';
// Add in data-type defaults.
if (empty($parameter_info['ui class'])) {
$parameter_info['ui class'] = (is_string($data_type) && isset($data_info[$data_type]['ui class'])) ? $data_info[$data_type]['ui class'] : 'RulesDataUI';
}
if (is_subclass_of($parameter_info['ui class'], 'RulesDataInputOptionsListInterface')) {
$parameter_info['options list'] = array($parameter_info['ui class'], 'optionsList');
}
return $parameter_info['ui class'];
}
/**
* Implements RulesPluginUIInterface.
* Show a preview of the configuration settings.
*
* Shows a preview of the configuration settings.
*/
public function buildContent() {
$config_name = $this->element->root()->name;
@@ -691,7 +704,7 @@ class RulesPluginUI extends FacesExtender implements RulesPluginUIInterface {
'#title' => $this->element->label(),
'#href' => $this->element->isRoot() ? RulesPluginUI::path($config_name) : RulesPluginUI::path($config_name, 'edit', $this->element),
'#prefix' => '<div class="rules-element-label">',
'#suffix' => '</div>'
'#suffix' => '</div>',
);
// Put the elements below in a "description" div.
$content['description'] = array(
@@ -705,14 +718,14 @@ class RulesPluginUI extends FacesExtender implements RulesPluginUIInterface {
$element = array();
if (!empty($this->element->settings[$name . ':select'])) {
$element['content'] = array(
'#markup' => '[' . $this->element->settings[$name . ':select'] . ']',
'#markup' => '[' . $this->element->settings[$name . ':select'] . ']',
);
}
elseif (isset($this->element->settings[$name]) && (!isset($parameter['default value']) || $parameter['default value'] != $this->element->settings[$name])) {
$method = empty($parameter['options list']) ? 'render' : 'renderOptionsLabel';
$class = $this->getDataTypeClass($parameter['type'], $parameter);
// We cannot use method_exists() here as it would trigger a PHP bug,
// @see http://drupal.org/node/1258284
$method = empty($parameter['options list']) ? 'render' : 'renderOptionsLabel';
// We cannot use method_exists() here as it would trigger a PHP bug.
// @see https://www.drupal.org/node/1258284
$element = call_user_func(array($class, $method), $this->element->settings[$name], $name, $parameter, $this->element);
}
// Only add parameters that are really configured / not default.
@@ -795,7 +808,6 @@ class RulesPluginUI extends FacesExtender implements RulesPluginUIInterface {
*/
public function help() {}
/**
* Deprecated by the controllers overviewTable() method.
*/
@@ -804,6 +816,8 @@ class RulesPluginUI extends FacesExtender implements RulesPluginUIInterface {
}
/**
* Generates an operation path.
*
* Generates a path using the given operation for the element with the given
* id of the configuration with the given name.
*/
@@ -817,12 +831,19 @@ class RulesPluginUI extends FacesExtender implements RulesPluginUIInterface {
else {
$base_path = isset($element) && $element instanceof RulesTriggerableInterface ? 'admin/config/workflow/rules/reaction' : 'admin/config/workflow/rules/components';
}
return implode('/', array_filter(array($base_path . '/manage', $name, $op, $element_id, $parameter)));
// Only append the '/manage' path if it is not already present.
if (substr($base_path, -strlen('/manage')) != '/manage') {
$base_path .= '/manage';
}
return implode('/', array_filter(array($base_path, $name, $op, $element_id, $parameter)));
}
/**
* Determines the default redirect target for an edited/deleted element. This
* is a parent element which is either a rule or the configuration root.
* Determines the default redirect target for an edited/deleted element.
*
* This is a parent element which is either a rule or the configuration root.
*/
public static function defaultRedirect(RulesPlugin $element) {
while (!$element->isRoot()) {
@@ -835,47 +856,10 @@ class RulesPluginUI extends FacesExtender implements RulesPluginUIInterface {
}
/**
* Returns an array of options to use with a select for the items specified
* in the given hook.
*
* @param $item_type
* The item type to get options for. One of 'data', 'event', 'condition' and
* 'action'.
* @param $items
* (optional) An array of items to restrict the options to.
*
* @return
* An array of options.
* @see RulesUICategory::getOptions()
*/
public static function getOptions($item_type, $items = NULL) {
$sorted_data = array();
$ungrouped = array();
$data = $items ? $items : rules_fetch_data($item_type . '_info');
foreach ($data as $name => $info) {
// Verfiy the current user has access to use it.
if (!user_access('bypass rules access') && !empty($info['access callback']) && !call_user_func($info['access callback'], $item_type, $name)) {
continue;
}
if (!empty($info['group'])) {
$sorted_data[drupal_ucfirst($info['group'])][$name] = drupal_ucfirst($info['label']);
}
else {
$ungrouped[$name] = drupal_ucfirst($info['label']);
}
}
asort($ungrouped);
foreach ($sorted_data as $key => $choices) {
asort($choices);
$sorted_data[$key] = $choices;
}
ksort($sorted_data);
// Always move the 'Components' group down it it exists.
if (isset($sorted_data[t('Components')])) {
$copy = $sorted_data[t('Components')];
unset($sorted_data[t('Components')]);
$sorted_data[t('Components')] = $copy;
}
return $ungrouped + $sorted_data;
return RulesUICategory::getOptions($item_type, $items = NULL);
}
public static function formDefaults(&$form, &$form_state) {
@@ -909,6 +893,7 @@ class RulesPluginUI extends FacesExtender implements RulesPluginUIInterface {
->fetchCol('tag');
return drupal_map_assoc($result);
}
}
/**
@@ -917,6 +902,8 @@ class RulesPluginUI extends FacesExtender implements RulesPluginUIInterface {
class RulesAbstractPluginUI extends RulesPluginUI {
/**
* Overrides RulesPluginUI::form().
*
* Overridden to invoke the abstract plugins form alter callback and to add
* the negation checkbox for conditions.
*/
@@ -953,6 +940,7 @@ class RulesAbstractPluginUI extends RulesPluginUI {
form_set_error(implode('][', $e->keys), $e->getMessage());
}
}
}
/**
@@ -971,11 +959,11 @@ class RulesContainerPluginUI extends RulesPluginUI {
'#tree' => TRUE,
'#theme' => 'rules_elements',
'#empty' => t('None'),
'#caption' => t('Elements')
'#caption' => t('Elements'),
);
$form['elements']['#attributes']['class'][] = 'rules-container-plugin';
// Recurse over all element childrens or use the provided iterator.
// Recurse over all element children or use the provided iterator.
$iterator = isset($iterator) ? $iterator : $this->element->elements();
$root_depth = $this->element->depth();
foreach ($iterator as $key => $child) {
@@ -991,11 +979,11 @@ class RulesContainerPluginUI extends RulesPluginUI {
$form['elements'][$id]['weight'] = array(
'#type' => 'weight',
'#default_value' => $child->weight,
'#delta' => 20,
'#delta' => 50,
);
$form['elements'][$id]['parent_id'] = array(
'#type' => 'hidden',
// If another iterator is passed in, the childs parent may not equal
// If another iterator is passed in, the child parent may not equal
// the current element. Thus ask the child for its parent.
'#default_value' => $child->parentElement()->elementId(),
);
@@ -1061,12 +1049,10 @@ class RulesContainerPluginUI extends RulesPluginUI {
return $render;
}
public function buildContent() {
$content = parent::buildContent();
// Don't link the title for embedded container plugins, except for rules.
if (!$this->element->isRoot() && !($this->element instanceof Rule)) {
$content['label']['#type'] = 'markup';
$content['label']['#markup'] = check_plain($content['label']['#title']);
unset($content['label']['#title']);
}
@@ -1109,6 +1095,7 @@ class RulesContainerPluginUI extends RulesPluginUI {
}
return $content;
}
}
/**
@@ -1123,7 +1110,7 @@ class RulesConditionContainerUI extends RulesContainerPluginUI {
$form['elements']['#attributes']['class'][] = 'rules-condition-container';
$form['elements']['#caption'] = t('Conditions');
// By default skip
// By default skip.
if (!empty($options['init']) && !$this->element->isRoot()) {
$config = $this->element->root();
$form['init_help'] = array(
@@ -1154,6 +1141,7 @@ class RulesConditionContainerUI extends RulesContainerPluginUI {
$this->element->negate($form_values['negate']);
}
}
}
/**
@@ -1162,10 +1150,148 @@ class RulesConditionContainerUI extends RulesContainerPluginUI {
class RulesActionContainerUI extends RulesContainerPluginUI {
public function form(&$form, &$form_state, $options = array(), $iterator = NULL) {
parent::form($form, $form_state, $options, $iterator);
parent::form($form, $form_state, $options, $iterator);
// Add the add-* operation links.
$form['elements']['#add'] = self::addOperations();
$form['elements']['#attributes']['class'][] = 'rules-action-container';
$form['elements']['#caption'] = t('Actions');
}
}
/**
* Class holding category related methods.
*/
class RulesUICategory {
/**
* Gets info about all available categories, or about a specific category.
*
* @return array
*/
public static function getInfo($category = NULL) {
$data = rules_fetch_data('category_info');
if (isset($category)) {
return $data[$category];
}
return $data;
}
/**
* Returns a group label, e.g. as usable for opt-groups in a select list.
*
* @param array $item_info
* The info-array of an item, e.g. an entry of hook_rules_action_info().
* @param bool $in_category
* (optional) Whether group labels for grouping inside a category should be
* return. Defaults to FALSE.
*
* @return string|bool
* The group label to use, or FALSE if none can be found.
*/
public static function getItemGroup($item_info, $in_category = FALSE) {
if (isset($item_info['category']) && !$in_category) {
return self::getCategory($item_info, 'label');
}
elseif (!empty($item_info['group'])) {
return $item_info['group'];
}
return FALSE;
}
/**
* Gets the category for the given item info array.
*
* @param array $item_info
* The info-array of an item, e.g. an entry of hook_rules_action_info().
* @param string|null $key
* (optional) The key of the category info to return, e.g. 'label'. If none
* is given the whole info array is returned.
*
* @return array|mixed|false
* Either the whole category info array or the value of the given key. If
* no category can be found, FALSE is returned.
*/
public static function getCategory($item_info, $key = NULL) {
if (isset($item_info['category'])) {
$info = self::getInfo($item_info['category']);
return isset($key) ? $info[$key] : $info;
}
return FALSE;
}
/**
* Returns an array of options to use with a select.
*
* Returns an array of options to use with a selectfor the items specified
* in the given hook.
*
* @param $item_type
* The item type to get options for. One of 'data', 'event', 'condition' and
* 'action'.
* @param $items
* (optional) An array of items to restrict the options to.
*
* @return array
* An array of options.
*/
public static function getOptions($item_type, $items = NULL) {
$sorted_data = array();
$ungrouped = array();
$data = $items ? $items : rules_fetch_data($item_type . '_info');
foreach ($data as $name => $info) {
// Verify the current user has access to use it.
if (!user_access('bypass rules access') && !empty($info['access callback']) && !call_user_func($info['access callback'], $item_type, $name)) {
continue;
}
if ($group = RulesUICategory::getItemGroup($info)) {
$sorted_data[drupal_ucfirst($group)][$name] = drupal_ucfirst($info['label']);
}
else {
$ungrouped[$name] = drupal_ucfirst($info['label']);
}
}
asort($ungrouped);
foreach ($sorted_data as $key => $choices) {
asort($choices);
$sorted_data[$key] = $choices;
}
// Sort the grouped data by category weights, defaulting to weight 0 for
// groups without a respective category.
$sorted_groups = array();
foreach (array_keys($sorted_data) as $label) {
$sorted_groups[$label] = array('weight' => 0, 'label' => $label);
}
// Add in category weights.
foreach (RulesUICategory::getInfo() as $info) {
if (isset($sorted_groups[$info['label']])) {
$sorted_groups[$info['label']] = $info;
}
}
uasort($sorted_groups, '_rules_ui_sort_categories');
// Now replace weights with group content.
foreach ($sorted_groups as $group => $weight) {
$sorted_groups[$group] = $sorted_data[$group];
}
return $ungrouped + $sorted_groups;
}
}
/**
* Helper for sorting categories.
*/
function _rules_ui_sort_categories($a, $b) {
// @see element_sort()
$a_weight = isset($a['weight']) ? $a['weight'] : 0;
$b_weight = isset($b['weight']) ? $b['weight'] : 0;
if ($a_weight == $b_weight) {
// @see element_sort_by_title()
$a_title = isset($a['label']) ? $a['label'] : '';
$b_title = isset($b['label']) ? $b['label'] : '';
return strnatcasecmp($a_title, $b_title);
}
return ($a_weight < $b_weight) ? -1 : 1;
}

View File

@@ -1,10 +1,10 @@
<?php
/**
* @file Contains data type related forms.
* @file
* Contains data type related forms.
*/
/**
* Interface for data types providing a direct input form.
*/
@@ -13,21 +13,47 @@ interface RulesDataDirectInputFormInterface {
/**
* Constructs the direct input form.
*
* @return Array
* The direct input form.
* @return array
* The direct input form.
*/
public static function inputForm($name, $info, $settings, RulesPlugin $element);
/**
* Render the configured value.
*
* @return Array
* @return array
* A renderable array.
*/
public static function render($value);
}
/**
* Interface for data UI classes providing an options list.
*/
interface RulesDataInputOptionsListInterface extends RulesDataDirectInputFormInterface {
/**
* Returns the options list for the data type.
*
* For retrieving information about the used data type and parameter, the
* helper RulesDataUI::getTypeInfo() may be used as following:
* @code
* list($type, $parameter_info) = RulesDataUI::getTypeInfo($element, $name);
* @endcode
*
* @param RulesPlugin $element
* The rules element to get the options for.
* @param string $name
* The name of the parameter for which to get options.
*
* @return array
* An array of options as used by hook_options_list().
*/
public static function optionsList(RulesPlugin $element, $name);
}
/**
* Default UI related class for data types.
*/
@@ -113,7 +139,7 @@ class RulesDataUI {
}
/**
* Renders the value by making use of the label if an options list is available.
* Renders the value with a label if an options list is available.
*
* Used for data UI classes implementing the
* RulesDataDirectInputFormInterface.
@@ -127,7 +153,7 @@ class RulesDataUI {
public static function renderOptionsLabel($value, $name, $info, RulesPlugin $element) {
if (!empty($info['options list'])) {
$element->call('loadBasicInclude');
$options = entity_property_options_flatten($info['options list']($element, $name));
$options = entity_property_options_flatten(call_user_func($info['options list'], $element, $name));
if (!is_array($value) && isset($options[$value])) {
$value = $options[$value];
}
@@ -145,6 +171,18 @@ class RulesDataUI {
);
}
}
/**
* Returns the data type and parameter information for the given arguments.
*
* This helper may be used by options list callbacks operation at data-type
* level, see RulesDataInputOptionsListInterface.
*/
public static function getTypeInfo(RulesPlugin $element, $name) {
$parameters = $element->pluginParameterInfo();
return array($parameters[$name]['type'], $parameters[$name]);
}
}
/**
@@ -152,10 +190,16 @@ class RulesDataUI {
*/
class RulesDataUIText extends RulesDataUI implements RulesDataDirectInputFormInterface {
/**
* Overrides RulesDataUI::getDefaultMode().
*/
public static function getDefaultMode() {
return 'input';
}
/**
* Implements RulesDataDirectInputFormInterface::inputForm().
*/
public static function inputForm($name, $info, $settings, RulesPlugin $element) {
if (!empty($info['options list'])) {
// Make sure the .rules.inc of the providing module is included as the
@@ -169,6 +213,7 @@ class RulesDataUIText extends RulesDataUI implements RulesDataDirectInputFormInt
else {
$form[$name] = array(
'#type' => 'textarea',
'#rows' => 3,
);
RulesDataInputEvaluator::attachForm($form, $settings, $info, $element->availableVariables());
}
@@ -178,17 +223,20 @@ class RulesDataUIText extends RulesDataUI implements RulesDataDirectInputFormInt
'#default_value' => $settings[$name],
'#required' => empty($info['optional']),
'#after_build' => array('rules_ui_element_fix_empty_after_build'),
'#rows' => 3,
);
return $form;
}
/**
* Implements RulesDataDirectInputFormInterface::render().
*/
public static function render($value) {
return array(
'content' => array('#markup' => check_plain($value)),
'#attributes' => array('class' => array('rules-parameter-text')),
);
}
}
/**
@@ -196,6 +244,9 @@ class RulesDataUIText extends RulesDataUI implements RulesDataDirectInputFormInt
*/
class RulesDataUITextToken extends RulesDataUIText {
/**
* Implements RulesDataDirectInputFormInterface::inputForm().
*/
public static function inputForm($name, $info, $settings, RulesPlugin $element) {
$form = parent::inputForm($name, $info, $settings, $element);
if ($form[$name]['#type'] == 'textarea') {
@@ -205,6 +256,7 @@ class RulesDataUITextToken extends RulesDataUIText {
}
return $form;
}
}
/**
@@ -212,6 +264,9 @@ class RulesDataUITextToken extends RulesDataUIText {
*/
class RulesDataUITextFormatted extends RulesDataUIText {
/**
* Implements RulesDataDirectInputFormInterface::inputForm().
*/
public static function inputForm($name, $info, $settings, RulesPlugin $element) {
$form = parent::inputForm($name, $info, $settings, $element);
$settings += array($name => isset($info['default value']) ? $info['default value'] : array('value' => NULL, 'format' => NULL));
@@ -223,21 +278,26 @@ class RulesDataUITextFormatted extends RulesDataUIText {
return $form;
}
/**
* Implements RulesDataDirectInputFormInterface::render().
*/
public static function render($value) {
return array(
'content' => array('#markup' => check_plain($value['value'])),
'#attributes' => array('class' => array('rules-parameter-text-formatted')),
);
}
}
/**
* UI for decimal data.
*/
class RulesDataUIDecimal extends RulesDataUIText {
/**
* Implements RulesDataDirectInputFormInterface::inputForm().
*/
public static function inputForm($name, $info, $settings, RulesPlugin $element) {
$form = parent::inputForm($name, $info, $settings, $element);
if (empty($info['options list'])) {
@@ -247,6 +307,7 @@ class RulesDataUIDecimal extends RulesDataUIText {
$form[$name]['#rows'] = 1;
return $form;
}
}
/**
@@ -254,6 +315,9 @@ class RulesDataUIDecimal extends RulesDataUIText {
*/
class RulesDataUIInteger extends RulesDataUIText {
/**
* Implements RulesDataDirectInputFormInterface::inputForm().
*/
public static function inputForm($name, $info, $settings, RulesPlugin $element) {
$form = parent::inputForm($name, $info, $settings, $element);
if (empty($info['options list'])) {
@@ -262,6 +326,28 @@ class RulesDataUIInteger extends RulesDataUIText {
$form[$name]['#element_validate'][] = 'rules_ui_element_integer_validate';
return $form;
}
}
/**
* UI for IP addresses.
*/
class RulesDataUIIPAddress extends RulesDataUIText {
/**
* Implements RulesDataDirectInputFormInterface::inputForm().
*/
public static function inputForm($name, $info, $settings, RulesPlugin $element) {
$form = parent::inputForm($name, $info, $settings, $element);
if (empty($info['options list'])) {
$form[$name]['#type'] = 'textfield';
$form[$name]['#description'] = t('If not provided, the IP address of the current user will be used.');
}
$form[$name]['#element_validate'][] = 'rules_ui_element_ip_address_validate';
$form[$name]['#rows'] = 1;
return $form;
}
}
/**
@@ -269,27 +355,40 @@ class RulesDataUIInteger extends RulesDataUIText {
*/
class RulesDataUIBoolean extends RulesDataUI implements RulesDataDirectInputFormInterface {
/**
* Overrides RulesDataUI::getDefaultMode().
*/
public static function getDefaultMode() {
return 'input';
}
/**
* Implements RulesDataDirectInputFormInterface::inputForm().
*/
public static function inputForm($name, $info, $settings, RulesPlugin $element) {
$settings += array($name => isset($info['default value']) ? $info['default value'] : NULL);
// Note: Due to the checkbox even optional parameter always receive a value.
$form[$name] = array(
'#type' => 'checkbox',
'#title' => check_plain($info['label']),
'#type' => 'radios',
'#default_value' => $settings[$name],
'#options' => array(
TRUE => t('@label: True.', array('@label' => $info['label'])),
FALSE => t('@label: False.', array('@label' => $info['label'])),
),
);
return $form;
}
/**
* Implements RulesDataDirectInputFormInterface::render().
*/
public static function render($value) {
return array(
'content' => array('#markup' => !empty($value) ? t('true') : t('false')),
'#attributes' => array('class' => array('rules-parameter-boolean')),
);
}
}
/**
@@ -297,6 +396,9 @@ class RulesDataUIBoolean extends RulesDataUI implements RulesDataDirectInputForm
*/
class RulesDataUIDate extends RulesDataUIText {
/**
* Implements RulesDataDirectInputFormInterface::inputForm().
*/
public static function inputForm($name, $info, $settings, RulesPlugin $element) {
$settings += array($name => isset($info['default value']) ? $info['default value'] : (empty($info['optional']) ? gmdate('Y-m-d H:i:s', time()) : NULL));
@@ -313,11 +415,14 @@ class RulesDataUIDate extends RulesDataUIText {
array('%format' => gmdate('Y-m-d H:i:s', time() + 86400),
'!strtotime' => l('strtotime()', 'http://php.net/strtotime')));
//TODO: Leverage the jquery datepicker+timepicker once a module providing
//the timpeicker is available.
// @todo Leverage the jquery datepicker+timepicker once a module providing
// The timepicker is available.
return $form;
}
/**
* Implements RulesDataDirectInputFormInterface::render().
*/
public static function render($value) {
$value = is_numeric($value) ? format_date($value, 'short') : check_plain($value);
return array(
@@ -325,6 +430,7 @@ class RulesDataUIDate extends RulesDataUIText {
'#attributes' => array('class' => array('rules-parameter-date')),
);
}
}
/**
@@ -332,6 +438,9 @@ class RulesDataUIDate extends RulesDataUIText {
*/
class RulesDataUIDuration extends RulesDataUIText {
/**
* Implements RulesDataDirectInputFormInterface::inputForm().
*/
public static function inputForm($name, $info, $settings, RulesPlugin $element) {
$form = parent::inputForm($name, $info, $settings, $element);
$form[$name]['#type'] = 'rules_duration';
@@ -339,6 +448,9 @@ class RulesDataUIDuration extends RulesDataUIText {
return $form;
}
/**
* Implements RulesDataDirectInputFormInterface::render().
*/
public static function render($value) {
$value = is_numeric($value) ? format_interval($value) : check_plain($value);
return array(
@@ -346,6 +458,7 @@ class RulesDataUIDuration extends RulesDataUIText {
'#attributes' => array('class' => array('rules-parameter-duration')),
);
}
}
/**
@@ -353,12 +466,16 @@ class RulesDataUIDuration extends RulesDataUIText {
*/
class RulesDataUIURI extends RulesDataUIText {
/**
* Implements RulesDataDirectInputFormInterface::inputForm().
*/
public static function inputForm($name, $info, $settings, RulesPlugin $element) {
$form = parent::inputForm($name, $info, $settings, $element);
$form[$name]['#rows'] = 1;
$form[$name]['#description'] = t('You may enter relative URLs like %url as well as absolute URLs like %absolute-url.', array('%url' => 'user/login?destination=node', '%absolute-url' => 'http://drupal.org'));
$form[$name]['#description'] = t('You may enter relative URLs like %url as well as absolute URLs like %absolute-url.', array('%url' => 'user/login?destination=node', '%absolute-url' => 'https://www.drupal.org'));
return $form;
}
}
/**
@@ -366,11 +483,16 @@ class RulesDataUIURI extends RulesDataUIText {
*/
class RulesDataUIListText extends RulesDataUIText {
/**
* Overrides RulesDataUI::getDefaultMode().
*/
public static function getDefaultMode() {
return 'input';
}
/**
* Implements RulesDataDirectInputFormInterface::inputForm().
*
* @todo This does not work for inputting textual values including "\n".
*/
public static function inputForm($name, $info, $settings, RulesPlugin $element) {
@@ -391,12 +513,16 @@ class RulesDataUIListText extends RulesDataUIText {
return $form;
}
/**
* Implements RulesDataDirectInputFormInterface::render().
*/
public static function render($value) {
return array(
'content' => array('#markup' => check_plain(implode(', ', $value))),
'#attributes' => array('class' => array('rules-parameter-list')),
);
}
}
/**
@@ -404,6 +530,9 @@ class RulesDataUIListText extends RulesDataUIText {
*/
class RulesDataUIListInteger extends RulesDataUIListText {
/**
* Implements RulesDataDirectInputFormInterface::inputForm().
*/
public static function inputForm($name, $info, $settings, RulesPlugin $element) {
$settings += array($name => isset($info['default value']) ? $info['default value'] : NULL);
$form = parent::inputForm($name, $info, $settings, $element);
@@ -417,6 +546,7 @@ class RulesDataUIListInteger extends RulesDataUIListText {
}
return $form;
}
}
/**
@@ -424,6 +554,9 @@ class RulesDataUIListInteger extends RulesDataUIListText {
*/
class RulesDataUIListToken extends RulesDataUIListInteger {
/**
* Implements RulesDataDirectInputFormInterface::inputForm().
*/
public static function inputForm($name, $info, $settings, RulesPlugin $element) {
$form = parent::inputForm($name, $info, $settings, $element);
@@ -433,6 +566,7 @@ class RulesDataUIListToken extends RulesDataUIListInteger {
}
return $form;
}
}
/**
@@ -440,10 +574,16 @@ class RulesDataUIListToken extends RulesDataUIListInteger {
*/
class RulesDataUIEntity extends RulesDataUIText {
/**
* Overrides RulesDataUI::getDefaultMode().
*/
public static function getDefaultMode() {
return 'selector';
}
/**
* Implements RulesDataDirectInputFormInterface::inputForm().
*/
public static function inputForm($name, $info, $settings, RulesPlugin $element) {
$form = parent::inputForm($name, $info, $settings, $element);
if (empty($info['options list'])) {
@@ -459,6 +599,7 @@ class RulesDataUIEntity extends RulesDataUIText {
}
return $form;
}
}
/**
@@ -466,9 +607,46 @@ class RulesDataUIEntity extends RulesDataUIText {
*/
class RulesDataUIEntityExportable extends RulesDataUIEntity {
/**
* Overrides RulesDataUI::getDefaultMode().
*/
public static function getDefaultMode() {
return 'input';
}
}
/**
* Data UI variant displaying a select list of available bundle entities.
*
* This is used for "bundle entities" implemented via the 'bundle of' feature
* of entity.module.
*/
class RulesDataUIBundleEntity extends RulesDataUIEntity implements RulesDataInputOptionsListInterface {
/**
* Overrides RulesDataUI::getDefaultMode().
*/
public static function getDefaultMode() {
return 'input';
}
/**
* Implements RulesDataInputOptionsListInterface::optionsList().
*/
public static function optionsList(RulesPlugin $element, $name) {
list($data_type, $parameter_info) = RulesDataUI::getTypeInfo($element, $name);
$bundles = array();
$entity_info = entity_get_info();
$bundle_of_type = $entity_info[$data_type]['bundle of'];
if (isset($entity_info[$bundle_of_type]['bundles'])) {
foreach ($entity_info[$bundle_of_type]['bundles'] as $bundle_name => $bundle_info) {
$bundles[$bundle_name] = $bundle_info['label'];
}
}
return $bundles;
}
}
/**
@@ -476,27 +654,26 @@ class RulesDataUIEntityExportable extends RulesDataUIEntity {
*
* @see RulesTaxonomyVocabularyWrapper
*/
class RulesDataUITaxonomyVocabulary extends RulesDataUIEntity {
class RulesDataUITaxonomyVocabulary extends RulesDataUIEntity implements RulesDataInputOptionsListInterface {
/**
* Overrides RulesDataUI::getDefaultMode().
*/
public static function getDefaultMode() {
return 'input';
}
public static function inputForm($name, $info, $settings, RulesPlugin $element) {
// Add an options list of all vocabularies if there is none yet.
if (!isset($info['options list'])) {
$info['options list'] = array('RulesDataUITaxonomyVocabulary', 'optionsList');
}
return parent::inputForm($name, $info, $settings, $element);
}
public static function optionsList() {
/**
* Implements RulesDataInputOptionsListInterface::optionsList().
*/
public static function optionsList(RulesPlugin $element, $name) {
$options = array();
foreach (taxonomy_vocabulary_get_names() as $machine_name => $vocab) {
$options[$machine_name] = $vocab->name;
}
return $options;
}
}
/**
@@ -504,6 +681,9 @@ class RulesDataUITaxonomyVocabulary extends RulesDataUIEntity {
*/
class RulesDataUIListEntity extends RulesDataUIListInteger {
/**
* Implements RulesDataDirectInputFormInterface::inputForm().
*/
public static function inputForm($name, $info, $settings, RulesPlugin $element) {
$form = parent::inputForm($name, $info, $settings, $element);
if (empty($info['options list'])) {
@@ -518,4 +698,5 @@ class RulesDataUIListEntity extends RulesDataUIListInteger {
}
return $form;
}
}

View File

@@ -1,7 +1,8 @@
<?php
/**
* @file Rules UI forms
* @file
* Rules User Interface forms.
*/
/**
@@ -35,7 +36,7 @@ function rules_ui_parameter_replace_submit($form, &$form_state) {
}
/**
* General form submit handler, that rebuilds the form
* General form submit handler, that rebuilds the form.
*/
function rules_form_submit_rebuild($form, &$form_state) {
$form_state['rebuild'] = TRUE;
@@ -54,8 +55,9 @@ function rules_ui_form_edit_rules_config($form, &$form_state, $rules_config, $ba
}
/**
* General rules configuration form validation callback. Also populates the
* rules configuration with the form values.
* General rules configuration form validation callback.
*
* Also populates the rules configuration with the form values.
*/
function rules_ui_form_rules_config_validate($form, &$form_state) {
$form_state['rules_element']->form_validate($form, $form_state);
@@ -78,7 +80,6 @@ function rules_ui_form_edit_rules_config_submit($form, &$form_state) {
function rules_ui_form_clone_rules_config($form, &$form_state, $rules_config, $base_path) {
RulesPluginUI::$basePath = $base_path;
$rules_config = clone $rules_config;
$rules_config->module = 'rules';
$rules_config->id = NULL;
$rules_config->name = '';
$rules_config->label .= ' (' . t('cloned') . ')';
@@ -166,13 +167,29 @@ function rules_ui_confirm_operations($op, $rules_config) {
switch ($op) {
case 'enable':
return array(t('Are you sure you want to enable the %plugin %label?', $vars), '');
return array(
t('Are you sure you want to enable the %plugin %label?', $vars),
'',
);
case 'disable':
return array(t('Are you sure you want to disable the %plugin %label?', $vars), '');
return array(
t('Are you sure you want to disable the %plugin %label?', $vars),
'',
);
case 'revert':
return array(t('Are you sure you want to revert the %plugin %label?', $vars), t('This action cannot be undone.'));
return array(
t('Are you sure you want to revert the %plugin %label?', $vars),
t('This action cannot be undone.'),
);
case 'delete':
return array(t('Are you sure you want to delete the %plugin %label?', $vars), t('This action cannot be undone.'));
return array(
t('Are you sure you want to delete the %plugin %label?', $vars),
t('This action cannot be undone.'),
);
default:
return FALSE;
}
@@ -194,9 +211,10 @@ function rules_ui_form_rules_config_confirm_op($form, &$form_state, $rules_confi
}
/**
* Applies the operation and returns the message to show to the user. Also the
* operation is logged to the watchdog. Note that the string is defined two
* times so that the translation extractor can find it.
* Applies the operation and returns the message to show to the user.
*
* The operation is also logged to the watchdog. Note that the string is
* defined two times so that the translation extractor can find it.
*/
function rules_ui_confirm_operation_apply($op, $rules_config) {
$vars = array('%plugin' => $rules_config->plugin(), '%label' => $rules_config->label());
@@ -291,8 +309,9 @@ function rules_ui_add_element($form, &$form_state, $rules_config, $plugin_name,
/**
* Add element submit callback.
*
* Used for "abstract plugins" to create the initial element object with the
* given implemenation name and rebuild the form.
* given implementation name and rebuild the form.
*/
function rules_ui_add_element_submit($form, &$form_state) {
$element = rules_plugin_factory($form_state['plugin'], $form_state['values']['element_name']);
@@ -349,7 +368,10 @@ function rules_ui_delete_element($form, &$form_state, $rules_config, $rules_elem
}
}
$confirm_question = t('Are you sure you want to delete the %element_plugin %element_name?', array('%element_plugin' => $rules_element->plugin(), '%element_name' => $rules_element->label(), '%plugin' => $rules_config->plugin(), '%label' => $rules_config->label()));
$confirm_question = t('Are you sure you want to delete the %element_plugin %element_name?', array(
'%element_plugin' => $rules_element->plugin(),
'%element_name' => $rules_element->label(),
));
return confirm_form($form, $confirm_question, RulesPluginUI::path($rules_config->name), t('This action cannot be undone.'), t('Delete'), t('Cancel'));
}
@@ -364,7 +386,6 @@ function rules_ui_delete_element_submit($form, &$form_state) {
}
}
/**
* Configure a rule element.
*/
@@ -394,43 +415,20 @@ function rules_ui_edit_element_submit($form, &$form_state) {
}
/**
* Add a new event.
* Form builder for the "add event" page.
*/
function rules_ui_add_event($form, &$form_state, RulesReactionRule $rules_config, $base_path) {
function rules_ui_add_event_page($form, &$form_state, RulesTriggerableInterface $rules_config, $base_path) {
RulesPluginUI::$basePath = $base_path;
$form_state += array('rules_config' => $rules_config);
$events = array_diff_key(rules_fetch_data('event_info'), array_flip($rules_config->events()));
$form['help'] = array(
'#markup' => t('Select the event to add. However note that all added events need to provide all variables that should be available to your rule.'),
);
$form['event'] = array(
'#type' => 'select',
'#title' => t('React on event'),
'#options' => RulesPluginUI::getOptions('event', $events),
'#description' => t('Whenever the event occurs, rule evaluation is triggered.'),
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Add'),
);
$form_state['redirect'] = RulesPluginUI::path($rules_config->name);
RulesPluginUI::formDefaults($form, $form_state);
$form = rules_ui_add_event($form, $form_state, $rules_config, $base_path);
$form['#validate'][] = 'rules_ui_add_event_validate';
return $form;
}
/**
* Submit callback that just adds the selected event.
*
* @see rules_admin_add_reaction_rule()
*/
function rules_ui_add_event_apply($form, &$form_state) {
$form_state['rules_config']->event($form_state['values']['event']);
}
/**
* Submit the event configuration.
*/
function rules_ui_add_event_submit($form, &$form_state) {
function rules_ui_add_event_page_submit($form, &$form_state) {
rules_ui_add_event_apply($form, $form_state);
$rules_config = $form_state['rules_config'];
@@ -453,13 +451,71 @@ function rules_ui_add_event_submit($form, &$form_state) {
}
/**
* Form to remove a event from a rule.
* Add a new event.
*/
function rules_ui_add_event($form, &$form_state, RulesReactionRule $rules_config, $base_path) {
$form_state += array('rules_config' => $rules_config);
$events = array_diff_key(rules_fetch_data('event_info'), array_flip($rules_config->events()));
$form['help'] = array(
'#markup' => t('Select the event to add. However note that all added events need to provide all variables that should be available to your rule.'),
);
$form['event'] = array(
'#type' => 'select',
'#title' => t('React on event'),
'#options' => RulesPluginUI::getOptions('event', $events),
'#description' => t('Whenever the event occurs, rule evaluation is triggered.'),
'#ajax' => rules_ui_form_default_ajax(),
'#required' => TRUE,
);
if (!empty($form_state['values']['event'])) {
$handler = rules_get_event_handler($form_state['values']['event']);
$form['event_settings'] = $handler->buildForm($form_state);
}
else {
$form['event_settings'] = array();
}
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Add'),
);
$form_state['redirect'] = RulesPluginUI::path($rules_config->name);
return $form;
}
/**
* Validation callback for adding an event.
*/
function rules_ui_add_event_validate($form, $form_state) {
$handler = rules_get_event_handler($form_state['values']['event']);
$handler->extractFormValues($form['event_settings'], $form_state);
try {
$handler->validate();
}
catch (RulesIntegrityException $e) {
form_set_error(implode('][', $e->keys), $e->getMessage());
}
}
/**
* Submit callback that just adds the selected event.
*
* @see rules_admin_add_reaction_rule()
*/
function rules_ui_add_event_apply($form, &$form_state) {
$handler = rules_get_event_handler($form_state['values']['event']);
$handler->extractFormValues($form['event_settings'], $form_state);
$form_state['rules_config']->event($form_state['values']['event'], $handler->getSettings());
}
/**
* Form to remove an event from a rule.
*/
function rules_ui_remove_event($form, &$form_state, $rules_config, $event, $base_path) {
RulesPluginUI::$basePath = $base_path;
$form_state += array('rules_config' => $rules_config, 'rules_event' => $event);
$events = rules_fetch_data('event_info');
$form_state['event_label'] = $events[$event]['label'];
$event_info = rules_get_event_info($event);
$form_state['event_label'] = $event_info['label'];
$confirm_question = t('Are you sure you want to remove the event?');
return confirm_form($form, $confirm_question, RulesPluginUI::path($rules_config->name), t('You are about to remove the event %event.', array('%event' => $form_state['event_label'])), t('Remove'), t('Cancel'));
}
@@ -564,6 +620,7 @@ function rules_ui_import_form_submit($form, &$form_state) {
/**
* FAPI process callback for the data selection widget.
*
* This finalises the auto completion callback path by appending the form build
* id.
*/
@@ -623,12 +680,12 @@ function rules_ui_form_data_selection_auto_completion($parameter, $form_build_id
drupal_json_output($matches);
}
/**
* FAPI validation of an integer element. Copy of the private function
* _element_validate_integer().
* FAPI validation of an integer element.
*
* Copy of the core Drupal private function _element_validate_integer().
*/
function rules_ui_element_integer_validate($element, &$form_state) {;
function rules_ui_element_integer_validate($element, &$form_state) {
$value = $element['#value'];
if (isset($value) && $value !== '' && (!is_numeric($value) || intval($value) != $value)) {
form_error($element, t('%name must be an integer value.', array('%name' => isset($element['#title']) ? $element['#title'] : t('Element'))));
@@ -636,8 +693,9 @@ function rules_ui_element_integer_validate($element, &$form_state) {;
}
/**
* FAPI validation of a decimal element. Improved version of the private
* function _element_validate_number().
* FAPI validation of a decimal element.
*
* Improved version of the private function _element_validate_number().
*/
function rules_ui_element_decimal_validate($element, &$form_state) {
// Substitute the decimal separator ",".
@@ -651,9 +709,21 @@ function rules_ui_element_decimal_validate($element, &$form_state) {
}
/**
* FAPI validation of a date element. Makes sure the specified date format is
* correct and converts date values specifiy a fixed (= non relative) date to
* a timestamp. Relative dates are handled by the date input evaluator.
* FAPI callback to validate an IP address.
*/
function rules_ui_element_ip_address_validate($element, &$form_state) {
$value = $element['#value'];
if ($value != '' && !filter_var($value, FILTER_VALIDATE_IP)) {
form_error($element, t('%name is not a valid IP address.', array('%name' => $element['#title'])));
}
}
/**
* FAPI validation of a date element.
*
* Makes sure the specified date format is correct and converts date values
* specify a fixed (= non relative) date to a timestamp. Relative dates are
* handled by the date input evaluator.
*/
function rules_ui_element_date_validate($element, &$form_state) {
$value = $element['#value'];
@@ -722,8 +792,9 @@ function rules_ui_element_duration_multipliers() {
}
/**
* Helper function to determine the value for a rules duration form
* element.
* Helper function a rules duration form element.
*
* Determines the value for a rules duration form element.
*/
function rules_ui_element_duration_value($element, $input = FALSE) {
// This runs before child elements are processed, so we cannot calculate the
@@ -737,6 +808,7 @@ function rules_ui_element_duration_value($element, $input = FALSE) {
/**
* FAPI after build callback for the duration parameter type form.
*
* Fixes up the form value by applying the multiplier.
*/
function rules_ui_element_duration_after_build($element, &$form_state) {
@@ -766,7 +838,6 @@ function rules_ui_element_fix_empty_after_build($element, &$form_state) {
return $element;
}
/**
* FAPI after build callback for specifying a list of values.
*
@@ -833,6 +904,7 @@ function rules_ui_element_machine_name_validate($element, &$form_state) {
/**
* FAPI callback to validate the form for editing variable info.
*
* @see RulesPluginUI::getVariableForm()
*/
function rules_ui_element_variable_form_validate($elements, &$form_state) {

View File

@@ -1,7 +1,8 @@
<?php
/**
* @file Contains UI for diverse plugins provided by Rules.
* @file
* Contains UI for diverse plugins provided by Rules.
*/
/**
@@ -9,15 +10,21 @@
*/
class RulesRuleUI extends RulesActionContainerUI {
protected $rule, $conditions;
protected $rule;
protected $conditions;
/**
* Constructs a RulesRuleUI object.
*
* @param FacesExtendable $object
*/
public function __construct(FacesExtendable $object) {
parent::__construct($object);
$this->rule = $object;
$this->conditions = $this->rule->conditionContainer();
}
public function form(&$form, &$form_state, $options = array()) {
public function form(&$form, &$form_state, $options = array(), $iterator = NULL) {
$form_state['rules_element'] = $this->rule;
$label = $this->element->label();
// Automatically add a counter to unlabelled rules.
@@ -58,7 +65,7 @@ class RulesRuleUI extends RulesActionContainerUI {
/**
* Applies the values of the form to the rule configuration.
*/
function form_extract_values($form, &$form_state) {
public function form_extract_values($form, &$form_state) {
$form_values = RulesPluginUI::getFormStateValues($form, $form_state);
// Run condition and action container value extraction.
if (isset($form['conditions'])) {
@@ -70,13 +77,13 @@ class RulesRuleUI extends RulesActionContainerUI {
parent::form_extract_values($form, $form_state);
}
public function operations() {
// When rules are listed only show the edit and delete operations.
$ops = parent::operations();
$ops['#links'] = array_intersect_key($ops['#links'], array_flip(array('edit', 'delete')));
return $ops;
}
}
/**
@@ -84,26 +91,46 @@ class RulesRuleUI extends RulesActionContainerUI {
*/
class RulesReactionRuleUI extends RulesRuleUI {
public function form(&$form, &$form_state, $options = array()) {
public function form(&$form, &$form_state, $options = array(), $iterator = NULL) {
$form['events'] = array(
'#type' => 'container',
'#weight' => -10,
'#access' => empty($options['init']),
);
$event_info = rules_fetch_data('event_info');
$form['events']['table'] = array(
'#theme' => 'table',
'#caption' => 'Events',
'#header' => array('Event', 'Operations'),
'#header' => array(t('Event'), t('Operations')),
'#empty' => t('None'),
);
$form['events']['table']['#attributes']['class'][] = 'rules-elements-table';
foreach ($this->rule->events() as $event_name) {
$event_info += array($event_name => array('label' => t('Unknown event "!event_name"', array('!event_name' => $event_name))));
$event_handler = rules_get_event_handler($event_name, $this->rule->getEventSettings($event_name));
$event_operations = array(
'#theme' => 'links__rules',
'#attributes' => array(
'class' => array(
'rules-operations',
'action-links',
'rules_rule_event',
),
),
'#links' => array(
'delete_event' => array(
'title' => t('delete'),
'href' => RulesPluginUI::path($this->rule->name, 'delete/event/' . $event_name),
'query' => drupal_get_destination(),
),
),
);
$form['events']['table']['#rows'][$event_name] = array(
check_plain($event_info[$event_name]['label']),
'<span class="rules_rule_event">' . l(t('delete'), RulesPluginUI::path($this->rule->name, 'delete/event/' . $event_name)) . '</span>',
'data' => array(
$event_handler->summary(),
array('data' => $event_operations),
),
);
}
@@ -150,6 +177,7 @@ class RulesReactionRuleUI extends RulesRuleUI {
$this->rule->active = $form_values['active'];
$this->rule->weight = $form_values['weight'];
}
}
/**
@@ -166,6 +194,7 @@ class RulesRuleSetUI extends RulesActionContainerUI {
$form['elements']['#attributes']['class'][] = 'rules-rule-set';
$form['elements']['#caption'] = t('Rules');
}
}
/**
@@ -173,7 +202,7 @@ class RulesRuleSetUI extends RulesActionContainerUI {
*/
class RulesLoopUI extends RulesActionContainerUI {
public function form(&$form, &$form_state, $options = array()) {
public function form(&$form, &$form_state, $options = array(), $iterator = NULL) {
parent::form($form, $form_state, $options);
$settings = $this->element->settings;
@@ -199,7 +228,7 @@ class RulesLoopUI extends RulesActionContainerUI {
);
}
function form_extract_values($form, &$form_state) {
public function form_extract_values($form, &$form_state) {
parent::form_extract_values($form, $form_state);
$form_values = RulesPluginUI::getFormStateValues($form, $form_state);
@@ -231,4 +260,5 @@ class RulesLoopUI extends RulesActionContainerUI {
);
return $content;
}
}

View File

@@ -1,10 +1,10 @@
<?php
/**
* @file Rules theme functions
* @file
* Rules theme functions.
*/
/**
* Themes a tree of rule elements in a draggable table.
*
@@ -58,13 +58,20 @@ function theme_rules_elements($variables) {
* Themes the rules form for editing the used variables.
*
* @see RulesPluginUI::getVariableForm()
*
* @ingroup themeable
*/
function theme_rules_ui_variable_form($variables) {
$elements = $variables['element'];
$table['#theme'] = 'table';
$table['#header'] = array(t('Data type'), t('Label'), t('Machine name'), t('Usage'), array('data' => t('Weight'), 'class' => array('tabledrag-hide')));
$table['#header'] = array(
t('Data type'),
t('Label'),
t('Machine name'),
t('Usage'),
array('data' => t('Weight'), 'class' => array('tabledrag-hide')),
);
$table['#attributes']['id'] = 'rules-' . drupal_html_id($elements['#title']) . '-id';
foreach (element_children($elements['items']) as $key) {
@@ -107,6 +114,7 @@ function theme_rules_ui_variable_form($variables) {
/**
* Themes a view of multiple configuration items.
*
* @ingroup themeable
*/
function theme_rules_content_group($variables) {
@@ -125,6 +133,7 @@ function theme_rules_content_group($variables) {
/**
* Themes the view of a single parameter configuration.
*
* @ingroup themeable
*/
function theme_rules_parameter_configuration($variables) {
@@ -149,6 +158,7 @@ function theme_rules_parameter_configuration($variables) {
/**
* Themes info about variables.
*
* @ingroup themeable
*/
function theme_rules_variable_view($variables) {
@@ -169,6 +179,7 @@ function theme_rules_variable_view($variables) {
/**
* Themes help for using the data selector.
*
* @ingroup themeable
*/
function theme_rules_data_selector_help($variables) {
@@ -193,13 +204,18 @@ function theme_rules_data_selector_help($variables) {
);
foreach (RulesData::matchingDataSelector($variables_info, $param_info) as $selector => $info) {
$info += array('label' => '', 'description' => '');
$render['table']['#rows'][] = array(check_plain($selector), check_plain(drupal_ucfirst($info['label'])), check_plain($info['description']));
$render['table']['#rows'][] = array(
check_plain($selector),
check_plain(drupal_ucfirst($info['label'])),
check_plain($info['description']),
);
}
return drupal_render($render);
}
/**
* Themes the rules log debug output.
*
* @ingroup themeable
*/
function theme_rules_log($variables) {
@@ -230,6 +246,7 @@ function theme_rules_log($variables) {
/**
* Theme rules debug log elements.
*
* @ingroup themeable
*/
function theme_rules_debug_element($variables) {
@@ -248,6 +265,7 @@ function theme_rules_debug_element($variables) {
/**
* Themes rules autocomplete forms.
*
* @ingroup themeable
*/
function theme_rules_autocomplete($variables) {
@@ -278,6 +296,7 @@ function theme_rules_autocomplete($variables) {
/**
* General theme function for displaying settings related help.
*
* @ingroup themeable
*/
function theme_rules_settings_help($variables) {