diff options
Diffstat (limited to 'modules/system')
-rw-r--r-- | modules/system/system.admin.inc | 273 | ||||
-rw-r--r-- | modules/system/system.api.php | 84 | ||||
-rw-r--r-- | modules/system/system.install | 13 | ||||
-rw-r--r-- | modules/system/system.module | 316 |
4 files changed, 377 insertions, 309 deletions
diff --git a/modules/system/system.admin.inc b/modules/system/system.admin.inc index d7c380f9d..48806cdb4 100644 --- a/modules/system/system.admin.inc +++ b/modules/system/system.admin.inc @@ -2296,3 +2296,276 @@ function theme_system_themes_form($form) { $output .= drupal_render_children($form); return $output; } + +/** + * Menu callback; Displays an overview of available and configured actions. + */ +function system_actions_manage() { + actions_synchronize(); + $actions = actions_list(); + $actions_map = actions_actions_map($actions); + $options = array(t('Choose an advanced action')); + $unconfigurable = array(); + + foreach ($actions_map as $key => $array) { + if ($array['configurable']) { + $options[$key] = $array['label'] . '...'; + } + else { + $unconfigurable[] = $array; + } + } + + $row = array(); + $instances_present = db_query("SELECT aid FROM {actions} WHERE parameters <> ''")->fetchField(); + $header = array( + array('data' => t('Action type'), 'field' => 'type'), + array('data' => t('Label'), 'field' => 'label'), + array('data' => $instances_present ? t('Operations') : '', 'colspan' => '2') + ); + $query = db_select('actions')->extend('PagerDefault')->extend('TableSort'); + $result = $query + ->fields('actions') + ->limit(50) + ->orderByHeader($header) + ->execute(); + + foreach ($result as $action) { + $row[] = array( + array('data' => $action->type), + array('data' => $action->label), + array('data' => $action->parameters ? l(t('configure'), "admin/config/system/actions/configure/$action->aid") : ''), + array('data' => $action->parameters ? l(t('delete'), "admin/config/system/actions/delete/$action->aid") : '') + ); + } + + if ($row) { + $pager = theme('pager', NULL); + if (!empty($pager)) { + $row[] = array(array('data' => $pager, 'colspan' => '3')); + } + $build['system_actions_header'] = array('#markup' => '<h3>' . t('Actions available to Drupal:') . '</h3>'); + $build['system_actions_table'] = array('#markup' => theme('table', $header, $row)); + } + + if ($actions_map) { + $build['system_actions_manage_form'] = drupal_get_form('system_actions_manage_form', $options); + } + + return $build; +} + +/** + * Define the form for the actions overview page. + * + * @param $form_state + * An associative array containing the current state of the form; not used. + * @param $options + * An array of configurable actions. + * @return + * Form definition. + * + * @ingroup forms + * @see system_actions_manage_form_submit() + */ +function system_actions_manage_form($form, &$form_state, $options = array()) { + $form['parent'] = array( + '#type' => 'fieldset', + '#title' => t('Make a new advanced action available'), + '#prefix' => '<div class="container-inline">', + '#suffix' => '</div>', + ); + $form['parent']['action'] = array( + '#type' => 'select', + '#default_value' => '', + '#options' => $options, + '#description' => '', + ); + $form['parent']['buttons']['submit'] = array( + '#type' => 'submit', + '#value' => t('Create'), + ); + return $form; +} + +/** + * Process system_actions_manage form submissions. + * + * @see system_actions_manage_form() + */ +function system_actions_manage_form_submit($form, &$form_state) { + if ($form_state['values']['action']) { + $form_state['redirect'] = 'admin/config/system/actions/configure/' . $form_state['values']['action']; + } +} + +/** + * Menu callback; Creates the form for configuration of a single action. + * + * We provide the "Description" field. The rest of the form is provided by the + * action. We then provide the Save button. Because we are combining unknown + * form elements with the action configuration form, we use an 'actions_' prefix + * on our elements. + * + * @param $action + * md5 hash of an action ID or an integer. If it is an md5 hash, we are + * creating a new instance. If it is an integer, we are editing an existing + * instance. + * @return + * A form definition. + * + * @see system_actions_configure_validate() + * @see system_actions_configure_submit() + */ +function system_actions_configure($form, &$form_state, $action = NULL) { + if ($action === NULL) { + drupal_goto('admin/config/system/actions'); + } + + $actions_map = actions_actions_map(actions_list()); + $edit = array(); + + // Numeric action denotes saved instance of a configurable action. + if (is_numeric($action)) { + $aid = $action; + // Load stored parameter values from database. + $data = db_query("SELECT * FROM {actions} WHERE aid = :aid", array(':aid' => $aid))->fetch(); + $edit['actions_label'] = $data->label; + $edit['actions_type'] = $data->type; + $function = $data->callback; + $action = md5($data->callback); + $params = unserialize($data->parameters); + if ($params) { + foreach ($params as $name => $val) { + $edit[$name] = $val; + } + } + } + // Otherwise, we are creating a new action instance. + else { + $function = $actions_map[$action]['callback']; + $edit['actions_label'] = $actions_map[$action]['label']; + $edit['actions_type'] = $actions_map[$action]['type']; + } + + $form['actions_label'] = array( + '#type' => 'textfield', + '#title' => t('Label'), + '#default_value' => $edit['actions_label'], + '#maxlength' => '255', + '#description' => t('A unique label for this advanced action. This label will be displayed in the interface of modules that integrate with actions, such as Trigger module.'), + '#weight' => -10 + ); + $action_form = $function . '_form'; + $form = array_merge($form, $action_form($edit)); + $form['actions_type'] = array( + '#type' => 'value', + '#value' => $edit['actions_type'], + ); + $form['actions_action'] = array( + '#type' => 'hidden', + '#value' => $action, + ); + // $aid is set when configuring an existing action instance. + if (isset($aid)) { + $form['actions_aid'] = array( + '#type' => 'hidden', + '#value' => $aid, + ); + } + $form['actions_configured'] = array( + '#type' => 'hidden', + '#value' => '1', + ); + $form['buttons']['submit'] = array( + '#type' => 'submit', + '#value' => t('Save'), + '#weight' => 13 + ); + + return $form; +} + +/** + * Validate system_actions_configure() form submissions. + */ +function system_actions_configure_validate($form, &$form_state) { + $function = actions_function_lookup($form_state['values']['actions_action']) . '_validate'; + // Hand off validation to the action. + if (function_exists($function)) { + $function($form, $form_state); + } +} + +/** + * Process system_actions_configure() form submissions. + */ +function system_actions_configure_submit($form, &$form_state) { + $function = actions_function_lookup($form_state['values']['actions_action']); + $submit_function = $function . '_submit'; + + // Action will return keyed array of values to store. + $params = $submit_function($form, $form_state); + $aid = isset($form_state['values']['actions_aid']) ? $form_state['values']['actions_aid'] : NULL; + + actions_save($function, $form_state['values']['actions_type'], $params, $form_state['values']['actions_label'], $aid); + drupal_set_message(t('The action has been successfully saved.')); + + $form_state['redirect'] = 'admin/config/system/actions/manage'; +} + +/** + * Create the form for confirmation of deleting an action. + * + * @see system_actions_delete_form_submit() + * @ingroup forms + */ +function system_actions_delete_form($form, &$form_state, $action) { + $form['aid'] = array( + '#type' => 'hidden', + '#value' => $action->aid, + ); + return confirm_form($form, + t('Are you sure you want to delete the action %action?', array('%action' => $action->label)), + 'admin/config/system/actions/manage', + t('This cannot be undone.'), + t('Delete'), + t('Cancel') + ); +} + +/** + * Process system_actions_delete form submissions. + * + * Post-deletion operations for action deletion. + */ +function system_actions_delete_form_submit($form, &$form_state) { + $aid = $form_state['values']['aid']; + $action = actions_load($aid); + actions_delete($aid); + $label = check_plain($action->label); + watchdog('user', 'Deleted action %aid (%action)', array('%aid' => $aid, '%action' => $label)); + drupal_set_message(t('Action %action was deleted', array('%action' => $label))); + $form_state['redirect'] = 'admin/config/system/actions/manage'; +} + +/** + * Post-deletion operations for deleting action orphans. + * + * @param $orphaned + * An array of orphaned actions. + */ +function system_action_delete_orphans_post($orphaned) { + foreach ($orphaned as $callback) { + drupal_set_message(t("Deleted orphaned action (%action).", array('%action' => $callback))); + } +} + +/** + * Remove actions that are in the database but not supported by any enabled module. + */ +function system_actions_remove_orphans() { + actions_synchronize(TRUE); + drupal_goto('admin/config/system/actions/manage'); +} + diff --git a/modules/system/system.api.php b/modules/system/system.api.php index 1251187ab..6a79445ac 100644 --- a/modules/system/system.api.php +++ b/modules/system/system.api.php @@ -2211,5 +2211,89 @@ function hook_file_mimetype_mapping_alter(&$mapping) { } /** + * Declares information about actions. + * + * Any module can define actions, and then call actions_do() to make those + * actions happen in response to events. The trigger module provides a user + * interface for associating actions with module-defined triggers, and it makes + * sure the core triggers fire off actions when their events happen. + * + * An action consists of two or three parts: + * - an action definition (returned by this hook) + * - a function which performs the action (which by convention is named + * MODULE_description-of-function_action) + * - an optional form definition function that defines a configuration form + * (which has the name of the action function with '_form' appended to it.) + * + * The action function takes two to four arguments, which come from the input + * arguments to actions_do(). + * + * @return + * An associative array of action descriptions. The keys of the array + * are the names of the action functions, and each corresponding value + * is an associative array with the following key-value pairs: + * - 'type': The type of object this action acts upon. Core actions have types + * 'node', 'user', 'comment', and 'system'. + * - 'label': The human-readable name of the action, which should be passed + * through the t() function for translation. + * - 'configurable': If FALSE, then the action doesn't require any extra + * configuration. If TRUE, then your module must define a form function with + * the same name as the action function with '_form' appended (e.g., the + * form for 'node_assign_owner_action' is 'node_assign_owner_action_form'.) + * This function takes $context as its only parameter, and is paired with + * the usual _submit function, and possibly a _validate function. + * - 'triggers': An array of the events (that is, hooks) that can trigger this + * action. For example: array('node_insert', 'user_update'). You can also + * declare support for any trigger by returning array('any') for this value. + * - 'behavior': (optional) machine-readable array of behaviors of this + * action, used to signal additional actions that may need to be triggered. + * Currently recognized behaviors by Trigger module: + * - 'changes_node_property': If an action with this behavior is assigned to + * a trigger other than 'node_presave', any node save actions also + * assigned to this trigger are moved later in the list. If a node save + * action is not present, one will be added. + */ +function hook_action_info() { + return array( + 'comment_unpublish_action' => array( + 'type' => 'comment', + 'label' => t('Unpublish comment'), + 'configurable' => FALSE, + 'triggers' => array('comment_insert', 'comment_update'), + ), + 'comment_unpublish_by_keyword_action' => array( + 'type' => 'comment', + 'label' => t('Unpublish comment containing keyword(s)'), + 'configurable' => TRUE, + 'triggers' => array('comment_insert', 'comment_update'), + ), + ); +} + +/** + * Executes code after an action is deleted. + * + * @param $aid + * The action ID. + */ +function hook_actions_delete($aid) { + db_delete('actions_assignments') + ->condition('aid', $aid) + ->execute(); +} + +/** + * Alters the actions declared by another module. + * + * Called by actions_list() to allow modules to alter the return values from + * implementations of hook_action_info(). + * + * @see trigger_example_action_info_alter(). + */ +function hook_action_info_alter(&$actions) { + $actions['node_unpublish_action']['label'] = t('Unpublish and remove from public view.'); +} + +/** * @} End of "addtogroup hooks". */ diff --git a/modules/system/system.install b/modules/system/system.install index 85423a0a4..87c4de592 100644 --- a/modules/system/system.install +++ b/modules/system/system.install @@ -574,8 +574,8 @@ function system_schema() { 'not null' => TRUE, 'size' => 'big', ), - 'description' => array( - 'description' => 'Description of the action.', + 'label' => array( + 'description' => 'Label of the action.', 'type' => 'varchar', 'length' => 255, 'not null' => TRUE, @@ -2493,6 +2493,15 @@ function system_update_7037() { } /** + * Rename action description to label. + */ +function system_update_7038() { + $ret = array(); + db_change_field($ret, 'actions', 'description', 'label', array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => '0')); + return $ret; +} + +/** * @} End of "defgroup updates-6.x-to-7.x" * The next series of updates should start at 8000. */ diff --git a/modules/system/system.module b/modules/system/system.module index 867ec7213..ab3c966b5 100644 --- a/modules/system/system.module +++ b/modules/system/system.module @@ -2403,336 +2403,38 @@ function system_cron() { } /** - * Implement hook_hook_info(). - */ -function system_hook_info() { - return array( - 'system' => array( - 'cron' => array( - 'run' => array( - 'runs when' => t('When cron runs'), - ), - ), - ), - ); -} - -/** * Implement hook_action_info(). */ function system_action_info() { return array( 'system_message_action' => array( 'type' => 'system', - 'description' => t('Display a message to the user'), + 'label' => t('Display a message to the user'), 'configurable' => TRUE, - 'hooks' => array( - 'node' => array('view', 'insert', 'update', 'delete'), - 'comment' => array('view', 'insert', 'update', 'delete'), - 'user' => array('view', 'insert', 'update', 'delete', 'login'), - 'taxonomy' => array('insert', 'update', 'delete'), - ), + 'triggers' => array('any'), ), 'system_send_email_action' => array( - 'description' => t('Send e-mail'), 'type' => 'system', + 'label' => t('Send e-mail'), 'configurable' => TRUE, - 'hooks' => array( - 'node' => array('view', 'insert', 'update', 'delete'), - 'comment' => array('view', 'insert', 'update', 'delete'), - 'user' => array('view', 'insert', 'update', 'delete', 'login'), - 'taxonomy' => array('insert', 'update', 'delete'), - 'cron' => array('run'), - ) + 'triggers' => array('any'), ), 'system_block_ip_action' => array( - 'description' => t('Ban IP address of current user'), 'type' => 'user', + 'label' => t('Ban IP address of current user'), 'configurable' => FALSE, - 'hooks' => array(), + 'triggers' => array(), ), 'system_goto_action' => array( - 'description' => t('Redirect to URL'), 'type' => 'system', + 'label' => t('Redirect to URL'), 'configurable' => TRUE, - 'hooks' => array( - 'node' => array('view', 'insert', 'update', 'delete'), - 'comment' => array('view', 'insert', 'update', 'delete'), - 'user' => array('view', 'insert', 'update', 'delete', 'login'), - ) - ) - ); -} - -/** - * Menu callback. Display an overview of available and configured actions. - */ -function system_actions_manage() { - actions_synchronize(); - $actions = actions_list(); - $actions_map = actions_actions_map($actions); - $options = array(t('Choose an advanced action')); - $unconfigurable = array(); - - foreach ($actions_map as $key => $array) { - if ($array['configurable']) { - $options[$key] = $array['description'] . '...'; - } - else { - $unconfigurable[] = $array; - } - } - - $row = array(); - $instances_present = db_query("SELECT aid FROM {actions} WHERE parameters <> ''")->fetchField(); - $header = array( - array('data' => t('Action type'), 'field' => 'type'), - array('data' => t('Description'), 'field' => 'description'), - array('data' => $instances_present ? t('Operations') : '', 'colspan' => '2') - ); - $query = db_select('actions')->extend('PagerDefault')->extend('TableSort'); - $result = $query - ->fields('actions') - ->limit(50) - ->orderByHeader($header) - ->execute(); - - foreach ($result as $action) { - $row[] = array( - array('data' => $action->type), - array('data' => $action->description), - array('data' => $action->parameters ? l(t('configure'), "admin/config/system/actions/configure/$action->aid") : ''), - array('data' => $action->parameters ? l(t('delete'), "admin/config/system/actions/delete/$action->aid") : '') - ); - } - - if ($row) { - $pager = theme('pager', NULL); - if (!empty($pager)) { - $row[] = array(array('data' => $pager, 'colspan' => '3')); - } - $build['system_actions_header'] = array('#markup' => '<h3>' . t('Actions available to Drupal:') . '</h3>'); - $build['system_actions_table'] = array('#markup' => theme('table', $header, $row)); - } - - if ($actions_map) { - $build['system_actions_manage_form'] = drupal_get_form('system_actions_manage_form', $options); - } - - return $build; -} - -/** - * Define the form for the actions overview page. - * - * @see system_actions_manage_form_submit() - * @ingroup forms - * @param $form_state - * An associative array containing the current state of the form; not used. - * @param $options - * An array of configurable actions. - * @return - * Form definition. - */ -function system_actions_manage_form($form, $form_state, $options = array()) { - $form['parent'] = array( - '#type' => 'fieldset', - '#title' => t('Make a new advanced action available'), - '#prefix' => '<div class="container-inline">', - '#suffix' => '</div>', - ); - $form['parent']['action'] = array( - '#type' => 'select', - '#default_value' => '', - '#options' => $options, - '#description' => '', - ); - $form['parent']['buttons']['submit'] = array( - '#type' => 'submit', - '#value' => t('Create'), - ); - return $form; -} - -/** - * Process system_actions_manage form submissions. - */ -function system_actions_manage_form_submit($form, &$form_state) { - if ($form_state['values']['action']) { - $form_state['redirect'] = 'admin/config/system/actions/configure/' . $form_state['values']['action']; - } -} - -/** - * Menu callback. Create the form for configuration of a single action. - * - * We provide the "Description" field. The rest of the form - * is provided by the action. We then provide the Save button. - * Because we are combining unknown form elements with the action - * configuration form, we use actions_ prefix on our elements. - * - * @see system_actions_configure_validate() - * @see system_actions_configure_submit() - * @param $action - * md5 hash of action ID or an integer. If it's an md5 hash, we - * are creating a new instance. If it's an integer, we're editing - * an existing instance. - * @return - * Form definition. - */ -function system_actions_configure($form, &$form_state, $action = NULL) { - if ($action === NULL) { - drupal_goto('admin/config/system/actions'); - } - - $actions_map = actions_actions_map(actions_list()); - $edit = array(); - - // Numeric action denotes saved instance of a configurable action; - // else we are creating a new action instance. - if (is_numeric($action)) { - $aid = $action; - // Load stored parameter values from database. - $data = db_query("SELECT * FROM {actions} WHERE aid = :aid", array(':aid' => $aid))->fetch(); - $edit['actions_description'] = $data->description; - $edit['actions_type'] = $data->type; - $function = $data->callback; - $action = md5($data->callback); - $params = unserialize($data->parameters); - if ($params) { - foreach ($params as $name => $val) { - $edit[$name] = $val; - } - } - } - else { - $function = $actions_map[$action]['callback']; - $edit['actions_description'] = $actions_map[$action]['description']; - $edit['actions_type'] = $actions_map[$action]['type']; - } - - $form['actions_description'] = array( - '#type' => 'textfield', - '#title' => t('Description'), - '#default_value' => $edit['actions_description'], - '#maxlength' => '255', - '#description' => t('A unique description for this advanced action. This description will be displayed in the interface of modules that integrate with actions, such as Trigger module.'), - '#weight' => -10 - ); - $action_form = $function . '_form'; - $form = array_merge($form, $action_form($edit)); - $form['actions_type'] = array( - '#type' => 'value', - '#value' => $edit['actions_type'], - ); - $form['actions_action'] = array( - '#type' => 'hidden', - '#value' => $action, - ); - // $aid is set when configuring an existing action instance. - if (isset($aid)) { - $form['actions_aid'] = array( - '#type' => 'hidden', - '#value' => $aid, - ); - } - $form['actions_configured'] = array( - '#type' => 'hidden', - '#value' => '1', - ); - $form['buttons']['submit'] = array( - '#type' => 'submit', - '#value' => t('Save'), - '#weight' => 13 - ); - - return $form; -} - -/** - * Validate system_actions_configure form submissions. - */ -function system_actions_configure_validate($form, $form_state) { - $function = actions_function_lookup($form_state['values']['actions_action']) . '_validate'; - // Hand off validation to the action. - if (function_exists($function)) { - $function($form, $form_state); - } -} - -/** - * Process system_actions_configure form submissions. - */ -function system_actions_configure_submit($form, &$form_state) { - $function = actions_function_lookup($form_state['values']['actions_action']); - $submit_function = $function . '_submit'; - - // Action will return keyed array of values to store. - $params = $submit_function($form, $form_state); - $aid = isset($form_state['values']['actions_aid']) ? $form_state['values']['actions_aid'] : NULL; - - actions_save($function, $form_state['values']['actions_type'], $params, $form_state['values']['actions_description'], $aid); - drupal_set_message(t('The action has been successfully saved.')); - - $form_state['redirect'] = 'admin/config/system/actions/manage'; -} - -/** - * Create the form for confirmation of deleting an action. - * - * @ingroup forms - * @see system_actions_delete_form_submit() - */ -function system_actions_delete_form($form, $form_state, $action) { - - $form['aid'] = array( - '#type' => 'hidden', - '#value' => $action->aid, - ); - return confirm_form($form, - t('Are you sure you want to delete the action %action?', array('%action' => $action->description)), - 'admin/config/system/actions/manage', - t('This cannot be undone.'), - t('Delete'), t('Cancel') + 'triggers' => array('any'), + ), ); } /** - * Process system_actions_delete form submissions. - * - * Post-deletion operations for action deletion. - */ -function system_actions_delete_form_submit($form, &$form_state) { - $aid = $form_state['values']['aid']; - $action = actions_load($aid); - actions_delete($aid); - $description = check_plain($action->description); - watchdog('user', 'Deleted action %aid (%action)', array('%aid' => $aid, '%action' => $description)); - drupal_set_message(t('Action %action was deleted', array('%action' => $description))); - $form_state['redirect'] = 'admin/config/system/actions/manage'; -} - -/** - * Post-deletion operations for deleting action orphans. - * - * @param $orphaned - * An array of orphaned actions. - */ -function system_action_delete_orphans_post($orphaned) { - foreach ($orphaned as $callback) { - drupal_set_message(t("Deleted orphaned action (%action).", array('%action' => $callback))); - } -} - -/** - * Remove actions that are in the database but not supported by any enabled module. - */ -function system_actions_remove_orphans() { - actions_synchronize(TRUE); - drupal_goto('admin/config/system/actions/manage'); -} - -/** * Return a form definition so the Send email action can be configured. * * @see system_send_email_action_validate() |