| [ Index ] |
PHP Cross Reference of Drupal 6 (gatewave) |
[Summary view] [Print] [Text view]
1 <?php 2 // $Id: rules_admin.rule_forms.inc,v 1.1.2.11 2011/01/05 13:59:43 fago Exp $ 3 4 5 /** 6 * @file Rules Admin UI 7 * Implements rule management and configuration screens. 8 */ 9 10 rules_include('rules_admin'); 11 12 /** 13 * Lists the available rules. 14 */ 15 function rules_admin_form_overview(&$form_state) { 16 // Check if token module is present. 17 rules_admin_check_token(); 18 $form['filter'] = array( 19 '#type' => 'fieldset', 20 '#title' => t('Filter'), 21 '#collapsible' => TRUE, 22 '#collapsed' => isset($form_state['values']) || count(rules_get_configured_items('rules')) < 20, 23 ); 24 $form['filter']['set'] = array( 25 '#type' => 'select', 26 '#title' => t('Filter by event'), 27 '#options' => array(0 => '<All>') + rules_admin_get_grouped_labels(rules_get_events()), 28 '#default_value' => isset($form_state['values']['set']) ? $form_state['values']['set'] : 0, 29 ); 30 $form['filter']['category'] = array( 31 '#type' => 'select', 32 '#title' => t('Filter by category'), 33 '#options' => array(0 => '<All>') + rules_admin_get_categories('rules'), 34 '#default_value' => isset($form_state['values']['category']) ? $form_state['values']['category'] : 0, 35 ); 36 $form['filter']['submit'] = array('#type' => 'submit', '#value' => t('Filter')); 37 38 $category = !empty($form_state['values']['category']) ? $form_state['values']['category'] : FALSE; 39 $set = !empty($form_state['values']['set']) ? 'event_'. $form_state['values']['set'] : FALSE; 40 41 $form['active_header'] = array('#value' => '<h3>'. t('Active rules') .'</h3>'); 42 $form['active'] = rules_admin_overview_table(array('category' => $category, 'set' => $set, 'active' => TRUE)); 43 $form['active']['#suffix'] = '<br />'; 44 $form['inactive_header'] = array('#value' => '<h3>'. t('Inactive rules') .'</h3>'); 45 $form['inactive'] = rules_admin_overview_table(array('category' => $category, 'set' => $set, 'active' => FALSE)); 46 47 if (variable_get('rules_show_fixed', FALSE)) { 48 $form['fixed_header'] = array('#value' => '<h3>'. t('Fixed rules') .'</h3>'); 49 $form['fixed'] = rules_admin_overview_table(array('category' => $category, 'set' => $set, 'active' => TRUE, 'fixed' => TRUE)); 50 } 51 return $form; 52 } 53 54 function rules_admin_form_overview_submit($form_id, &$form_state) { 55 $form_state['rebuild'] = TRUE; 56 } 57 58 /** 59 * Check to see if the token module is installed, and if not put up 60 * a message. 61 * 62 * Only call this function if the user is already in a position for this to 63 * be useful. 64 */ 65 function rules_admin_check_token() { 66 if (!variable_get('rules_hide_token_message', FALSE) && !module_exists('token')) { 67 drupal_set_message(t('If you install the token module from !href, token replacements will be supported. <a href="@hide">Hide this message.</a>', array('!href' => l('http://drupal.org/project/token', 'http://drupal.org/project/token'), '@hide' => url('admin/rules/settings')))); 68 } 69 } 70 71 /** 72 * Returns the add rule form 73 */ 74 function rules_admin_form_add_rule(&$form_state, $set_info = FALSE) { 75 drupal_add_js(drupal_get_path('module', 'rules_admin') . '/rules_admin.js'); 76 $form = rules_admin_form_rule_settings(array(), (boolean)$set_info); 77 $form['settings']['set']['#default_value'] = $set_info['name']; 78 return $form; 79 } 80 81 function rules_admin_form_add_rule_validate($form_id, &$form_state) { 82 rules_admin_validate_machine_name('rules', 'name', $form_state['values']['name']); 83 } 84 85 function rules_admin_form_add_rule_submit($form_id, &$form_state) { 86 $rule = isset($form_state['proxy']) ? $form_state['proxy']->get_rule() : array('#type' => 'rule'); 87 88 foreach (array('set', 'label', 'active', 'weight') as $key) { 89 $rule['#'. $key] = $form_state['values'][$key]; 90 } 91 $rule['#categories'] = array_filter(array_map('trim', explode(',', $form_state['values']['categories']))); 92 $rule['#status'] = 'custom'; 93 94 // Get the name of the rule. 95 $rule_name = 'rules_' . $form_state['values']['name']; 96 97 rules_item_save('rules', $rule_name, $rule); 98 rules_clear_cache(); 99 drupal_set_message(t("The rule %label has been added. You can start adding some conditions or actions now.", array('%label' => $rule['#label']))); 100 $form_state['redirect'] = RULES_ADMIN_RULE_PATH .'/'. $rule_name; 101 } 102 103 /** 104 * Returns the form for the settings of a rule 105 * 106 * @param $is_set 107 * When adding a new rule for a rule set, TRUE. 108 */ 109 function rules_admin_form_rule_settings($rule, $is_set = FALSE, $changable_name = TRUE) { 110 $form['settings'] = array( 111 '#type' => 'fieldset', 112 '#title' => t('Rule settings'), 113 '#collapsible' => TRUE, 114 ); 115 $form['settings']['label'] = array( 116 '#title' => t('Label'), 117 '#type' => 'textfield', 118 '#description' => t('Choose an appropriate label for this rule.'), 119 '#default_value' => isset($rule['#label']) ? $rule['#label'] : '', 120 '#required' => TRUE, 121 ); 122 $form['settings']['name'] = array( 123 '#title' => t('Machine readable name'), 124 '#type' => 'textfield', 125 '#description' => t('Specify a unique name containing only alphanumeric characters, and underscores.'), 126 '#default_value' => isset($rule['#name']) ? $rule['#name'] : '', 127 '#disabled' => !$changable_name, 128 '#required' => TRUE, 129 ); 130 // Only set the value if name isn't changable. 131 if (!$changable_name) { 132 $form['settings']['name']['#value'] = $rule['#name']; 133 } 134 $form['settings']['set'] = array( 135 '#type' => 'select', 136 '#default_value' => isset($rule['#set']) ? $rule['#set'] : '', 137 '#required' => TRUE, 138 ); 139 if ($is_set) { 140 $form['settings']['set'] += array( 141 '#title' => t('Rule set'), 142 '#options' => rules_admin_get_grouped_labels(rules_admin_get_compatible_sets($rule, rules_get_configured_items('rule_sets'))), 143 '#description' => t('Select to which rule set this rule should belong.'), 144 ); 145 } 146 else { 147 $form['settings']['set'] += array( 148 '#title' => t('Event'), 149 '#options' => rules_admin_get_grouped_labels(rules_admin_get_compatible_sets($rule, rules_get_event_sets())), 150 '#description' => t('Select the event on which you want to evaluate this rule.'), 151 ); 152 }; 153 $form['settings']['categories'] = array( 154 '#type' => 'textfield', 155 '#title' => t('Categories'), 156 '#default_value' => isset($rule['#categories']) ? implode(', ', $rule['#categories']) : '', 157 '#description' => t('A comma-separated list of terms describing this rule. Example: funny, bungee jumping.'), 158 '#autocomplete_path' => RULES_ADMIN_PATH .'/autocomplete', 159 ); 160 $form['settings']['active'] = array( 161 '#title' => t('This rule is active and should be evaluated when the associated event occurs.'), 162 '#type' => 'checkbox', 163 '#default_value' => isset($rule['#active']) ? $rule['#active'] : 1, 164 ); 165 $form['settings']['weight'] = array( 166 '#title' => t('Weight'), 167 '#type' => 'weight', 168 '#description' => t('Adjust the weight to customize the evaluation order of rules.'), 169 '#default_value' => isset($rule['#weight']) ? $rule['#weight'] : 0, 170 ); 171 $form['settings']['button'] = array('#type' => 'submit', '#weight' => 10, '#value' => t('Save changes')); 172 return $form; 173 } 174 175 /** 176 * Returns the form for editing a rule 177 */ 178 function rules_admin_form_edit_rule(&$form_state, $proxy) { 179 $form_state['proxy'] = &$proxy; 180 $rule = $proxy->get_rule(); 181 _rules_element_defaults($rule); 182 $rule['#name'] = drupal_substr($proxy->get_rule_name(), drupal_strlen('rules_')); 183 $is_set = strpos($rule['#set'], 'event_') !== 0; 184 $form = rules_admin_form_rule_settings($rule, $is_set, $rule['#status'] == 'custom'); 185 $form['settings']['#collapsed'] = TRUE; 186 187 // Add help 188 rules_admin_element_help($form, $proxy->get_set_info()); 189 190 // Show a warning when editing custom rules form other modules 191 if ($rule['#status'] == 'custom' && strpos($proxy->get_rule_name(), 'rules_') !== 0) { 192 drupal_set_message(t('<em>Warning</em>: This rule has been provided by another module. <br />Be aware that any changes made through this interface might be overwritten once the providing module updates the rule.')); 193 } 194 195 $form['elements'] = array( 196 '#type' => 'fieldset', 197 '#title' => t('Rule elements'), 198 '#collapsible' => TRUE, 199 ); 200 201 //this will render the whole rule with the help of drupal_render(), 202 //see rules_admin.render.inc 203 $form['elements']['rule'] = $proxy->get_indexed_rule(); 204 $form['elements']['rule']['#name'] = $proxy->get_rule_name(); 205 $form['elements']['rule']['#theme'] = array('rules_admin_rule_render'); 206 207 return $form; 208 } 209 210 function rules_admin_form_edit_rule_validate($form, &$form_state) { 211 // Get the name of the rule. 212 $name = $form_state['proxy']->get_rule_name(); 213 // We only need to check this if the name differs. 214 if ('rules_' . $form_state['values']['name'] != $name) { 215 rules_admin_validate_machine_name('rules', 'name', $form_state['values']['name']); 216 } 217 } 218 219 function rules_admin_form_edit_rule_submit(&$form, &$form_state) { 220 $rule_ref = &$form_state['proxy']->get_rule(); 221 foreach (array('label', 'active', 'weight', 'set') as $key) { 222 $rule_ref['#'. $key] = $form_state['values'][$key]; 223 } 224 $rule_ref['#categories'] = array_filter(array_map('trim', explode(',', $form_state['values']['categories']))); 225 // Set the new rule name if needed. 226 if ($rule_ref['#status'] == 'custom' && $form_state['values']['name'] != $form_state['proxy']->get_rule_name()) { 227 $name = 'rules_' . $form_state['values']['name']; 228 $form_state['proxy']->set_rule_name($name); 229 $form_state['redirect'] = 'admin/rules/rules/' . $name . '/edit'; 230 } 231 $form_state['proxy']->save_changes(); 232 drupal_set_message(t("The rule %label has been updated.", array('%label' => $rule_ref['#label']))); 233 } 234 235 /** 236 * Returns the form for the add operation 237 * This handles adding conditions and actions 238 * 239 * @param $type Either 'action' or 'condition' or 'op' 240 * @param $parent_id The id of the the element where the condition / action is to be added 241 */ 242 function rules_admin_form_add(&$form_state, $proxy, $type, $parent_id = NULL) { 243 $form_state['proxy'] = &$proxy; 244 $rule = $proxy->get_rule(); 245 _rules_element_defaults($rule); 246 247 if (in_array($type, array('action', 'condition', 'op'))) { 248 if (!isset($form_state['element'])) { 249 //initial step! 250 $form_state += array('element' => array('#type' => $type), 'step' => 0); 251 } 252 $element = &$form_state['element']; 253 $element += array('#id' => NULL, '#settings' => array()); 254 255 // Due to adding storage during the form build, the form will be rebuilt 256 // immediately. So be sure to increase the step only out of a #submit callback. 257 // Also see http://drupal.org/node/302240. 258 259 if ($form_state['step'] == 0) { 260 if (isset($parent_id) && is_array($parent = $proxy->get_element(intval($parent_id)))) { 261 if (function_exists($function = 'rules_admin_form_add_'. $element['#type'])) { 262 $form_state['parent_id'] = intval($parent_id); 263 _rules_element_defaults($parent); 264 $form = $function($form_state, $element, $parent); 265 return rules_admin_form_pack_storage($form, $form_state); 266 } 267 } 268 } 269 else { 270 if (function_exists($function = 'rules_admin_form_edit_'. $type)) { 271 $form = $function($form_state, $element); 272 return rules_admin_form_pack_storage($form, $form_state); 273 } 274 } 275 } 276 drupal_not_found(); 277 exit; 278 } 279 280 /** 281 * Returns the form for the first action add page 282 */ 283 function rules_admin_form_add_action(&$form_state, &$element) { 284 $vars = $form_state['proxy']->get_available_variables(); 285 $all_actions = rules_get_actions(); 286 $satisfied_actions = rules_admin_filter_info($vars, $all_actions); 287 $unsatisfied_actions = array_filter(array_diff_assoc($all_actions, $satisfied_actions), 'rules_admin_element_filter'); 288 $form['name'] = array( 289 '#type' => 'select', 290 '#title' => t('Select an action to add'), 291 '#options' => rules_admin_get_grouped_labels($satisfied_actions), 292 '#required' => TRUE, 293 ); 294 if (!empty($unsatisfied_actions)) { 295 // Hold all the actions that are disabled because argument(s) are missing. 296 $form['unsatisfied'] = array( 297 '#type' => 'fieldset', 298 '#title' => format_plural(count($unsatisfied_actions), '1 action is not configurable', '@count actions are not configurable'), 299 '#description' => t("The following actions aren't available in this context because they require arguments that don't exist in your rule. If you want to use any of these actions, you must first add some action that adds variables of this kind, or have an event that passes the required variables."), 300 '#collapsible' => TRUE, 301 '#collapsed' => TRUE, 302 ); 303 $form['unsatisfied']['items'] = array( 304 '#type' => 'item', 305 '#unsatisfied_grouped_options' => $unsatisfied_actions, 306 '#theme' => 'rules_admin_unsatisfied_elements', 307 ); 308 } 309 $form['submit'] = array( 310 '#type' => 'submit', 311 '#weight' => 10, 312 '#value' => t('Next'), 313 '#submit' => array('rules_admin_form_add_submit'), 314 ); 315 return $form; 316 } 317 318 /** 319 * Returns the form for the first condition add page 320 */ 321 function rules_admin_form_add_condition(&$form_state, &$element, $parent) { 322 323 if (!isset($parent['#type']) || isset($parent['#logical_op']) && $parent['#logical_op']) { 324 $vars = $form_state['proxy']->get_available_variables(0); 325 $all_conditions = rules_get_conditions(); 326 $satisfied_conditions = rules_admin_filter_info($vars, $all_conditions); 327 $unsatisfied_conditions = array_filter(array_diff_assoc($all_conditions, $satisfied_conditions), 'rules_admin_element_filter'); 328 $form['name'] = array( 329 '#type' => 'select', 330 '#title' => t('Select the condition to add'), 331 '#options' => rules_admin_get_grouped_labels($satisfied_conditions), 332 '#required' => TRUE, 333 ); 334 if (!empty($unsatisfied_conditions)) { 335 // Hold all the actions that are disabled because argument(s) are missing. 336 $form['unsatisfied'] = array( 337 '#type' => 'fieldset', 338 '#title' => format_plural(count($unsatisfied_conditions), '1 condition is not configurable', '@count conditions are not configurable'), 339 '#description' => t("The following conditions aren't available in this context because they require arguments that don't exist in your rule. If you want to use any of these conditions, you must first add some action that adds variables of this kind in a previous rule, or have an event that passes the required variables."), 340 '#collapsible' => TRUE, 341 '#collapsed' => TRUE, 342 ); 343 $form['unsatisfied']['items'] = array( 344 '#type' => 'item', 345 '#unsatisfied_grouped_options' => $unsatisfied_conditions, 346 '#theme' => 'rules_admin_unsatisfied_elements', 347 ); 348 } 349 $form['submit'] = array( 350 '#type' => 'submit', 351 '#weight' => 10, 352 '#value' => t('Next'), 353 '#submit' => array('rules_admin_form_add_submit'), 354 ); 355 return $form; 356 } 357 } 358 359 /** 360 * Indenting a condition 361 * Adds a logical operation and place the given condition element inside. We automatically 362 * determine which operation is to be added. 363 */ 364 function rules_admin_form_add_op(&$form_state, $element, $parent) { 365 $parent_ref = &$form_state['proxy']->get_element($form_state['parent_id']); 366 367 //determine the appropriate operation and apply it 368 $op = rules_admin_determine_operation($form_state['proxy'], $form_state['parent_id']); 369 if (isset($parent_ref['#weight'])) { 370 $weight = $parent_ref['#weight']; 371 unset($parent_ref['#weight']); 372 } 373 $parent_ref = rules_configure($op, $parent_ref); 374 375 if (isset($weight)) { 376 //apply the weight of the element to the op 377 $parent_ref['#weight'] = $weight; 378 } 379 380 //and save 381 $form_state['proxy']->save_changes(); 382 drupal_goto(RULES_ADMIN_RULE_PATH .'/'. $form_state['proxy']->get_rule_name()); 383 } 384 385 function rules_admin_form_add_submit($form, &$form_state) { 386 $form_state['element']['#name'] = $form_state['values']['name']; 387 $form_state['step']++; 388 rules_init_element_info($form_state['element']); 389 } 390 391 /** 392 * Use this function when there should be a further step. 393 * It puts all variables needed into the form storage 394 */ 395 function rules_admin_form_pack_storage($form, &$form_state) { 396 foreach (array('proxy', 'step', 'element', 'parent_id') as $key) { 397 if (isset($form_state[$key])) { 398 $form_state['storage'][$key] = &$form_state[$key]; 399 } 400 } 401 // Add a mechanism that includes arbitrary files needed by the form. 402 // This can be used by configuration forms that need to rely on other files. 403 $form['#after_build'][] = 'rules_after_build_include_files'; 404 405 // Register an after build callback that unpacks the storage. 406 // However let the rules_admin.rule_forms.inc file be included previously, so that 407 // #ahah callbacks from other modules keep working. 408 $form['#includes'][] = "./". drupal_get_path('module', 'rules_admin') ."/rules_admin.rule_forms.inc"; 409 $form['#after_build'][] = 'rules_admin_form_unpack_storage'; 410 return $form; 411 } 412 413 /** 414 * Puts the variables out of storage on their usual place. Invoked through 415 * #after_build, which is set by rules_admin_form_pack_storage(). 416 */ 417 function rules_admin_form_unpack_storage($form, &$form_state) { 418 if (!isset($form_state['unpacked'])) { 419 foreach (array('proxy', 'step', 'element', 'parent_id') as $key) { 420 if (isset($form_state['storage'][$key]) && !isset($form_state[$key])) { 421 $form_state[$key] = &$form_state['storage'][$key]; 422 } 423 } 424 $form_state['unpacked'] = TRUE; 425 } 426 427 return $form; 428 } 429 430 /** 431 * Returns the form for the edit operation 432 * This handles editing conditions and actions 433 * 434 * @param $id The id of the the element where the condition / action is to be added 435 */ 436 function rules_admin_form_edit(&$form_state, $proxy, $element) { 437 if (!isset($form_state['element'])) { 438 //initial step! 439 $form_state += array('element' => $element, 'step' => 1); 440 } 441 //just call the add form with the appropriate step. 442 $type = in_array($element['#type'], array('action', 'condition')) ? $element['#type'] : 'op'; 443 return rules_admin_form_add($form_state, $proxy, $type); 444 } 445 446 /** 447 * Returns the edit form for an action 448 */ 449 function rules_admin_form_edit_action(&$form_state, $element) { 450 $label = rules_get_element_label($element); 451 $form['label'] = array( 452 '#title' => t('Label'), 453 '#type' => 'textfield', 454 '#description' => t('Customize the label for this action.'), 455 '#default_value' => isset($form_state['values']['label']) ? $form_state['values']['label'] : $label, 456 '#required' => TRUE, 457 '#weight' => -5, 458 ); 459 if ($label) { 460 drupal_set_title(t('Editing action %label', array('%label' => $label))); 461 } 462 $form['weight'] = array( 463 '#title' => t('Weight'), 464 '#type' => 'weight', 465 '#description' => t('Adjust the weight to customize the ordering of actions.'), 466 '#default_value' => isset($element['#weight']) ? $element['#weight'] : 0, 467 '#weight' => 8, 468 ); 469 $form['submit'] = array( 470 '#type' => 'submit', 471 '#weight' => 10, 472 '#value' => t('Save'), 473 '#submit' => array('rules_admin_form_edit_action_submit', 'rules_admin_form_edit_save'), 474 ); 475 if (isset($element['#id'])) { 476 $form['delete'] = array( 477 '#type' => 'submit', 478 '#weight' => 11, 479 '#value' => t('Delete'), 480 '#submit' => array('rules_admin_form_edit_delete_submit'), 481 ); 482 } 483 rules_admin_element_help($form, $element); 484 $form['help']['#weight'] = -4; // Move upwards 485 rules_admin_default_argument_form($form, $form_state, $element); 486 rules_admin_new_variables_form($form, $form_state, $element); 487 rules_admin_element_alter_form($form, $form_state, $element); 488 return $form; 489 } 490 491 /* 492 * Apply the changes to the element 493 */ 494 function rules_admin_form_edit_action_submit($form, &$form_state) { 495 $element = &$form_state['element']; 496 $element['#weight'] = $form_state['values']['weight']; 497 rules_admin_default_argument_form_submit($form, $form_state, $element); 498 rules_admin_new_variables_form_submit($form, $form_state, $element); 499 rules_admin_save_element_label($form, $form_state, $element); 500 rules_admin_element_alter_form_submit($form, $form_state, $element); 501 drupal_set_message(t('The action %label has been saved.', array('%label' => rules_get_element_label($element)))); 502 } 503 504 /** 505 * Returns the edit form for a condition 506 */ 507 function rules_admin_form_edit_condition(&$form_state, $element) { 508 $label = rules_get_element_label($element); 509 $form['label'] = array( 510 '#title' => t('Label'), 511 '#type' => 'textfield', 512 '#description' => t('Customize the label for this condition.'), 513 '#default_value' => isset($form_state['values']['label']) ? $form_state['values']['label'] : $label, 514 '#required' => TRUE, 515 '#weight' => -5, 516 ); 517 if ($label) { 518 drupal_set_title(t('Editing condition %label', array('%label' => $label))); 519 } 520 $form['negate'] = array( 521 '#title' => t('Negate'), 522 '#type' => 'checkbox', 523 '#description' => t('If checked, the condition returns TRUE, if it evaluates to FALSE.'), 524 '#default_value' => isset($element['#negate']) ? $element['#negate'] : 0, 525 ); 526 $form['weight'] = array( 527 '#title' => t('Weight'), 528 '#type' => 'weight', 529 '#description' => t('Adjust the weight to customize the ordering of conditions.'), 530 '#default_value' => isset($element['#weight']) ? $element['#weight'] : 0, 531 '#weight' => 8, 532 ); 533 $form['submit'] = array( 534 '#type' => 'submit', 535 '#weight' => 10, 536 '#value' => t('Save'), 537 '#submit' => array('rules_admin_form_edit_condition_submit', 'rules_admin_form_edit_save'), 538 ); 539 if (isset($element['#id'])) { 540 $form['delete'] = array( 541 '#type' => 'submit', 542 '#weight' => 11, 543 '#value' => t('Delete'), 544 '#submit' => array('rules_admin_form_edit_delete_submit'), 545 ); 546 } 547 else { 548 // For conditions we set the id to 0, so new variables of this rules aren't shown 549 // in argument mapping forms. 550 $element['#id'] = 0; 551 } 552 rules_admin_element_help($form, $element); 553 rules_admin_default_argument_form($form, $form_state, $element); 554 rules_admin_element_alter_form($form, $form_state, $element); 555 return $form; 556 } 557 558 /** 559 * Apply the changes to the element 560 */ 561 function rules_admin_form_edit_condition_submit($form, &$form_state) { 562 $element = &$form_state['element']; 563 foreach (array('negate', 'weight') as $key) { 564 $element['#'. $key] = $form_state['values'][$key]; 565 } 566 rules_admin_default_argument_form_submit($form, $form_state, $element); 567 rules_admin_save_element_label($form, $form_state, $element); 568 rules_admin_element_alter_form_submit($form, $form_state, $element); 569 drupal_set_message(t('The condition %label has been saved.', array('%label' => rules_get_element_label($element)))); 570 } 571 572 /** 573 * Returns the edit form of a logical operation 574 */ 575 function rules_admin_form_edit_op(&$form_state, $element) { 576 drupal_set_title(t('Editing condition group %label', array('%label' => rules_get_element_label($element)))); 577 $form['negate'] = array( 578 '#title' => t('Negate'), 579 '#type' => 'checkbox', 580 '#description' => t('If checked, the operation will be negated. E.g. AND would be handled as NOT AND.'), 581 '#default_value' => isset($element['#negate']) ? $element['#negate'] : 0, 582 ); 583 $form['operation'] = array( 584 '#title' => t('Operation'), 585 '#type' => 'select', 586 '#description' => t('The logical operation of this condition group. E.g. if you select AND, this condition group will only evaluate to TRUE if all conditions of this group evaluate to TRUE.'), 587 '#default_value' => $element['#type'], 588 '#options' => rules_admin_elements_get_logical_ops(), 589 '#required' => TRUE, 590 ); 591 $form['weight'] = array( 592 '#title' => t('Weight'), 593 '#type' => 'weight', 594 '#description' => t('Adjust the weight to customize the ordering.'), 595 '#default_value' => isset($element['#weight']) ? $element['#weight'] : 0, 596 ); 597 $form['submit'] = array( 598 '#type' => 'submit', 599 '#weight' => 10, 600 '#value' => t('Save'), 601 '#submit' => array('rules_admin_form_edit_op_submit', 'rules_admin_form_edit_save'), 602 ); 603 if (isset($element['#id'])) { 604 $form['delete'] = array( 605 '#type' => 'submit', 606 '#weight' => 10, 607 '#value' => t('Delete'), 608 '#submit' => array('rules_admin_form_edit_delete_submit'), 609 ); 610 } 611 return $form; 612 } 613 614 /** 615 * Apply the changes to the element 616 */ 617 function rules_admin_form_edit_op_submit($form, &$form_state) { 618 $element = &$form_state['element']; 619 foreach (array('negate', 'weight') as $key) { 620 $element['#'. $key] = $form_state['values'][$key]; 621 } 622 $element['#type'] = $form_state['values']['operation']; 623 drupal_set_message(t('The condition group %label has been saved.', array('%label' => $element['#type']))); 624 } 625 626 /** 627 * Actually saves the element. Note that this handles also saving newly added elements. 628 */ 629 function rules_admin_form_edit_save($form, &$form_state) { 630 $element = &$form_state['element']; 631 //remove empty values 632 $element = array_filter($element); 633 634 if (isset($element['#id']) && $element['#id']) { 635 //save edited element 636 $element_ref = &$form_state['proxy']->get_element($element['#id']); 637 $element_ref = $element; 638 unset($element_ref['#id']); 639 } 640 else { 641 $parent_ref = &$form_state['proxy']->get_element($form_state['parent_id']); 642 //just add the element to the parent 643 unset($element['#id']); 644 $parent_ref = rules_configure($parent_ref, $element); 645 } 646 $form_state['proxy']->save_changes(); 647 $form_state['redirect'] = RULES_ADMIN_RULE_PATH .'/'. $form_state['proxy']->get_rule_name(); 648 unset($form_state['storage']); 649 } 650 651 /** 652 * Just redirect to the delete form 653 */ 654 function rules_admin_form_edit_delete_submit($form, &$form_state) { 655 $element = &$form_state['element']; 656 $base_path = RULES_ADMIN_RULE_PATH .'/'. $form_state['proxy']->get_rule_name(); 657 unset($_REQUEST['destination']); 658 $form_state['redirect'] = array( 659 'path' => $base_path .'/delete/'. $element['#id'], 660 'query' => 'destination='. $base_path, 661 ); 662 // We need to empty the storage or there will be no redirect. 663 $form_state['storage'] = NULL; 664 } 665 666 /** 667 * Allows the element to alter the default configuration form 668 */ 669 function rules_admin_element_alter_form(&$form, &$form_state, $element) { 670 rules_include('rules_forms'); 671 $element += array('#settings' => array()); 672 673 rules_element_invoke($element, 'form', array($element['#settings'], &$form, &$form_state), FALSE); 674 $form['submit']['#validate'][] = 'rules_admin_element_alter_form_validate'; 675 } 676 677 function rules_admin_element_alter_form_validate(&$form, &$form_state) { 678 rules_include('rules_forms'); 679 rules_element_invoke($form_state['element'], 'validate', array(&$form, &$form_state), FALSE); 680 } 681 682 function rules_admin_element_alter_form_submit(&$form, &$form_state, &$element) { 683 rules_include('rules_forms'); 684 rules_element_invoke($element, 'submit', array(&$element['#settings'], &$form, &$form_state), FALSE); 685 686 // After altering we can apply the input evaluators. 687 rules_prepare_input_evaluators($element, $form_state['proxy']->get_available_variables($form_state['element']['#id'])); 688 } 689 690 /** 691 * Returns form elements for new variables 692 */ 693 function rules_admin_new_variables_form(&$form, &$form_state, $element) { 694 $info = rules_get_element_info($element); 695 696 if (isset($info['new variables']) && count($info['new variables'])) { 697 $form['new'] = array('#tree' => TRUE); 698 foreach ($info['new variables'] as $name => $var) { 699 $form['new'][$name] = array( 700 '#type' => 'fieldset', 701 '#title' => t('Variable @label settings', array('@label' => $var['label'])), 702 '#collapsible' => TRUE, 703 ); 704 // Make sure the variable label is in lower case. 705 $var['label'] = drupal_strtolower(drupal_substr($var['label'], 0, 1)) . drupal_substr($var['label'], 1); 706 $form['new'][$name]['label'] = array( 707 '#type' => 'textfield', 708 '#title' => t('Label'), 709 '#default_value' => $var['label'], 710 '#required' => TRUE, 711 ); 712 $form['new'][$name]['name'] = array( 713 '#type' => 'textfield', 714 '#title' => t('Machine readable variable name'), 715 '#description' => t('Specify a unique name containing only alphanumeric characters, and underscores.'), 716 '#default_value' => $name, 717 '#required' => TRUE, 718 ); 719 // Preserve its old argument map value or initialize the map 720 $element['#settings'] += array('#argument map' => array()); 721 $default_name = array_search($name, $element['#settings']['#argument map']); 722 $default_name = $default_name === FALSE ? $name : $default_name; 723 $form['map'][$default_name] = array('#type' => 'value', '#value' => $name); 724 } 725 $form['submit']['#validate'][] = 'rules_admin_new_variables_form_validate'; 726 } 727 } 728 729 function rules_admin_new_variables_form_validate($form, &$form_state) { 730 $variables = $form_state['proxy']->get_defined_variables(); 731 foreach ($form_state['values']['new'] as $old_name => $values) { 732 // If the variable name changed or we add a new element we have to ensure 733 // that the variable name is not taken yet. 734 if (isset($variables[ $values['name'] ]) && ($values['name'] != $old_name || !isset($form_state['element']['#id']))) { 735 form_set_error(implode('][', array('new', $old_name, 'name')), t('A variable with this name does already exist. Please choose another name.')); 736 } 737 if (!preg_match('/^[0-9a-zA-Z_]*$/', $values['name'])) { 738 form_set_error(implode('][', array('new', $old_name, 'name')), t('The name contains not allowed characters.')); 739 } 740 } 741 } 742 743 function rules_admin_new_variables_form_submit(&$form, &$form_state, &$element) { 744 if (isset($form_state['values']['new'])) { 745 foreach ($form_state['values']['new'] as $old_name => $values) { 746 747 //handle the label 748 $info = &$element['#info']['new variables'][$old_name]; 749 $info = _rules_admin_get_label($form_state, $info, $element, $values['label'], FALSE) + $info; 750 751 if ($old_name != $values['name']) { 752 //add it to the argument map 753 $default_name = array_search($old_name, $element['#settings']['#argument map']); 754 $element['#settings']['#argument map'][$default_name] = $values['name']; 755 //and alter the info about the variable to reflect the name change 756 $element['#info']['new variables'][ $values['name'] ] = $element['#info']['new variables'][$old_name]; 757 unset($element['#info']['new variables'][$old_name]); 758 } 759 } 760 } 761 } 762 763 /** 764 * Returns the argument form for the given element 765 */ 766 function rules_admin_default_argument_form(&$form, &$form_state, $element) { 767 $form['input_help'] = rules_input_evaluators_help($element, $form_state['proxy']->get_available_variables($form_state['element']['#id'])); 768 $form['settings'] = array('#tree' => TRUE); 769 $form['map'] = array('#tree' => TRUE); 770 771 $function = $element['#name'] .'_form'; 772 $info = rules_retrieve_element_info($element); 773 774 if (isset($info['arguments']) && count($info['arguments'])) { 775 $variables = $form_state['proxy']->get_available_variables($element['#id']); 776 777 foreach ($info['arguments'] as $name => $arg_info) { 778 $arg = rules_get_data_object($arg_info); 779 if ($arg->uses_input_form()) { 780 $value = isset($element['#settings'][$name]) ? $element['#settings'][$name] : NULL; 781 $form['settings'][$name] = $arg->get_default_input_form($arg_info, $value, $form_state); 782 } 783 else { 784 $args = rules_admin_map_get_possible_arguments($arg_info, $variables); 785 $form['map'][$name] = array( 786 '#type' => 'select', 787 '#title' => $arg_info['label'], 788 '#options' => $args, 789 '#default_value' => rules_admin_element_map_variable_name($name, $element), 790 '#description' => isset($arg_info['description']) ? $arg_info['description'] : '', 791 ); 792 } 793 } 794 if (element_children($form['map'])) { 795 $form['map'] += array( 796 '#type' => 'fieldset', 797 '#title' => t('Arguments configuration'), 798 '#weight' => -2, 799 ); 800 } 801 } 802 } 803 804 function rules_admin_default_argument_form_submit($form, &$form_state, &$element) { 805 //save the argument map 806 if (isset($form_state['values']['map'])) { 807 $element['#settings']['#argument map'] = $form_state['values']['map']; 808 } 809 //add in values of not identifiable variables 810 if (isset($form_state['values']['settings'])) { 811 $element['#settings'] = $form_state['values']['settings'] + $element['#settings']; 812 } 813 } 814 815 /** 816 * Shows the delete form for elements (conditions, actions, ..) 817 */ 818 function rules_admin_form_delete(&$form_state, $proxy, $element) { 819 $form_state['proxy'] = &$proxy; 820 821 //get the item assocaited with $id 822 $form_state['id'] = $element['#id']; 823 _rules_element_defaults($element); 824 825 $form = array(); 826 $path = array(); 827 $path['path'] = isset($_GET['destination']) ? $_GET['destination'] : RULES_ADMIN_PATH; 828 829 if (isset($element['#logical_op']) && $element['#logical_op']) { 830 $form_state['is_op'] = TRUE; 831 $text = t('Are you sure you want to delete the logical operation %label?', array('%label' => rules_get_element_label($element))); 832 } 833 else { 834 $text = t('Are you sure you want to delete %label?', array('%label' => rules_get_element_label($element))); 835 } 836 return confirm_form($form, $text, $path, t('This action cannot be undone.'), t('Delete'), t('Cancel')); 837 } 838 839 function rules_admin_form_delete_submit($form_id, $form_state) { 840 $rule = $form_state['proxy']->get_rule(); 841 //get a reference on the element 842 $element = &$form_state['proxy']->get_element(intval($form_state['id'])); 843 844 if (isset($form_state['is_op']) && $form_state['is_op']) { 845 drupal_set_message(t("The logical operation %label has been deleted.", array('%label' => rules_get_element_label($element)))); 846 //just unset the type, so that containing conditions are not deleted 847 unset($element['#type']); 848 } 849 else { 850 drupal_set_message(t("%label has been deleted.", array('%label' => rules_get_element_label($element)))); 851 $element = NULL; 852 //remove the elements key by cleaning the rule 853 } 854 $form_state['proxy']->clean_rule(); 855 $form_state['proxy']->save_changes(); 856 $form_state['redirect'] = RULES_ADMIN_PATH; 857 } 858 859 /** 860 * Clones a rule 861 */ 862 function rules_admin_form_clone(&$form_state, $proxy) { 863 drupal_add_js(drupal_get_path('module', 'rules_admin') . '/rules_admin.js'); 864 $form_state['proxy'] = &$proxy; 865 $rule = $proxy->get_rule(); 866 _rules_element_defaults($rule); 867 $rule['#name'] = drupal_substr($proxy->get_rule_name(), drupal_strlen('rules_')) . '_cloned'; 868 if (!$form_state['post']) { 869 drupal_set_message(t('Alter the settings for the cloned rule.')); 870 } 871 872 $form_state['set'] = strpos($rule['#set'], 'event_') !== 0; 873 874 $form = rules_admin_form_rule_settings($rule, $form_state['set']); 875 $form['#submit'] = array('rules_admin_form_add_rule_submit'); 876 return $form; 877 } 878 879 /** 880 * Determines which operation should be added 881 * If the parent operation is an AND, we add an OR, and vice versa. 882 */ 883 function rules_admin_determine_operation(&$proxy, $id) { 884 $parent = $proxy->get_element($proxy->get_element_parent_id($id)) + array('#type' => ''); 885 switch ($parent['#type']) { 886 default: 887 case 'rule': 888 case 'AND': 889 return 'OR'; 890 891 case 'OR': 892 return 'AND'; 893 } 894 } 895 896 /** 897 * Returns a list of available logical operations suitable for use with #options 898 */ 899 function rules_admin_elements_get_logical_ops() { 900 $elements = rules_gather_data('elements'); 901 $labels = array_map('rules_get_element_label', array_filter($elements, '_rules_admin_element_is_logical_op')); 902 asort($labels); 903 return $labels; 904 } 905 906 function _rules_admin_element_is_logical_op($element) { 907 return isset($element['#logical_op']) && $element['#logical_op']; 908 } 909 910 /** 911 * Themes the a list of actions or conditions, that are not satisfiable. 912 */ 913 function theme_rules_admin_unsatisfied_elements($element) { 914 $output = ''; 915 $output .= '<div class="rules-unsatisfied-arguments">'; 916 foreach (rules_admin_get_grouped_labels($element['#unsatisfied_grouped_options']) as $grouped_rules) { 917 $output .= theme('rules_admin_unsatisfied_elements_group', $grouped_rules, $element['#unsatisfied_grouped_options']); 918 } 919 $output .= '</div>'; 920 return $output; 921 } 922 923 /** 924 * Themes not satisifable elements of a group. 925 */ 926 function theme_rules_admin_unsatisfied_elements_group($grouped_rules, $elements) { 927 $output = '<dl>'; 928 foreach ($grouped_rules as $name => $value) { 929 $fieldset = array( 930 '#type' => 'fieldset', 931 '#title' => t('@group module', array('@group' => $elements[$name]['module'])), 932 '#collapsible' => FALSE, 933 ); 934 $output .= '<dt>'. check_plain($elements[$name]['label']) .'</dt>'; 935 $output .= '<dd><em>'. format_plural(count($elements[$name]['unsatisfied arguments']), 'Unavailable argument: @arguments', 'Unavailable arguments: @arguments', array('@arguments' => implode(', ', $elements[$name]['unsatisfied arguments']))) .'</em></dd>'; 936 } 937 $output .= '</dl>'; 938 $fieldset['items'] = array( 939 '#type' => 'markup', 940 '#value' => $output, 941 ); 942 return drupal_render($fieldset); 943 } 944 945 /** 946 * Menu callback for the autocompletion of categories. 947 */ 948 function rules_admin_categories_autocomplete($string) { 949 // The user enters a comma-separated list of tags. We only autocomplete the last tag. 950 $array = array_filter(drupal_explode_tags($string)); 951 // Fetch last tag 952 $last_string = drupal_strtolower(trim(array_pop($array))); 953 $prefix = count($array) ? implode(', ', $array) .', ' : ''; 954 $tags = rules_admin_get_categories('rules') + rules_admin_get_categories('rule_sets'); 955 956 $matches = array(); 957 foreach ($tags as $tag) { 958 if ($last_string && strpos(drupal_strtolower($tag), $last_string) !== FALSE) { 959 $matches[$prefix . $tag] = check_plain($tag); 960 } 961 } 962 drupal_json($matches); 963 } 964 965 /** 966 * Saves the element label. 967 */ 968 function rules_admin_save_element_label($form, &$form_state, &$element) { 969 $info = _rules_admin_get_label($form_state, rules_get_element_info($element), $element, $form_state['values']['label'], TRUE); 970 $element['#info'] = $info + $element['#info']; 971 } 972 973 /** 974 * Defines the rules settings form 975 */ 976 function rules_admin_settings(&$form_state) { 977 $form['rules_debug'] = array( 978 '#type' => 'checkbox', 979 '#title' => t('Debug rule evaluation'), 980 '#default_value' => variable_get('rules_debug', FALSE), 981 '#description' => t('When activated, debugging information is shown when rules are evaluated.'), 982 ); 983 $form['rules_show_fixed'] = array( 984 '#type' => 'checkbox', 985 '#title' => t('Show fixed rules and rule sets'), 986 '#default_value' => variable_get('rules_show_fixed', FALSE), 987 '#description' => t('When activated, fixed items provided by modules are shown in the admin center too.'), 988 ); 989 $form['rules_hide_token_message'] = array( 990 '#type' => 'checkbox', 991 '#title' => t('Ignore missing token module'), 992 '#default_value' => variable_get('rules_hide_token_message', FALSE), 993 '#description' => t('Rules can use the token module to provide token replacements; if this module is not present rules will complain, unless this setting is checked.'), 994 ); 995 return system_settings_form($form); 996 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Thu Mar 24 11:18:33 2011 | Cross-referenced by PHPXref 0.7 |