cms/drupal/modules/trigger/trigger.admin.inc
changeset 541 e756a8c72c3d
equal deleted inserted replaced
540:07239de796bb 541:e756a8c72c3d
       
     1 <?php
       
     2 
       
     3 /**
       
     4  * @file
       
     5  * Admin page callbacks for the trigger module.
       
     6  */
       
     7 
       
     8 /**
       
     9  * Builds a form that allows users to assign actions to triggers.
       
    10  *
       
    11  * @param $module_to_display
       
    12  *   Which tab of triggers to display. E.g., 'node' for all node-related
       
    13  *   triggers.
       
    14  *
       
    15  * @return
       
    16  *   HTML form.
       
    17  *
       
    18  * @see trigger_menu()
       
    19  */
       
    20 function trigger_assign($module_to_display = NULL) {
       
    21   // If no type is specified we default to node actions, since they
       
    22   // are the most common.
       
    23   if (!isset($module_to_display)) {
       
    24     drupal_goto('admin/structure/trigger/node');
       
    25   }
       
    26 
       
    27   $build = array();
       
    28   $trigger_info = module_invoke_all('trigger_info');
       
    29   drupal_alter('trigger_info', $trigger_info);
       
    30   foreach ($trigger_info as $module => $hooks) {
       
    31     if ($module == $module_to_display) {
       
    32       foreach ($hooks as $hook => $description) {
       
    33         $form_id = 'trigger_' . $hook . '_assign_form';
       
    34         $build[$form_id] = drupal_get_form($form_id, $module, $hook, $description['label']);
       
    35       }
       
    36     }
       
    37   }
       
    38   return $build;
       
    39 }
       
    40 
       
    41 /**
       
    42  * Form constructor for confirmation page for removal of an assigned action.
       
    43  *
       
    44  * @param $module
       
    45  *   The tab of triggers the user will be directed to after successful
       
    46  *   removal of the action, or if the confirmation form is cancelled.
       
    47  * @param $hook
       
    48  *   The name of the trigger hook, e.g., 'node_insert'.
       
    49  * @param $aid
       
    50  *   The action ID.
       
    51  *
       
    52  * @see trigger_unassign_submit()
       
    53  * @ingroup forms
       
    54  */
       
    55 function trigger_unassign($form, $form_state, $module, $hook = NULL, $aid = NULL) {
       
    56   if (!isset($hook, $aid)) {
       
    57     drupal_goto('admin/structure/trigger');
       
    58   }
       
    59 
       
    60   $form['hook'] = array(
       
    61     '#type' => 'value',
       
    62     '#value' => $hook,
       
    63   );
       
    64   $form['module'] = array(
       
    65     '#type' => 'value',
       
    66     '#value' => $module,
       
    67   );
       
    68   $form['aid'] = array(
       
    69     '#type' => 'value',
       
    70     '#value' => $aid,
       
    71   );
       
    72 
       
    73   $action = actions_function_lookup($aid);
       
    74   $actions = actions_get_all_actions();
       
    75 
       
    76   $destination = 'admin/structure/trigger/' . $module;
       
    77 
       
    78   return confirm_form($form,
       
    79     t('Are you sure you want to unassign the action %title?', array('%title' => $actions[$action]['label'])),
       
    80     $destination,
       
    81     t('You can assign it again later if you wish.'),
       
    82     t('Unassign'), t('Cancel')
       
    83   );
       
    84 }
       
    85 
       
    86 /**
       
    87  * Form submission handler for trigger_unassign().
       
    88  */
       
    89 function trigger_unassign_submit($form, &$form_state) {
       
    90   if ($form_state['values']['confirm'] == 1) {
       
    91     $aid = actions_function_lookup($form_state['values']['aid']);
       
    92     db_delete('trigger_assignments')
       
    93       ->condition('hook', $form_state['values']['hook'])
       
    94       ->condition('aid', $aid)
       
    95       ->execute();
       
    96     drupal_static_reset('trigger_get_assigned_actions');
       
    97     $actions = actions_get_all_actions();
       
    98     watchdog('actions', 'Action %action has been unassigned.',  array('%action' => $actions[$aid]['label']));
       
    99     drupal_set_message(t('Action %action has been unassigned.', array('%action' => $actions[$aid]['label'])));
       
   100     $form_state['redirect'] = 'admin/structure/trigger/' . $form_state['values']['module'];
       
   101   }
       
   102   else {
       
   103     drupal_goto('admin/structure/trigger');
       
   104   }
       
   105 }
       
   106 
       
   107 /**
       
   108  * Returns the form for assigning an action to a trigger.
       
   109  *
       
   110  * @param $module
       
   111  *   The name of the trigger group, e.g., 'node'.
       
   112  * @param $hook
       
   113  *   The name of the trigger hook, e.g., 'node_insert'.
       
   114  * @param $label
       
   115  *   A plain English description of what this trigger does.
       
   116  *
       
   117  * @see trigger_assign_form_validate()
       
   118  * @see trigger_assign_form_submit()
       
   119  * @ingroup forms
       
   120  */
       
   121 function trigger_assign_form($form, $form_state, $module, $hook, $label) {
       
   122   $form['module'] = array(
       
   123     '#type' => 'hidden',
       
   124     '#value' => $module,
       
   125   );
       
   126   $form['hook'] = array(
       
   127     '#type' => 'hidden',
       
   128     '#value' => $hook,
       
   129   );
       
   130   // All of these forms use the same validate and submit functions.
       
   131   $form['#validate'][] = 'trigger_assign_form_validate';
       
   132   $form['#submit'][] = 'trigger_assign_form_submit';
       
   133 
       
   134   $options = array();
       
   135   $functions = array();
       
   136   // Restrict the options list to actions that declare support for this hook.
       
   137   foreach (actions_list() as $func => $metadata) {
       
   138     if (isset($metadata['triggers']) && array_intersect(array($hook, 'any'), $metadata['triggers'])) {
       
   139       $functions[] = $func;
       
   140     }
       
   141   }
       
   142   foreach (actions_actions_map(actions_get_all_actions()) as $aid => $action) {
       
   143     if (in_array($action['callback'], $functions)) {
       
   144       $options[$action['type']][$aid] = $action['label'];
       
   145     }
       
   146   }
       
   147 
       
   148   $form[$hook] = array(
       
   149     '#type' => 'fieldset',
       
   150     // !description is correct, since these labels are passed through t() in
       
   151     // hook_trigger_info().
       
   152     '#title' => t('Trigger: !description', array('!description' => $label)),
       
   153     '#theme' => 'trigger_display',
       
   154   );
       
   155 
       
   156   // Retrieve actions that are already assigned to this hook combination.
       
   157   $actions = trigger_get_assigned_actions($hook);
       
   158   $form[$hook]['assigned']['#type'] = 'value';
       
   159   $form[$hook]['assigned']['#value'] = array();
       
   160   foreach ($actions as $aid => $info) {
       
   161     // If action is defined unassign it, otherwise offer to delete all orphaned
       
   162     // actions.
       
   163     $hash = drupal_hash_base64($aid, TRUE);
       
   164     if (actions_function_lookup($hash)) {
       
   165       $form[$hook]['assigned']['#value'][$aid] = array(
       
   166         'label' => $info['label'],
       
   167         'link' => l(t('unassign'), "admin/structure/trigger/unassign/$module/$hook/$hash"),
       
   168       );
       
   169     }
       
   170     else {
       
   171       // Link to system_actions_remove_orphans() to do the clean up.
       
   172       $form[$hook]['assigned']['#value'][$aid] = array(
       
   173         'label' => $info['label'],
       
   174         'link' => l(t('Remove orphaned actions'), "admin/config/system/actions/orphan"),
       
   175       );
       
   176     }
       
   177   }
       
   178 
       
   179   $form[$hook]['parent'] = array(
       
   180     '#type' => 'container',
       
   181     '#attributes' => array('class' => array('container-inline')),
       
   182   );
       
   183   // List possible actions that may be assigned.
       
   184   if (count($options) != 0) {
       
   185     $form[$hook]['parent']['aid'] = array(
       
   186       '#type' => 'select',
       
   187       '#title' => t('List of trigger actions when !description', array('!description' => $label)),
       
   188       '#title_display' => 'invisible',
       
   189       '#options' => $options,
       
   190       '#empty_option' => t('Choose an action'),
       
   191     );
       
   192     $form[$hook]['parent']['submit'] = array(
       
   193       '#type' => 'submit',
       
   194       '#value' => t('Assign')
       
   195     );
       
   196   }
       
   197   else {
       
   198     $form[$hook]['none'] = array(
       
   199       '#markup' => t('No actions available for this trigger. <a href="@link">Add action</a>.', array('@link' => url('admin/config/system/actions/manage')))
       
   200     );
       
   201   }
       
   202   return $form;
       
   203 }
       
   204 
       
   205 /**
       
   206  * Form validation handler for trigger_assign_form().
       
   207  *
       
   208  * Makes sure that the user is not re-assigning an action to an event.
       
   209  *
       
   210  * @see trigger_assign_form_submit()
       
   211  */
       
   212 function trigger_assign_form_validate($form, $form_state) {
       
   213   $form_values = $form_state['values'];
       
   214   if (!empty($form_values['aid'])) {
       
   215     $aid = actions_function_lookup($form_values['aid']);
       
   216     $aid_exists = db_query("SELECT aid FROM {trigger_assignments} WHERE hook = :hook AND aid = :aid", array(
       
   217       ':hook' => $form_values['hook'],
       
   218       ':aid' => $aid,
       
   219     ))->fetchField();
       
   220     if ($aid_exists) {
       
   221       form_set_error($form_values['hook'], t('The action you chose is already assigned to that trigger.'));
       
   222     }
       
   223   }
       
   224 }
       
   225 
       
   226 /**
       
   227  * Form submission handler for trigger_assign_form().
       
   228  *
       
   229  * @see trigger_assign_form_validate()
       
   230  */
       
   231 function trigger_assign_form_submit($form, &$form_state) {
       
   232   if (!empty($form_state['values']['aid'])) {
       
   233     $aid = actions_function_lookup($form_state['values']['aid']);
       
   234     $weight = db_query("SELECT MAX(weight) FROM {trigger_assignments} WHERE hook = :hook", array(':hook' => $form_state['values']['hook']))->fetchField();
       
   235 
       
   236     // Insert the new action.
       
   237     db_insert('trigger_assignments')
       
   238       ->fields(array(
       
   239         'hook' => $form_state['values']['hook'],
       
   240         'aid' => $aid,
       
   241         'weight' => $weight + 1,
       
   242       ))
       
   243       ->execute();
       
   244 
       
   245     // If we are not configuring an action for a "presave" hook and this action
       
   246     // changes an object property, then we need to save the object, so the
       
   247     // property change will persist.
       
   248     $actions = actions_list();
       
   249     if (strpos($form_state['values']['hook'], 'presave') === FALSE && isset($actions[$aid]['behavior']) && in_array('changes_property', $actions[$aid]['behavior'])) {
       
   250       // Determine the corresponding save action name for this action.
       
   251       $save_action = strtok($aid, '_') . '_save_action';
       
   252       // If no corresponding save action exists, we need to bail out.
       
   253       if (!isset($actions[$save_action])) {
       
   254         throw new Exception(t('Missing/undefined save action (%save_aid) for %aid action.', array('%save_aid' => $aid, '%aid' => $aid)));
       
   255       }
       
   256       // Delete previous save action if it exists, and re-add it using a higher
       
   257       // weight.
       
   258       $save_action_assigned = db_query("SELECT aid FROM {trigger_assignments} WHERE hook = :hook AND aid = :aid", array(':hook' => $form_state['values']['hook'], ':aid' => $save_action))->fetchField();
       
   259 
       
   260       if ($save_action_assigned) {
       
   261         db_delete('trigger_assignments')
       
   262           ->condition('hook', $form_state['values']['hook'])
       
   263           ->condition('aid', $save_action)
       
   264           ->execute();
       
   265       }
       
   266       db_insert('trigger_assignments')
       
   267         ->fields(array(
       
   268           'hook' => $form_state['values']['hook'],
       
   269           'aid' => $save_action,
       
   270           'weight' => $weight + 2,
       
   271         ))
       
   272         ->execute();
       
   273 
       
   274       // If no save action existed before, inform the user about it.
       
   275       if (!$save_action_assigned) {
       
   276         drupal_set_message(t('The %label action has been appended, which is required to save the property change.', array('%label' => $actions[$save_action]['label'])));
       
   277       }
       
   278       // Otherwise, just inform about the new weight.
       
   279       else {
       
   280         drupal_set_message(t('The %label action was moved to save the property change.', array('%label' => $actions[$save_action]['label'])));
       
   281       }
       
   282     }
       
   283   }
       
   284   drupal_static_reset('trigger_get_assigned_actions');
       
   285 }
       
   286 
       
   287 /**
       
   288  * Returns HTML for the form showing actions assigned to a trigger.
       
   289  *
       
   290  * @param $variables
       
   291  *   An associative array containing:
       
   292  *   - element: The fieldset including all assigned actions.
       
   293  *
       
   294  * @ingroup themeable
       
   295  */
       
   296 function theme_trigger_display($variables) {
       
   297   $element = $variables['element'];
       
   298 
       
   299   $header = array();
       
   300   $rows = array();
       
   301   if (isset($element['assigned']) && count($element['assigned']['#value'])) {
       
   302     $header = array(array('data' => t('Name')), array('data' => t('Operation')));
       
   303     $rows = array();
       
   304     foreach ($element['assigned']['#value'] as $aid => $info) {
       
   305       $rows[] = array(
       
   306         check_plain($info['label']),
       
   307         $info['link']
       
   308       );
       
   309     }
       
   310   }
       
   311 
       
   312   if (count($rows)) {
       
   313     $output = theme('table', array('header' => $header, 'rows' => $rows)) . drupal_render_children($element);
       
   314   }
       
   315   else {
       
   316     $output = drupal_render_children($element);
       
   317   }
       
   318   return $output;
       
   319 }