web/drupal/modules/trigger/trigger.admin.inc
branchdrupal
changeset 74 0ff3ba646492
equal deleted inserted replaced
73:fcf75e232c5b 74:0ff3ba646492
       
     1 <?php
       
     2 // $Id: trigger.admin.inc,v 1.5 2008/01/08 10:35:43 goba Exp $
       
     3 
       
     4 /**
       
     5  * @file
       
     6  * Admin page callbacks for the trigger module.
       
     7  */
       
     8 
       
     9 /**
       
    10  * Build the form that allows users to assign actions to hooks.
       
    11  *
       
    12  * @param $type
       
    13  *   Name of hook.
       
    14  * @return
       
    15  *   HTML form.
       
    16  */
       
    17 function trigger_assign($type = NULL) {
       
    18   // If no type is specified we default to node actions, since they
       
    19   // are the most common.
       
    20   if (!isset($type)) {
       
    21     drupal_goto('admin/build/trigger/node');
       
    22   }
       
    23   if ($type == 'node') {
       
    24     $type = 'nodeapi';
       
    25   }
       
    26 
       
    27   $output = '';
       
    28   $hooks = module_invoke_all('hook_info');
       
    29   foreach ($hooks as $module => $hook) {
       
    30     if (isset($hook[$type])) {
       
    31       foreach ($hook[$type] as $op => $description) {
       
    32         $form_id = 'trigger_'. $type .'_'. $op .'_assign_form';
       
    33         $output .= drupal_get_form($form_id, $type, $op, $description['runs when']);
       
    34       }
       
    35     }
       
    36   }
       
    37   return $output;
       
    38 }
       
    39 
       
    40 /**
       
    41  * Confirm removal of an assigned action.
       
    42  *
       
    43  * @param $hook
       
    44  * @param $op
       
    45  * @param $aid
       
    46  *   The action ID.
       
    47  * @ingroup forms
       
    48  * @see trigger_unassign_submit()
       
    49  */
       
    50 function trigger_unassign($form_state, $hook = NULL, $op = NULL, $aid = NULL) {
       
    51   if (!($hook && $op && $aid)) {
       
    52     drupal_goto('admin/build/trigger/assign');
       
    53   }
       
    54 
       
    55   $form['hook'] = array(
       
    56     '#type' => 'value',
       
    57     '#value' => $hook,
       
    58   );
       
    59   $form['operation'] = array(
       
    60     '#type' => 'value',
       
    61     '#value' => $op,
       
    62   );
       
    63   $form['aid'] = array(
       
    64     '#type' => 'value',
       
    65     '#value' => $aid,
       
    66   );
       
    67 
       
    68   $action = actions_function_lookup($aid);
       
    69   $actions = actions_get_all_actions();
       
    70 
       
    71   $destination = 'admin/build/trigger/'. ($hook == 'nodeapi' ? 'node' : $hook);
       
    72 
       
    73   return confirm_form($form,
       
    74     t('Are you sure you want to unassign the action %title?', array('%title' => $actions[$action]['description'])),
       
    75     $destination,
       
    76     t('You can assign it again later if you wish.'),
       
    77     t('Unassign'), t('Cancel')
       
    78   );
       
    79 }
       
    80 
       
    81 function trigger_unassign_submit($form, &$form_state) {
       
    82   $form_values = $form_state['values'];
       
    83   if ($form_values['confirm'] == 1) {
       
    84     $aid = actions_function_lookup($form_values['aid']);
       
    85     db_query("DELETE FROM {trigger_assignments} WHERE hook = '%s' AND op = '%s' AND aid = '%s'", $form_values['hook'], $form_values['operation'], $aid);
       
    86     $actions = actions_get_all_actions();
       
    87     watchdog('actions', 'Action %action has been unassigned.',  array('%action' => check_plain($actions[$aid]['description'])));
       
    88     drupal_set_message(t('Action %action has been unassigned.', array('%action' => $actions[$aid]['description'])));
       
    89     $hook = $form_values['hook'] == 'nodeapi' ? 'node' : $form_values['hook'];
       
    90     $form_state['redirect'] = 'admin/build/trigger/'. $hook;
       
    91   }
       
    92   else {
       
    93     drupal_goto('admin/build/trigger');
       
    94   }
       
    95 }
       
    96 
       
    97 /**
       
    98  * Create the form definition for assigning an action to a hook-op combination.
       
    99  *
       
   100  * @param $form_state
       
   101  *   Information about the current form.
       
   102  * @param $hook
       
   103  *   The name of the hook, e.g., 'nodeapi'.
       
   104  * @param $op
       
   105  *   The name of the hook operation, e.g., 'insert'.
       
   106  * @param $description
       
   107  *   A plain English description of what this hook operation does.
       
   108  * @return
       
   109  *
       
   110  * @ingoup forms
       
   111  * @see trigger_assign_form_validate()
       
   112  * @see trigger_assign_form_submit()
       
   113  */
       
   114 function trigger_assign_form($form_state, $hook, $op, $description) {
       
   115   $form['hook'] = array(
       
   116     '#type' => 'hidden',
       
   117     '#value' => $hook,
       
   118   );
       
   119   $form['operation'] = array(
       
   120     '#type' => 'hidden',
       
   121     '#value' => $op,
       
   122   );
       
   123   // All of these forms use the same validate and submit functions.
       
   124   $form['#validate'][] = 'trigger_assign_form_validate';
       
   125   $form['#submit'][] = 'trigger_assign_form_submit';
       
   126 
       
   127   $options = array();
       
   128   $functions = array();
       
   129   // Restrict the options list to actions that declare support for this hook-op
       
   130   // combination.
       
   131   foreach (actions_list() as $func => $metadata) {
       
   132     if (isset($metadata['hooks']['any']) || (isset($metadata['hooks'][$hook]) && is_array($metadata['hooks'][$hook]) && (in_array($op, $metadata['hooks'][$hook])))) {
       
   133       $functions[] = $func;
       
   134     }
       
   135   }
       
   136   foreach (actions_actions_map(actions_get_all_actions()) as $aid => $action) {
       
   137     if (in_array($action['callback'], $functions)) {
       
   138       $options[$action['type']][$aid] = $action['description'];
       
   139     }
       
   140   }
       
   141 
       
   142   $form[$op] = array(
       
   143     '#type' => 'fieldset',
       
   144     '#title' => t('Trigger: ') . $description,
       
   145     '#theme' => 'trigger_display'
       
   146     );
       
   147   // Retrieve actions that are already assigned to this hook-op combination.
       
   148   $actions = _trigger_get_hook_actions($hook, $op);
       
   149   $form[$op]['assigned']['#type'] = 'value';
       
   150   $form[$op]['assigned']['#value'] = array();
       
   151   foreach ($actions as $aid => $description) {
       
   152     $form[$op]['assigned']['#value'][$aid] = array(
       
   153       'description' => $description,
       
   154       'link' => l(t('unassign'), "admin/build/trigger/unassign/$hook/$op/". md5($aid))
       
   155     );
       
   156   }
       
   157 
       
   158   $form[$op]['parent'] = array(
       
   159     '#prefix' => "<div class='container-inline'>",
       
   160     '#suffix' => '</div>',
       
   161   );
       
   162   // List possible actions that may be assigned.
       
   163   if (count($options) != 0) {
       
   164     array_unshift($options, t('Choose an action'));
       
   165     $form[$op]['parent']['aid'] = array(
       
   166       '#type' => 'select',
       
   167       '#options' => $options,
       
   168     );
       
   169     $form[$op]['parent']['submit'] = array(
       
   170       '#type' => 'submit',
       
   171       '#value' => t('Assign')
       
   172     );
       
   173   }
       
   174   else {
       
   175     $form[$op]['none'] = array(
       
   176       '#value' => t('No available actions for this trigger.')
       
   177     );
       
   178   }
       
   179   return $form;
       
   180 }
       
   181 
       
   182 /**
       
   183  * Validation function for trigger_assign_form().
       
   184  *
       
   185  * Makes sure that the user is not re-assigning an action to an event.
       
   186  */
       
   187 function trigger_assign_form_validate($form, $form_state) {
       
   188   $form_values = $form_state['values'];
       
   189   if (!empty($form_values['aid'])) {
       
   190     $aid = actions_function_lookup($form_values['aid']);
       
   191     if (db_result(db_query("SELECT aid FROM {trigger_assignments} WHERE hook = '%s' AND op = '%s' AND aid = '%s'", $form_values['hook'], $form_values['operation'], $aid))) {
       
   192       form_set_error($form_values['operation'], t('The action you chose is already assigned to that trigger.'));
       
   193     }
       
   194   }
       
   195 }
       
   196 
       
   197 /**
       
   198  * Submit function for trigger_assign_form().
       
   199  */
       
   200 function trigger_assign_form_submit($form, $form_state) {
       
   201   $form_values = $form_state['values'];
       
   202 
       
   203   if (!empty($form_values['aid'])) {
       
   204     $aid = actions_function_lookup($form_values['aid']);
       
   205     $weight = db_result(db_query("SELECT MAX(weight) FROM {trigger_assignments} WHERE hook = '%s' AND op = '%s'", $form_values['hook'], $form_values['operation']));
       
   206     db_query("INSERT INTO {trigger_assignments} values ('%s', '%s', '%s', %d)", $form_values['hook'], $form_values['operation'], $aid, $weight + 1);
       
   207     // If this action changes a node property, we need to save the node
       
   208     // so the change will persist.
       
   209     $actions = actions_list();
       
   210     if (isset($actions[$aid]['behavior']) && in_array('changes_node_property', $actions[$aid]['behavior']) && ($form_values['operation'] != 'presave')) {
       
   211       // Delete previous node_save_action if it exists, and re-add a new one at a higher weight.
       
   212       $save_post_action_assigned = db_result(db_query("SELECT aid FROM {trigger_assignments} WHERE hook = '%s' AND op = '%s' AND aid = 'node_save_action'", $form_values['hook'], $form_values['operation']));
       
   213       if ($save_post_action_assigned) {
       
   214         db_query("DELETE FROM {trigger_assignments} WHERE hook = '%s' AND op = '%s' AND aid = 'node_save_action'", $form_values['hook'], $form_values['operation']);
       
   215       }
       
   216       db_query("INSERT INTO {trigger_assignments} VALUES ('%s', '%s', '%s', %d)", $form_values['hook'], $form_values['operation'], 'node_save_action', $weight + 2);
       
   217       if (!$save_post_action_assigned) {
       
   218         drupal_set_message(t('You have added an action that changes a the property of a post. A Save post action has been added so that the property change will be saved.'));
       
   219       }
       
   220     }
       
   221   }
       
   222 }
       
   223 
       
   224 /**
       
   225  * Display actions assigned to this hook-op combination in a table.
       
   226  *
       
   227  * @param array $element
       
   228  *   The fieldset including all assigned actions.
       
   229  * @return
       
   230  *   The rendered form with the table prepended.
       
   231  *
       
   232  * @ingroup themeable
       
   233  */
       
   234 function theme_trigger_display($element) {
       
   235   $header = array();
       
   236   $rows = array();
       
   237   if (count($element['assigned']['#value'])) {
       
   238     $header = array(array('data' => t('Name')), array('data' => t('Operation')));
       
   239     $rows = array();
       
   240     foreach ($element['assigned']['#value'] as $aid => $info) {
       
   241       $rows[] = array(
       
   242         $info['description'],
       
   243         $info['link']
       
   244       );
       
   245     }
       
   246   }
       
   247 
       
   248   if (count($rows)) {
       
   249     $output = theme('table', $header, $rows) . drupal_render($element);
       
   250   }
       
   251   else {
       
   252     $output = drupal_render($element);
       
   253   }
       
   254   return $output;
       
   255 }
       
   256 
       
   257 
       
   258 /**
       
   259  * Get the actions that have already been defined for this
       
   260  * type-hook-op combination.
       
   261  *
       
   262  * @param $type
       
   263  *   One of 'node', 'user', 'comment'.
       
   264  * @param $hook
       
   265  *   The name of the hook for which actions have been assigned,
       
   266  *   e.g. 'nodeapi'.
       
   267  * @param $op
       
   268  *   The hook operation for which the actions have been assigned,
       
   269  *   e.g., 'view'.
       
   270  * @return
       
   271  *   An array of action descriptions keyed by action IDs.
       
   272  */
       
   273 function _trigger_get_hook_actions($hook, $op, $type = NULL) {
       
   274   $actions = array();
       
   275   if ($type) {
       
   276     $result = db_query("SELECT h.aid, a.description FROM {trigger_assignments} h LEFT JOIN {actions} a on a.aid = h.aid WHERE a.type = '%s' AND h.hook = '%s' AND h.op = '%s' ORDER BY h.weight", $type, $hook, $op);
       
   277   }
       
   278   else {
       
   279     $result = db_query("SELECT h.aid, a.description FROM {trigger_assignments} h LEFT JOIN {actions} a on a.aid = h.aid WHERE h.hook = '%s' AND h.op = '%s' ORDER BY h.weight", $hook, $op);
       
   280   }
       
   281   while ($action = db_fetch_object($result)) {
       
   282     $actions[$action->aid] = $action->description;
       
   283   }
       
   284   return $actions;
       
   285 }