| [ Index ] |
PHP Cross Reference of Drupal 6 (yi-drupal) |
[Summary view] [Print] [Text view]
1 <?php 2 // $Id: context-admin.inc,v 1.9.2.3 2010/07/13 23:55:22 merlinofchaos Exp $ 3 4 /** 5 * @file includes/common-context.inc 6 * Provide API for adding contexts for modules that embed displays. 7 * 8 * Note that most of this code was directly copied from Panels 2, and as such 9 * a lot of this code is crusty. It could probably stand to be rewritten, 10 * and brought up to date, or at least better commented. 11 */ 12 13 /** 14 * Provide a list of the ways contexts can be embedded. 15 * 16 * This provides a full list of context types that the tool understands 17 * and can let modules utilize. 18 */ 19 function ctools_context_info($type = NULL) { 20 static $info = NULL; 21 22 // static doesn't work with functions like t(). 23 if (empty($info)) { 24 $info = array( 25 'argument' => array( 26 'title' => t('Arguments'), 27 'singular title' => t('argument'), 28 'description' => '', // t("Arguments are parsed from the URL and translated into contexts that may be added to the display via the 'content' tab. These arguments are parsed in the order received, and you may use % in your URL to hold the place of an object; the rest of the arguments will come after the URL. For example, if the URL is node/%/panel and your user visits node/1/panel/foo, the first argument will be 1, and the second argument will be foo."), 29 'add button' => t('Add argument'), 30 'context function' => 'ctools_get_argument', 31 'form id' => 'ctools_edit_argument_form', 32 'key' => 'arguments', // the key that data will be stored on an object, eg $panel_page 33 'sortable' => TRUE, 34 'settings' => 'argument_settings', 35 ), 36 'relationship' => array( 37 'title' => t('Relationships'), 38 'singular title' => t('relationship'), 39 'description' => '', // t('Relationships are contexts that are created from already existing contexts; the add relationship button will only appear once there is another context available. Relationships can load objects based upon how they are related to each other; for example, the author of a node, or a taxonomy term attached to a node, or the vocabulary of a taxonomy term.'), 40 'add button' => t('Add relationship'), 41 'context function' => 'ctools_get_relationship', 42 'form id' => 'ctools_edit_relationship_form', 43 'key' => 'relationships', 44 'sortable' => FALSE, 45 'settings' => 'relationship_settings', 46 ), 47 'context' => array( 48 'title' => t('Contexts'), 49 'singular title' => t('context'), 50 'description' => '', // t('Contexts are embedded directly into the panel; you generally must select an object in the panel. For example, you could select node 5, or the term "animals" or the user "administrator"'), 51 'add button' => t('Add context'), 52 'context function' => 'ctools_get_context', 53 'form id' => 'ctools_edit_context_form', 54 'key' => 'contexts', 55 'sortable' => FALSE, 56 'settings' => 'context_settings', 57 ), 58 'requiredcontext' => array( 59 'title' => t('Required contexts'), 60 'singular title' => t('required context'), 61 'description' => '', // t('Required contexts are passed in from some external source, such as a containing panel. If a mini panel has required contexts, it can only appear when that context is available, and therefore will not show up as a standard Drupal block.'), 62 'add button' => t('Add required context'), 63 'context function' => 'ctools_get_context', 64 'form id' => 'ctools_edit_requiredcontext_form', 65 'key' => 'requiredcontexts', 66 'sortable' => FALSE, 67 ), 68 ); 69 } 70 71 if ($type === NULL) { 72 return $info; 73 } 74 75 return $info[$type]; 76 } 77 78 /** 79 * Get the cache for the context object. 80 * 81 * This can pass through to a module provided cache if it exists, or 82 * the default cache will be used. 83 */ 84 function ctools_context_cache_get($fragment, $key) { 85 // Separate the fragment into 'module' and 'argument' 86 if (strpos($fragment, '-') === FALSE) { 87 $module = $fragment; 88 $argument = NULL; 89 } 90 else { 91 list($module, $argument) = explode('-', $fragment, 2); 92 } 93 94 $function = $module . '_context_cache_get'; 95 if (function_exists($function)) { 96 return $function($argument, $key); 97 } 98 else { 99 return ctools_object_cache_get("context_object:$module", $key); 100 } 101 } 102 103 /** 104 * Get the cache for the context object. 105 * 106 * This can pass through to a module provided cache if it exists, or 107 * the default cache will be used. 108 */ 109 function ctools_context_cache_set($fragment, $key, $object) { 110 // Separate the fragment into 'module' and 'argument' 111 if (strpos($fragment, '-') === FALSE) { 112 $module = $fragment; 113 $argument = NULL; 114 } 115 else { 116 list($module, $argument) = explode('-', $fragment, 2); 117 } 118 119 $function = $module . '_context_cache_set'; 120 if (function_exists($function)) { 121 return $function($argument, $key, $object); 122 } 123 else { 124 return ctools_object_cache_set("context_object:$module", $key, $object); 125 } 126 } 127 128 /** 129 * Get the data belonging to a particular context. 130 */ 131 function ctools_context_data($type, $name) { 132 $info = ctools_context_info($type); 133 if (function_exists($info['context function'])) { 134 return $info['context function']($name); 135 } 136 } 137 138 /** 139 * Add the argument table plus gadget plus javascript to the form. 140 */ 141 function ctools_context_add_argument_form($module, &$form, &$form_state, &$form_location, $object, $name = NULL) { 142 if (empty($name)) { 143 $name = $object->name; 144 } 145 146 $form_location = array( 147 '#prefix' => '<div id="ctools-arguments-table">', 148 '#suffix' => '</div>', 149 '#theme' => 'ctools_context_item_form', 150 '#object_name' => $name, 151 '#ctools_context_type' => 'argument', 152 '#ctools_context_module' => $module, 153 ); 154 155 $args = ctools_get_arguments(); 156 $choices = array(); 157 foreach ($args as $name => $arg) { 158 $choices[$name] = $arg['title']; 159 } 160 161 asort($choices); 162 163 if (!empty($choices) || !empty($object->arguments)) { 164 ctools_context_add_item_table('argument', $form_location, $choices, $object->arguments); 165 } 166 } 167 168 function ctools_context_add_context_form($module, &$form, &$form_state, &$form_location, $object, $name = NULL) { 169 if (empty($name)) { 170 $name = $object->name; 171 } 172 173 $form_location = array( 174 '#prefix' => '<div id="ctools-contexts-table">', 175 '#suffix' => '</div>', 176 '#theme' => 'ctools_context_item_form', 177 '#object_name' => $name, 178 '#ctools_context_type' => 'context', 179 '#ctools_context_module' => $module, 180 ); 181 182 // Store the order the choices are in so javascript can manipulate it. 183 $form_location['markup'] = array( 184 '#value' => ' ', 185 ); 186 187 $choices = array(); 188 foreach (ctools_get_contexts() as $name => $arg) { 189 if (empty($arg['no ui'])) { 190 $choices[$name] = $arg['title']; 191 } 192 } 193 194 asort($choices); 195 196 if (!empty($choices) || !empty($object->contexts)) { 197 ctools_context_add_item_table('context', $form_location, $choices, $object->contexts); 198 } 199 } 200 201 function ctools_context_add_required_context_form($module, &$form, &$form_state, &$form_location, $object, $name = NULL) { 202 if (empty($name)) { 203 $name = $object->name; 204 } 205 206 $form_location = array( 207 '#prefix' => '<div id="ctools-requiredcontexts-table">', 208 '#suffix' => '</div>', 209 '#theme' => 'ctools_context_item_form', 210 '#object_name' => $name, 211 '#ctools_context_type' => 'requiredcontext', 212 '#ctools_context_module' => $module, 213 ); 214 215 // Store the order the choices are in so javascript can manipulate it. 216 $form_location['markup'] = array( 217 '#value' => ' ', 218 ); 219 220 $choices = array(); 221 foreach (ctools_get_contexts() as $name => $arg) { 222 $choices[$name] = $arg['title']; 223 } 224 225 asort($choices); 226 227 if (!empty($choices) || !empty($object->contexts)) { 228 ctools_context_add_item_table('requiredcontext', $form_location, $choices, $object->requiredcontexts); 229 } 230 } 231 232 function ctools_context_add_relationship_form($module, &$form, &$form_state, &$form_location, $object, $name = NULL) { 233 if (empty($name)) { 234 $name = $object->name; 235 } 236 237 $form_location = array( 238 '#prefix' => '<div id="ctools-relationships-table">', 239 '#suffix' => '</div>', 240 '#theme' => 'ctools_context_item_form', 241 '#object_name' => $name, 242 '#ctools_context_type' => 'relationship', 243 '#ctools_context_module' => $module, 244 ); 245 246 // Store the order the choices are in so javascript can manipulate it. 247 $form_location['markup'] = array( 248 '#value' => ' ', 249 ); 250 251 $base_contexts = isset($object->base_contexts) ? $object->base_contexts : array(); 252 $available_relationships = ctools_context_get_relevant_relationships(ctools_context_load_contexts($object, TRUE, $base_contexts)); 253 254 ctools_context_add_item_table('relationship', $form_location, $available_relationships, $object->relationships); 255 } 256 257 /** 258 * Include all context administrative include files, css, javascript. 259 */ 260 function ctools_context_admin_includes() { 261 ctools_include('context'); 262 ctools_include('modal'); 263 ctools_include('ajax'); 264 ctools_include('object-cache'); 265 ctools_modal_add_js(); 266 ctools_modal_add_plugin_js(ctools_get_contexts()); 267 ctools_modal_add_plugin_js(ctools_get_relationships()); 268 } 269 270 /** 271 * Add the context table to the page. 272 */ 273 function ctools_context_add_item_table($type, &$form, $available_contexts, $items) { 274 $form[$type] = array( 275 '#tree' => TRUE, 276 ); 277 278 $module = $form['#ctools_context_module']; 279 $name = $form['#object_name']; 280 281 if (isset($items) && is_array($items)) { 282 foreach ($items as $position => $context) { 283 ctools_context_add_item_to_form($module, $type, $name, $form[$type][$position], $position, $context); 284 } 285 } 286 287 $type_info = ctools_context_info($type); 288 $form['description'] = array( 289 '#prefix' => '<div class="description">', 290 '#suffix' => '</div>', 291 '#value' => $type_info['description'], 292 ); 293 294 ctools_context_add_item_table_buttons($type, $module, $form, $available_contexts); 295 } 296 297 function ctools_context_add_item_table_buttons($type, $module, &$form, $available_contexts) { 298 $form['buttons'] = array( 299 '#tree' => TRUE, 300 ); 301 302 if (!empty($available_contexts)) { 303 $type_info = ctools_context_info($type); 304 305 $module = $form['#ctools_context_module']; 306 $name = $form['#object_name']; 307 308 // The URL for this ajax button 309 $form['buttons'][$type]['add-url'] = array( 310 '#attributes' => array('class' => "ctools-$type-add-url"), 311 '#type' => 'hidden', 312 '#value' => url("ctools/context/ajax/add/$module/$type/$name", array('absolute' => TRUE)), 313 ); 314 315 // This also will be in the URL. 316 $form['buttons'][$type]['item'] = array( 317 '#attributes' => array('class' => "ctools-$type-add-url"), 318 '#type' => 'select', 319 '#options' => $available_contexts, 320 ); 321 322 $form['buttons'][$type]['add'] = array( 323 '#type' => 'submit', 324 '#attributes' => array('class' => 'ctools-use-modal'), 325 '#id' => "ctools-$type-add", 326 '#value' => $type_info['add button'], 327 ); 328 } 329 } 330 331 /** 332 * Add a row to the form. Used both in the main form and by 333 * the ajax to add an item. 334 */ 335 function ctools_context_add_item_to_form($module, $type, $name, &$form, $position, $item) { 336 // This is the single function way to load any plugin by variable type. 337 $info = ctools_context_data($type, $item['name']); 338 $form['title'] = array( 339 '#value' => check_plain($item['identifier']), 340 ); 341 342 // Relationships not sortable. 343 $type_info = ctools_context_info($type); 344 345 if (!empty($type_info['sortable'])) { 346 $form['position'] = array( 347 '#type' => 'weight', 348 '#default_value' => $position, 349 '#attributes' => array('class' => 'drag-position'), 350 ); 351 } 352 353 $form['remove'] = array( 354 '#value' => ctools_ajax_image_button(ctools_image_path('icon-delete.png'), "ctools/context/ajax/delete/$module/$type/$name/$position", t('Remove this item.')), 355 ); 356 357 $form['settings'] = array( 358 '#value' => ctools_modal_image_button(ctools_image_path('icon-configure.png'), "ctools/context/ajax/configure/$module/$type/$name/$position", t('Configure settings for this item.')), 359 ); 360 } 361 362 363 // --------------------------------------------------------------------------- 364 // AJAX forms and stuff. 365 366 /** 367 * Ajax entry point to add an context 368 */ 369 function ctools_context_ajax_item_add($module = NULL, $type = NULL, $object_name = NULL, $name = NULL) { 370 ctools_include('ajax'); 371 ctools_include('modal'); 372 ctools_include('context'); 373 ctools_include('object-cache'); 374 375 if (!$name) { 376 return ctools_ajax_render_error(); 377 } 378 379 // Load stored object from cache. 380 if (!($object = ctools_context_cache_get($module, $object_name))) { 381 ctools_ajax_render_error(t('Invalid object name.')); 382 } 383 384 // Get info about what we're adding. 385 $info = ctools_context_data($type, $name); 386 if (empty($info)) { 387 return ctools_ajax_render_error(); 388 } 389 $type_info = ctools_context_info($type); 390 391 // Create a reference to the place our context lives. Since this is fairly 392 // generic, this is the easiest way to get right to the place of the 393 // object without knowing precisely what data we're poking at. 394 $ref = &$object->{$type_info['key']}; 395 396 // Give this item an id, which is really just the nth version 397 // of this particular context. 398 $id = ctools_context_next_id($ref, $name); 399 400 // Figure out the position for our new context. 401 $position = empty($ref) ? 0 : max(array_keys($ref)) + 1; 402 403 // Create the basis for our new context. 404 $ref[$position] = array( 405 'identifier' => $info['title'] . ($id > 1 ? ' ' . $id : ''), 406 'keyword' => ctools_get_keyword($object, $info['keyword']), 407 'id' => $id, 408 'name' => $name, 409 ); 410 411 if (isset($type_info['settings'])) { 412 $ref[$position][$type_info['settings']] = isset($info['defaults']) ? $info['defaults'] : array(); 413 } 414 415 $base_contexts = isset($object->base_contexts) ? $object->base_contexts : array(); 416 $contexts = ctools_context_load_contexts($object, TRUE, $base_contexts); 417 418 $form_state = array( 419 'object' => &$object, 420 'module' => $module, 421 'type' => $type, 422 'name' => $name, 423 'ajax' => TRUE, 424 'info' => $info, 425 'position' => $position, 426 'contexts' => $contexts, 427 'ref' => &$ref, 428 'title' => t('Add @type "@context"', array('@type' => $type_info['singular title'], '@context' => $info['title'])), 429 ); 430 431 $output = ctools_modal_form_wrapper($type_info['form id'], $form_state); 432 433 if (empty($output)) { 434 // successful submit 435 ctools_context_cache_set($module, $object_name, $object); 436 437 $arg_form_state = array(); 438 439 $arg_form = array( 440 '#post' => array(), 441 '#programmed' => FALSE, 442 '#tree' => FALSE, 443 ); 444 445 // Build a chunk of the form to merge into the displayed form 446 $arg_form[$type] = array( 447 '#tree' => TRUE, 448 ); 449 $arg_form[$type][$position] = array( 450 '#tree' => TRUE, 451 ); 452 453 ctools_context_add_item_to_form($module, $type, $object_name, $arg_form[$type][$position], $position, $ref[$position]); 454 $arg_form = form_builder($type_info['form id'], $arg_form, $arg_form_state); 455 456 // Build the relationships table so we can ajax it in. 457 // This is an additional thing that goes in here. 458 $rel_form = array( 459 '#theme' => 'ctools_context_item_form', 460 '#object_name' => $object_name, 461 '#ctools_context_type' => 'relationship', 462 '#ctools_context_module' => $module, 463 '#only_buttons' => TRUE, 464 '#post' => array(), 465 '#programmed' => FALSE, 466 '#tree' => FALSE, 467 ); 468 469 $rel_form['relationship'] = array( 470 '#tree' => TRUE, 471 ); 472 473 // Allow an object to set some 'base' contexts that come from elsewhere. 474 $rel_contexts = isset($object->base_contexts) ? $object->base_contexts : array(); 475 $all_contexts = ctools_context_load_contexts($object, TRUE, $rel_contexts); 476 $available_relationships = ctools_context_get_relevant_relationships($all_contexts); 477 478 $output = array(); 479 if (!empty($available_relationships)) { 480 ctools_context_add_item_table_buttons('relationship', $module, $rel_form, $available_relationships); 481 $rel_form = form_builder('dummy_form_id', $rel_form, $arg_form_state); 482 $output[] = ctools_ajax_command_replace('div#ctools-relationships-table div.buttons', drupal_render($rel_form)); 483 } 484 485 $text = theme('ctools_context_item_row', $type, $arg_form[$type][$position], $position, $position); 486 $output[] = ctools_ajax_command_append('#' . $type . '-table tbody', $text); 487 $output[] = ctools_ajax_command_changed('#' . $type . '-row-' . $position, '.title'); 488 $output[] = ctools_modal_command_dismiss(); 489 } 490 491 ctools_ajax_render($output); 492 } 493 494 /** 495 * Ajax entry point to edit an item 496 */ 497 function ctools_context_ajax_item_edit($module = NULL, $type = NULL, $object_name = NULL, $position = NULL) { 498 ctools_include('ajax'); 499 ctools_include('modal'); 500 ctools_include('context'); 501 ctools_include('object-cache'); 502 503 if (!isset($position)) { 504 return ctools_ajax_render_error(); 505 } 506 507 // Load stored object from cache. 508 if (!($object = ctools_context_cache_get($module, $object_name))) { 509 ctools_ajax_render_error(t('Invalid object name.')); 510 } 511 512 $type_info = ctools_context_info($type); 513 514 // Create a reference to the place our context lives. Since this is fairly 515 // generic, this is the easiest way to get right to the place of the 516 // object without knowing precisely what data we're poking at. 517 $ref = &$object->{$type_info['key']}; 518 519 $name = $ref[$position]['name']; 520 if (empty($name)) { 521 ctools_ajax_render_error(); 522 } 523 524 // load the context 525 $info = ctools_context_data($type, $name); 526 if (empty($info)) { 527 ctools_ajax_render_error(t('Invalid context type')); 528 } 529 530 $base_contexts = isset($object->base_contexts) ? $object->base_contexts : array(); 531 $contexts = ctools_context_load_contexts($object, TRUE, $base_contexts); 532 533 // Remove this context, because we can't really allow circular contexts. 534 unset($contexts[ctools_context_id($ref[$position])]); 535 536 $form_state = array( 537 'object' => &$object, 538 'module' => $module, 539 'type' => $type, 540 'name' => $name, 541 'ajax' => TRUE, 542 'info' => $info, 543 'position' => $position, 544 'contexts' => $contexts, 545 'ref' => &$ref, 546 'title' => t('Edit @type "@context"', array('@type' => $type_info['singular title'], '@context' => $info['title'])), 547 ); 548 549 $output = ctools_modal_form_wrapper($type_info['form id'], $form_state); 550 551 if (empty($output)) { 552 // successful submit 553 ctools_context_cache_set($module, $object_name, $object); 554 555 $output = array(); 556 $output[] = ctools_modal_command_dismiss(); 557 558 $arg_form = array( 559 '#post' => array(), 560 '#programmed' => FALSE, 561 '#tree' => FALSE, 562 ); 563 564 // Build a chunk of the form to merge into the displayed form 565 $arg_form[$type] = array( 566 '#tree' => TRUE, 567 ); 568 $arg_form[$type][$position] = array( 569 '#tree' => TRUE, 570 ); 571 572 ctools_context_add_item_to_form($module, $type, $object_name, $arg_form[$type][$position], $position, $ref[$position]); 573 $arg_form = form_builder($type_info['form id'], $arg_form, $arg_form_state); 574 575 $output[] = ctools_ajax_command_replace('#' . $type . '-row-' . $position, theme('ctools_context_item_row', $type, $arg_form[$type][$position], $position, $position)); 576 $output[] = ctools_ajax_command_changed('#' . $type . '-row-' . $position, '.title'); 577 } 578 ctools_ajax_render($output); 579 } 580 581 /** 582 * Form (for ajax use) to add a context 583 */ 584 function ctools_edit_context_form(&$form_state) { 585 $object = $form_state['object']; 586 $context = $form_state['info']; 587 $position = $form_state['position']; 588 $contexts = $form_state['contexts']; 589 590 $ctext = $object->contexts[$position]; 591 592 $form['description'] = array( 593 '#prefix' => '<div class="description">', 594 '#suffix' => '</div>', 595 '#value' => check_plain($context['description']), 596 ); 597 598 // Basic context values 599 $form['context']['#tree'] = TRUE; 600 601 $form['context']['name'] = array( 602 '#type' => 'hidden', 603 '#value' => $context['name'], 604 ); 605 606 $form['context']['id'] = array( 607 '#type' => 'hidden', 608 '#value' => $ctext['id'], 609 ); 610 611 $form['context']['identifier'] = array( 612 '#type' => 'textfield', 613 '#title' => t('Identifier'), 614 '#description' => t('Enter a name to identify this !type on administrative screens.', array('!type' => t('context'))), 615 '#default_value' => $ctext['identifier'], 616 ); 617 618 $form['context']['keyword'] = array( 619 '#type' => 'textfield', 620 '#title' => t('Keyword'), 621 '#description' => t('Enter a keyword to use for substitution in titles.'), 622 '#default_value' => $ctext['keyword'], 623 ); 624 625 // Settings particular to this context 626 $context_settings = array(); 627 if (isset($ctext['context_settings'])) { 628 $context_settings = $ctext['context_settings']; 629 } 630 631 if (isset($context['settings form']) && function_exists($context['settings form'])) { 632 $form['context']['context_settings'] = $context['settings form']($context_settings); 633 $form['context']['context_settings']['#tree'] = TRUE; 634 } 635 636 $form['next'] = array( 637 '#type' => 'submit', 638 '#value' => t('Save'), 639 ); 640 return $form; 641 } 642 643 /** 644 * validate a context edited/added via ajax 645 */ 646 function ctools_edit_context_form_validate($form, &$form_state) { 647 $context = $form_state['info']; 648 649 if (isset($context['settings form validate']) && function_exists($context['settings form validate'])) { 650 $context['settings form validate']($form['context']['context_settings'], $form_state['values']['context']['context_settings'], $form_state); 651 } 652 } 653 654 /** 655 * Updates an context edited/added via ajax 656 */ 657 function ctools_edit_context_form_submit($form, &$form_state) { 658 $info = $form_state['info']; 659 660 if (isset($info['settings form submit']) && function_exists($info['settings form submit'])) { 661 $info['settings form submit']($form, $form_state['values']['context']['context_settings'], $form_state); 662 } 663 664 $context = $form_state['values']['context']; 665 $form_state['ref'][$form_state['position']] = $context; 666 } 667 668 /** 669 * Form (for ajax use) to add a context 670 */ 671 function ctools_edit_requiredcontext_form(&$form_state) { 672 $object = $form_state['object']; 673 $context = $form_state['info']; 674 $position = $form_state['position']; 675 $contexts = $form_state['contexts']; 676 677 $ctext = $object->requiredcontexts[$position]; 678 $form['start_form'] = array('#value' => '<div class="modal-form clear-block">'); 679 680 $form['description'] = array( 681 '#prefix' => '<div class="description">', 682 '#suffix' => '</div>', 683 '#value' => check_plain($context['description']), 684 ); 685 686 // Basic context values 687 $form['requiredcontext']['#tree'] = TRUE; 688 689 $form['requiredcontext']['name'] = array( 690 '#type' => 'hidden', 691 '#value' => $context['name'], 692 ); 693 694 $form['requiredcontext']['id'] = array( 695 '#type' => 'hidden', 696 '#value' => $ctext['id'], 697 ); 698 699 $form['requiredcontext']['identifier'] = array( 700 '#type' => 'textfield', 701 '#title' => t('Identifier'), 702 '#description' => t('Enter a name to identify this !type on administrative screens.', array('!type' => t('required context'))), 703 '#default_value' => $ctext['identifier'], 704 ); 705 706 $form['requiredcontext']['keyword'] = array( 707 '#type' => 'textfield', 708 '#title' => t('Keyword'), 709 '#description' => t('Enter a keyword to use for substitution in titles.'), 710 '#default_value' => $ctext['keyword'], 711 ); 712 713 $form['end_form'] = array('#value' => '</div>'); 714 715 $form['next'] = array( 716 '#type' => 'submit', 717 '#value' => t('Save'), 718 ); 719 return $form; 720 } 721 722 /** 723 * Updates a required context edited/added via ajax 724 */ 725 function ctools_edit_requiredcontext_form_submit($form, &$form_state) { 726 $form_state['ref'][$form_state['position']] = $form_state['values']['requiredcontext']; 727 } 728 729 /** 730 * Form (for ajax use) to add a relationship 731 */ 732 function ctools_edit_relationship_form(&$form_state) { 733 $object = $form_state['object']; 734 $relationship = $form_state['info']; 735 $position = $form_state['position']; 736 $contexts = $form_state['contexts']; 737 738 $rel = $object->relationships[$position]; 739 740 $form['description'] = array( 741 '#prefix' => '<div class="description">', 742 '#suffix' => '</div>', 743 '#value' => check_plain($relationship['description']), 744 ); 745 746 // Basic relationship values 747 $form['relationship']['#tree'] = TRUE; 748 749 $form['relationship']['context'] = ctools_context_selector($contexts, $relationship['required context'], isset($rel['context']) ? $rel['context'] : ''); 750 751 $form['relationship']['name'] = array( 752 '#type' => 'hidden', 753 '#value' => $relationship['name'], 754 ); 755 756 $form['relationship']['id'] = array( 757 '#type' => 'hidden', 758 '#value' => $rel['id'], 759 ); 760 761 $form['relationship']['identifier'] = array( 762 '#type' => 'textfield', 763 '#title' => t('Identifier'), 764 '#description' => t('Enter a name to identify this !type on administrative screens.', array('!type' => t('relationship'))), 765 '#default_value' => $rel['identifier'], 766 ); 767 768 $form['relationship']['keyword'] = array( 769 '#type' => 'textfield', 770 '#title' => t('Keyword'), 771 '#description' => t('Enter a keyword to use for substitution in titles.'), 772 '#default_value' => $rel['keyword'], 773 ); 774 775 // Settings particular to this relationship 776 $relationship_settings = array(); 777 if (isset($rel['relationship_settings'])) { 778 $relationship_settings = $rel['relationship_settings']; 779 } 780 781 if (isset($relationship['settings form']) && function_exists($relationship['settings form'])) { 782 $form['relationship']['relationship_settings'] = $relationship['settings form']($relationship_settings); 783 $form['relationship']['relationship_settings']['#tree'] = TRUE; 784 } 785 786 $form['next'] = array( 787 '#type' => 'submit', 788 '#value' => t('Save'), 789 ); 790 return $form; 791 } 792 793 /** 794 * validate an relationship edited/added via ajax 795 */ 796 function ctools_edit_relationship_form_validate($form, &$form_state) { 797 $relationship = $form_state['info']; 798 799 if (isset($relationship['settings form validate']) && function_exists($relationship['settings form validate'])) { 800 $relationship['settings form validate']($form['relationship']['relationship_settings'], $form_state['values']['relationship']['relationship_settings'], $form_state); 801 } 802 } 803 804 /** 805 * Updates an relationship edited/added via ajax 806 */ 807 function ctools_edit_relationship_form_submit($form, &$form_state) { 808 $relationship = $form_state['info']; 809 810 if (isset($relationship['settings form submit']) && function_exists($relationship['settings form submit'])) { 811 $relationship['settings form submit']($form, $form_state['values']['relationship']['relationship_settings'], $form_state); 812 } 813 814 $form_state['ref'][$form_state['position']] = $form_state['values']['relationship']; 815 } 816 817 /** 818 * Form (for ajax use) to add an argument 819 */ 820 function ctools_edit_argument_form(&$form_state) { 821 // Basic values required to orient ourselves 822 $object = $form_state['object']; 823 $argument = $form_state['info']; 824 $position = $form_state['position']; 825 $contexts = $form_state['contexts']; 826 827 $arg = $object->arguments[$position]; 828 829 if (!isset($arg['default'])) { 830 $arg['default'] = 'ignore'; 831 $arg['title'] = ''; 832 } 833 834 $form['description'] = array( 835 '#prefix' => '<div class="description">', 836 '#suffix' => '</div>', 837 '#value' => check_plain($argument['description']), 838 ); 839 840 // Basic argument values 841 $form['argument']['#tree'] = TRUE; 842 843 $form['argument']['name'] = array( 844 '#type' => 'hidden', 845 '#value' => $argument['name'], 846 ); 847 848 $form['argument']['id'] = array( 849 '#type' => 'hidden', 850 '#value' => $arg['id'], 851 ); 852 853 $form['argument']['default'] = array( 854 '#type' => 'select', 855 '#title' => t('Default'), 856 '#options' => array( 857 'ignore' => t('Ignore it; content that requires this context will not be available.'), 858 '404' => t('Display page not found or display nothing at all.'), 859 ), 860 '#default_value' => $arg['default'], 861 '#description' => t('If the argument is missing or is not valid, select how this should behave.'), 862 ); 863 864 $form['argument']['title'] = array( 865 '#type' => 'textfield', 866 '#title' => t('Title'), 867 '#default_value' => $arg['title'], 868 '#description' => t('Enter a title to use when this argument is present. You may use %KEYWORD substitution, where the keyword is specified below.'), 869 ); 870 871 $form['argument']['identifier'] = array( 872 '#type' => 'textfield', 873 '#title' => t('Identifier'), 874 '#description' => t('Enter a name to identify this !type on administrative screens.', array('!type' => t('argument'))), 875 '#default_value' => $arg['identifier'], 876 ); 877 878 $form['argument']['keyword'] = array( 879 '#type' => 'textfield', 880 '#title' => t('Keyword'), 881 '#description' => t('Enter a keyword to use for substitution in titles.'), 882 '#default_value' => $arg['keyword'], 883 ); 884 885 // Settings particular to this argument 886 $argument_settings = array(); 887 if (isset($arg['argument_settings'])) { 888 $argument_settings = $arg['argument_settings']; 889 } 890 891 892 if (isset($argument['settings form']) && function_exists($argument['settings form'])) { 893 $form['argument']['argument_settings'] = $argument['settings form']($argument_settings); 894 } 895 $form['argument']['argument_settings']['#tree'] = TRUE; 896 897 $form['next'] = array( 898 '#type' => 'submit', 899 '#value' => t('Save'), 900 ); 901 902 return $form; 903 } 904 905 /** 906 * validate an argument edited/added via ajax 907 */ 908 function ctools_edit_argument_form_validate($form, &$form_state) { 909 $argument = $form_state['info']; 910 911 if (isset($argument['settings form validate']) && function_exists($argument['settings form validate'])) { 912 $argument['settings form validate']($form, $form_state['values']['argument_settings'], $form_state); 913 } 914 } 915 916 /** 917 * Updates an argument edited/added via ajax 918 */ 919 function ctools_edit_argument_form_submit($form, &$form_state) { 920 $argument = $form_state['info']; 921 922 if (!isset($form_state['values']['argument_settings'])) { 923 $form_state['values']['argument_settings'] = array(); 924 } 925 926 if (isset($argument['settings form submit']) && function_exists($argument['settings form submit'])) { 927 $argument['settings form submit']($form, $form_state['values']['argument_settings'], $form_state); 928 } 929 930 $form_state['ref'][$form_state['position']] = $form_state['values']['argument']; 931 } 932 933 /** 934 * Ajax entry point to edit an item 935 */ 936 function ctools_context_ajax_item_delete($module = NULL, $type = NULL, $object_name = NULL, $position = NULL) { 937 ctools_include('ajax'); 938 ctools_include('context'); 939 ctools_include('object-cache'); 940 941 if (!isset($position)) { 942 return ctools_ajax_render_error(); 943 } 944 945 // Load stored object from cache. 946 if (!($object = ctools_context_cache_get($module, $object_name))) { 947 ctools_ajax_render_error(t('Invalid object name.')); 948 } 949 950 $type_info = ctools_context_info($type); 951 952 // Create a reference to the place our context lives. Since this is fairly 953 // generic, this is the easiest way to get right to the place of the 954 // object without knowing precisely what data we're poking at. 955 $ref = &$object->{$type_info['key']}; 956 957 if (!array_key_exists($position, $ref)) { 958 ctools_ajax_render_error(t('Unable to delete missing item!')); 959 } 960 961 unset($ref[$position]); 962 ctools_context_cache_set($module, $object_name, $object); 963 964 $output = array(); 965 $output[] = ctools_ajax_command_replace('#' . $type . '-row-' . $position, ''); 966 $output[] = ctools_ajax_command_restripe("#$type-table"); 967 ctools_ajax_render($output); 968 } 969 970 // --- End of contexts 971 972 function ctools_save_context($type, &$ref, $form_values) { 973 $type_info = ctools_context_info($type); 974 975 // Organize arguments 976 $new = array(); 977 $order = array(); 978 979 foreach ($ref as $id => $context) { 980 $position = $form_values[$type][$id]['position']; 981 $order[$position] = $id; 982 } 983 984 ksort($order); 985 foreach ($order as $id) { 986 $new[] = $ref[$id]; 987 } 988 $ref = $new; 989 } 990 991 function ctools_get_keyword($page, $word) { 992 // Create a complete set of keywords 993 $keywords = array(); 994 foreach (array('arguments', 'relationships', 'contexts', 'requiredcontexts') as $type) { 995 if (!empty($page->$type) && is_array($page->$type)) { 996 foreach ($page->$type as $info) { 997 $keywords[$info['keyword']] = TRUE; 998 } 999 } 1000 } 1001 1002 $keyword = $word; 1003 $count = 0; 1004 while (!empty($keywords[$keyword])) { 1005 $keyword = $word . '_' . ++$count; 1006 } 1007 return $keyword; 1008 } 1009
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Mon Jul 9 18:01:44 2012 | Cross-referenced by PHPXref 0.7 |