00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 class panels_allowed_layouts {
00046
00047
00048
00049
00050
00051
00052
00053 var $allow_new = TRUE;
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065 var $module_name = NULL;
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075 var $allowed_layout_settings = array();
00076
00077
00078
00079
00080
00081
00082 var $form_state;
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093 function panels_allowed_layouts($start_allowed = TRUE) {
00094
00095 foreach ($this->list_layouts() as $layout_name) {
00096 $this->allowed_layout_settings[$layout_name] = $start_allowed ? 1 : 0;
00097 }
00098 }
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148 function set_allowed($title = 'Panels: Allowed Layouts') {
00149 $this->sync_with_available();
00150 $form_id = 'panels_common_set_allowed_layouts';
00151 $form = drupal_retrieve_form($form_id, $this, $title);
00152
00153 if ($result = drupal_process_form($form_id, $form)) {
00154
00155 $this->form_state = 'submit';
00156 return $result;
00157 }
00158 $this->form_state = isset($_POST['op']) ? 'failed-validate' : 'render';
00159 $result = drupal_render_form($form_id, $form);
00160 return $result;
00161 }
00162
00163
00164
00165
00166
00167
00168
00169 function sync_with_available() {
00170 $layouts = $this->list_layouts();
00171 foreach (array_diff($layouts, array_keys($this->allowed_layout_settings)) as $new_layout) {
00172 $this->allowed_layout_settings[$new_layout] = $this->allow_new ? 1 : 0;
00173 }
00174 foreach (array_diff(array_keys($this->allowed_layout_settings), $layouts) as $deleted_layout) {
00175 unset($this->allowed_layout_settings[$deleted_layout]);
00176 }
00177 }
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197 function api_save() {
00198 if (!is_null($this->module_name)) {
00199 variable_set($this->module_name . "_allowed_layouts", serialize($this));
00200 }
00201 }
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212 function list_layouts() {
00213 static $layouts = array();
00214 if (empty($layouts)) {
00215 panels_load_include('plugins');
00216 $layouts = array_keys(panels_get_layouts());
00217 }
00218 return $layouts;
00219 }
00220 }
00221
00222
00223
00224
00225
00226 function panels_common_settings($module_name = 'panels_common') {
00227 panels_load_include('plugins');
00228 $content_types = panels_get_content_types();
00229 $default_types = variable_get($module_name . '_default', NULL);
00230 if (!isset($default_types)) {
00231 $default_types = array('block' => TRUE, 'views' => TRUE, 'other' => TRUE);
00232 $skip = TRUE;
00233 }
00234
00235 foreach ($content_types as $id => $info) {
00236 if (empty($info['single'])) {
00237 $default_options[$id] = t('New @s', array('@s' => $info['title']));
00238 }
00239 }
00240
00241 $default_options['other'] = t('New content of other types');
00242 $form['panels_common_default'] = array(
00243 '#type' => 'checkboxes',
00244 '#title' => t('New content behavior'),
00245 '#description' => t('Select the default behavior of new content added to the system. If checked, new content will automatically be immediately available to be added to Panels pages. If not checked, new content will not be available until specifically allowed here.'),
00246 '#options' => $default_options,
00247 '#default_value' => array_keys(array_filter($default_types)),
00248 );
00249
00250 if ($skip) {
00251 $form['markup'] = array('#value' => t('<p>Click Submit to be presented with a complete list of available content types set to the defaults you selected.</p>'));
00252 $form['skip'] = array('#type' => 'value', '#value' => TRUE);
00253 }
00254 else {
00255
00256
00257
00258 $available_content_types = panels_get_all_content_types();
00259 $allowed_content_types = variable_get($module_name . '_allowed_types', array());
00260
00261 foreach ($available_content_types as $id => $types) {
00262 foreach ($types as $type => $info) {
00263 $key = $id . '-' . $type;
00264 $checkboxes = empty($content_types[$id]['single']) ? $id : 'other';
00265 $options[$checkboxes][$key] = $info['title'];
00266 if (!isset($allowed_content_types[$key])) {
00267 $allowed[$checkboxes][$key] = isset($default_types[$id]) ? $default_types[$id] : $default_types['other'];
00268 }
00269 else {
00270 $allowed[$checkboxes][$key] = $allowed_content_types[$key];
00271 }
00272 }
00273 }
00274
00275 $form['content_types'] = array('#tree' => TRUE);
00276
00277 $content_types['other'] = array('title' => t('Other'), 'weight' => 10);
00278 foreach ($content_types as $id => $info) {
00279 if (isset($allowed[$id])) {
00280 $form['content_types'][$id] = array(
00281 '#prefix' => '<div class="panels-page-type-container clear-block">',
00282 '#suffix' => '</div>',
00283 '#type' => 'checkboxes',
00284 '#title' => t('Allowed @s content', array('@s' => $info['title'])),
00285 '#options' => $options[$id],
00286 '#default_value' => array_keys(array_filter($allowed[$id])),
00287 );
00288 }
00289 }
00290 }
00291
00292 $form['module_name'] = array(
00293 '#type' => 'value',
00294 '#value' => $module_name,
00295 );
00296
00297 $form['submit'] = array(
00298 '#type' => 'submit',
00299 '#value' => t('Submit'),
00300 );
00301
00302 drupal_add_css(panels_get_path('css/panels_page.css'));
00303 return $form;
00304 }
00305
00306
00307
00308
00309 function panels_common_settings_submit($form_id, $form_values) {
00310 $module_name = $form_values['module_name'];
00311 variable_set($module_name . '_default', $form_values['panels_common_default']);
00312 if (!$form_values['skip']) {
00313
00314 variable_set($module_name . '_allowed_types', call_user_func_array('array_merge', $form_values['content_types']));
00315 }
00316 drupal_set_message(t('Your changes have been saved.'));
00317 }
00318
00319
00320
00321
00322 function panels_common_get_allowed_types($module, $contexts = array(), $has_content = FALSE, $default_defaults = array(), $default_allowed_types = array()) {
00323
00324
00325
00326 $default_types = variable_get($module . '_defaults', $default_defaults);
00327 $allowed_types = variable_get($module . '_allowed_types', $default_allowed_types);
00328
00329
00330
00331 if (!isset($default_types['other'])) {
00332 $default_types['other'] = TRUE;
00333 }
00334
00335 panels_load_include('plugins');
00336 $content_types = panels_get_available_content_types($contexts, $has_content, $allowed_types, $default_types);
00337
00338 return $content_types;
00339 }
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366 function panels_common_set_allowed_layouts($allowed_layouts, $title) {
00367 $layouts = panels_get_layouts();
00368 foreach ($layouts as $id => $layout) {
00369 $options[$id] = panels_print_layout_icon($id, $layout, check_plain($layout['title']));
00370 }
00371
00372 drupal_set_title($title);
00373
00374 $form['variables'] = array('#type' => 'value', '#value' => array($allowed_layouts));
00375
00376 drupal_add_js(panels_get_path('js/layout.js'));
00377 $form['layouts'] = array(
00378 '#type' => 'checkboxes',
00379 '#title' => t('Select allowed layouts'),
00380 '#options' => $options,
00381 '#description' => t('Check the boxes for all layouts you want to allow users choose from when picking a layout. You must allow at least one layout.'),
00382 '#default_value' => array_keys(array_filter($allowed_layouts->allowed_layout_settings)),
00383 );
00384
00385 $form['clearer'] = array(
00386
00387 '#value' => '<div style="clear: both;"></div>',
00388 );
00389 $form['#redirect'] = FALSE;
00390 $form['submit'] = array(
00391 '#type' => 'submit',
00392 '#value' => t('Save'),
00393 );
00394
00395 $form['#token'] = FALSE;
00396 return $form;
00397 }
00398
00399 function panels_common_set_allowed_layouts_validate($form_id, $form_values, $form) {
00400 $selected = array_filter($form_values['layouts']);
00401 if (empty($selected)) {
00402 form_set_error('layouts', 'You must choose at least one layout to allow.');
00403 }
00404 }
00405
00406 function panels_common_set_allowed_layouts_submit($form_id, $form_values) {
00407 list($allowed_layouts) = $form_values['variables'];
00408 foreach ($form_values['layouts'] as $layout => $setting) {
00409 $allowed_layouts->allowed_layout_settings[$layout] = $setting === 0 ? 0 : 1;
00410 }
00411 method_exists($allowed_layouts, 'save') ? $allowed_layouts->save() : $allowed_layouts->api_save();
00412 return $allowed_layouts->allowed_layout_settings;
00413 }
00414
00415
00416
00417
00418 function panels_common_get_layout_information($panel_implementation, $contexts = array()) {
00419 $form = array();
00420 panels_load_include('plugins');
00421 $layout = panels_get_layout($panel_implementation->display->layout);
00422
00423 $form = array(
00424 '#type' => 'fieldset',
00425 '#title' => t('Layout'),
00426 );
00427
00428 $form['layout-icon'] = array(
00429 '#value' => panels_print_layout_icon($panel_implementation->display->layout, $layout),
00430 );
00431
00432 $form['layout-display'] = array(
00433 '#value' => check_plain($layout['title']),
00434 );
00435 $content = '<dl class="content-list">';
00436
00437 foreach (panels_get_panels($layout, $panel_implementation->display) as $panel_id => $title) {
00438 $content .= "<dt>$title</dt><dd>";
00439 if ($panel_implementation->display->panels[$panel_id]) {
00440 $content .= '<ol>';
00441 foreach ($panel_implementation->display->panels[$panel_id] as $pid) {
00442 $content .= '<li>'. panels_get_pane_title($panel_implementation->display->content[$pid], $contexts) .'</li>';
00443 }
00444 $content .= '</ol>';
00445 }
00446 else {
00447 $content .= t('Empty');
00448 }
00449 $content .= '</dd>';
00450 }
00451 $content .= '</dl>';
00452
00453 $form['layout-content'] = array(
00454 '#value' => $content,
00455 );
00456
00457 return $form;
00458 }
00459
00460
00461
00462
00463
00464
00465 function panels_common_context_info($type = NULL) {
00466 static $info = NULL;
00467
00468
00469 if (empty($info)) {
00470 $info = array(
00471 'argument' => array(
00472 'title' => t('Arguments'),
00473 'singular title' => t('argument'),
00474 '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."),
00475 'add button' => t('Add argument'),
00476 'context function' => 'panels_get_argument',
00477 'sortable' => TRUE,
00478 ),
00479 'relationship' => array(
00480 'title' => t('Relationships'),
00481 'singular title' => t('relationship'),
00482 '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.'),
00483 'add button' => t('Add relationship'),
00484 'context function' => 'panels_get_relationship',
00485 'sortable' => FALSE,
00486 ),
00487 'context' => array(
00488 'title' => t('Contexts'),
00489 'singular title' => t('context'),
00490 '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"'),
00491 'add button' => t('Add context'),
00492 'context function' => 'panels_get_context',
00493 'sortable' => FALSE,
00494 ),
00495 'requiredcontext' => array(
00496 'title' => t('Required contexts'),
00497 'singular title' => t('required context'),
00498 '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.'),
00499 'add button' => t('Add required context'),
00500 'context function' => 'panels_get_context',
00501 'sortable' => TRUE,
00502 ),
00503 );
00504 }
00505
00506 if ($type === NULL) {
00507 return $info;
00508 }
00509
00510 return $info[$type];
00511 }
00512
00513 function panels_common_context_data($type, $name) {
00514 $info = panels_common_context_info($type);
00515 if (function_exists($info['context function'])) {
00516 return $info['context function']($name);
00517 }
00518 }
00519
00520
00521
00522
00523 function panels_common_add_argument_form($module, &$form, &$form_location, $object) {
00524 $form_location = array(
00525 '#theme' => 'panels_common_context_item_form',
00526 '#panel_name' => $object->name,
00527 '#panels_context_type' => 'argument',
00528 '#panels_context_module' => $module,
00529 );
00530
00531 $form['arguments'] = array(
00532 '#type' => 'value',
00533 '#value' => $object->arguments,
00534 );
00535
00536
00537 $form['argument_order'] = array(
00538 '#type' => 'hidden',
00539 '#id' => 'argument-order',
00540 '#default_value' => $object->arguments ? implode(',', array_keys($object->arguments)) : '',
00541 );
00542
00543 $args = panels_get_arguments();
00544 $choices = array();
00545 foreach ($args as $name => $arg) {
00546 $choices[$name] = $arg['title'];
00547 }
00548
00549 asort($choices);
00550
00551 if (!empty($choices) || !empty($object->arguments)) {
00552 panels_common_add_item_table('argument', $form_location, $choices, $object->arguments);
00553 }
00554 return _panels_common_context_js($object->name, $module, 'argument');
00555 }
00556
00557 function panels_common_add_context_form($module, &$form, &$form_location, $object) {
00558 $form['contexts'] = array(
00559 '#type' => 'value',
00560 '#value' => $object->contexts,
00561 );
00562
00563 $form_location = array(
00564 '#prefix' => '<div id="panels-contexts-table">',
00565 '#suffix' => '</div>',
00566 '#theme' => 'panels_common_context_item_form',
00567 '#panel_name' => $object->name,
00568 '#panels_context_type' => 'context',
00569 '#panels_context_module' => $module,
00570 );
00571
00572
00573 $form_location['markup'] = array(
00574 '#value' => ' ',
00575 );
00576 $form['context_order'] = array(
00577 '#type' => 'hidden',
00578 '#id' => 'context-order',
00579 '#default_value' => $object->contexts ? implode(',', array_keys($object->contexts)) : '',
00580 );
00581
00582 $choices = array();
00583 foreach (panels_get_contexts() as $name => $arg) {
00584 if (empty($arg['no ui'])) {
00585 $choices[$name] = $arg['title'];
00586 }
00587 }
00588
00589 asort($choices);
00590
00591 if (!empty($choices) || !empty($object->contexts)) {
00592 panels_common_add_item_table('context', $form_location, $choices, $object->contexts);
00593 }
00594 return _panels_common_context_js($object->name, $module, 'context');
00595 }
00596
00597 function panels_common_add_required_context_form($module, &$form, &$form_location, $object) {
00598 $form['requiredcontexts'] = array(
00599 '#type' => 'value',
00600 '#value' => $object->requiredcontexts,
00601 );
00602
00603 $form_location = array(
00604 '#prefix' => '<div id="panels-requiredcontexts-table">',
00605 '#suffix' => '</div>',
00606 '#theme' => 'panels_common_context_item_form',
00607 '#panel_name' => $object->name,
00608 '#panels_context_type' => 'requiredcontext',
00609 '#panels_context_module' => $module,
00610 );
00611
00612
00613 $form_location['markup'] = array(
00614 '#value' => ' ',
00615 );
00616 $form['requiredcontext_order'] = array(
00617 '#type' => 'hidden',
00618 '#id' => 'requiredcontext-order',
00619 '#default_value' => $object->requiredcontexts ? implode(',', array_keys($object->requiredcontexts)) : '',
00620 );
00621
00622 $choices = array();
00623 foreach (panels_get_contexts() as $name => $arg) {
00624 $choices[$name] = $arg['title'];
00625 }
00626
00627 asort($choices);
00628
00629 if (!empty($choices) || !empty($object->contexts)) {
00630 panels_common_add_item_table('requiredcontext', $form_location, $choices, $object->requiredcontexts);
00631 }
00632 return _panels_common_context_js($object->name, $module, 'requiredcontext');
00633 }
00634
00635 function panels_common_add_relationship_form($module, &$form, &$form_location, $object) {
00636 $form['relationships'] = array(
00637 '#type' => 'value',
00638 '#value' => $object->relationships,
00639 );
00640
00641 $form_location = array(
00642 '#prefix' => '<div id="panels-relationships-table">',
00643 '#suffix' => '</div>',
00644 '#theme' => 'panels_common_context_item_form',
00645 '#panel_name' => $object->name,
00646 '#panels_context_type' => 'relationship',
00647 '#panels_context_module' => $module,
00648 );
00649
00650
00651 $form_location['markup'] = array(
00652 '#value' => ' ',
00653 );
00654 $form['relationship_order'] = array(
00655 '#type' => 'hidden',
00656 '#id' => 'relationship-order',
00657 '#default_value' => $object->relationships ? implode(',', array_keys($object->relationships)) : '',
00658 );
00659
00660 $available_relationships = panels_get_relevant_relationships(panels_context_load_contexts($object));
00661
00662
00663 panels_common_add_item_table('relationship', $form_location, $available_relationships, $object->relationships);
00664
00665
00666 return _panels_common_context_js($object->name, $module, 'relationship');
00667 }
00668
00669 function _panels_common_context_js($name, $module, $type) {
00670 return array($type . '-table' => array(
00671
00672 'remove' => "input.$type-remove",
00673
00674 'order' => "input#$type-order",
00675 'up' => "input.$type-up",
00676 'down' => "input.$type-down",
00677 'configure' => "input.$type-settings",
00678 'configure_path' => url("panels/common/ajax/edit/$module/$type/$name", NULL, NULL, TRUE),
00679
00680
00681 'add' => "input#edit-buttons-$type-add",
00682
00683 'path' => url("panels/common/ajax/add/$module/$type/$name", NULL, NULL, TRUE),
00684
00685 'post' => array("#edit-buttons-$type-item", "input#edit-buttons-$type-add"),
00686
00687 'tr' => $type . '-row-',
00688 'row_class' => "tr.$type-row",
00689
00690 'replace' => array('div#panels-relationships-table div.buttons' => 'relationships_table'),
00691 ));
00692 }
00693
00694 function panels_common_add_context_js($base) {
00695 $settings = array(
00696 'list' => $base,
00697 'panels' => array(
00698 'closeText' => t('Close Window'),
00699 'closeImage' => theme('image', panels_get_path('images/close.gif'), t('Close window'), t('Close window')),
00700 'throbber' => theme('image', panels_get_path('images/throbber.gif'), t('Loading...'), t('Loading')),
00701 ),
00702 );
00703
00704 drupal_add_js($settings, 'setting');
00705 drupal_add_js(panels_get_path('js/list.js'));
00706 drupal_add_js(panels_get_path('js/lib/dimensions.js'));
00707 drupal_add_js(panels_get_path('js/lib/mc.js'));
00708 drupal_add_js(panels_get_path('js/lib/form.js'));
00709 drupal_add_js(panels_get_path('js/modal_forms.js'));
00710 drupal_add_css(panels_get_path('css/panels_dnd.css'));
00711
00712 drupal_add_js('misc/collapse.js');
00713 drupal_add_js('misc/autocomplete.js');
00714 }
00715
00716
00717
00718
00719 function panels_common_add_item_table($type, &$form, $available_contexts, $items) {
00720 $form[$type] = array(
00721 '#tree' => TRUE,
00722 );
00723
00724 if (isset($items) && is_array($items)) {
00725 foreach ($items as $position => $context) {
00726 panels_common_add_item_to_form($type, $form[$type][$position], $position, $context);
00727 }
00728 }
00729
00730 $type_info = panels_common_context_info($type);
00731 $form['description'] = array(
00732 '#prefix' => '<div class="description">',
00733 '#suffix' => '</div>',
00734 '#value' => $type_info['description'],
00735 );
00736
00737 panels_common_add_item_table_buttons($type, $form, $available_contexts);
00738 }
00739
00740 function panels_common_add_item_table_buttons($type, &$form, $available_contexts) {
00741 $form['buttons'] = array(
00742 '#tree' => TRUE,
00743 );
00744
00745 if (!empty($available_contexts)) {
00746 $form['buttons'][$type]['item'] = array(
00747 '#type' => 'select',
00748 '#options' => $available_contexts,
00749 );
00750
00751 $type_info = panels_common_context_info($type);
00752 $form['buttons'][$type]['add'] = array(
00753 '#type' => 'submit',
00754 '#attributes' => array('class' => $type . '-add'),
00755 '#value' => $type_info['add button'],
00756 );
00757 }
00758 }
00759
00760
00761
00762
00763
00764 function panels_common_add_item_to_form($type, &$form, $position, $item) {
00765
00766 $info = panels_common_context_data($type, $item['name']);
00767 $form['title'] = array(
00768 '#value' => check_plain($item['identifier']),
00769 );
00770
00771
00772 $type_info = panels_common_context_info($type);
00773
00774 if (!empty($type_info['sortable'])) {
00775 $form['up'] = panels_add_button('go-up.png', t('Up'),
00776 t('Move this item up'),
00777 $type . '-up',
00778 $type . '-up-' . $position
00779 );
00780
00781 $form['down'] = panels_add_button('go-down.png', t('Down'),
00782 t('Move this item down'),
00783 $type . '-down',
00784 $type . '-down-' . $position
00785 );
00786 }
00787
00788 $form['remove'] = panels_add_button('icon-delete.png', t('Remove'),
00789 t('Remove this item'),
00790 $type . '-remove',
00791 $type . '-remove-' . $position
00792 );
00793
00794 $form['settings'] = panels_add_button('icon-configure.png', t('Configure'),
00795 t('Configure this item'),
00796 $type . '-settings',
00797 $type . '-settings-' . $position
00798 );
00799 }
00800
00801
00802
00803
00804 function theme_panels_common_context_item_row($type, $form, $position, $count, $with_tr = TRUE) {
00805 $output = '<td class="title"> ' . drupal_render($form['title']) . '</td>';
00806 $output .= '<td class="operation">' . drupal_render($form['settings']);
00807 $type_info = panels_common_context_info($type);
00808 if (!empty($type_info['sortable'])) {
00809 $output .= drupal_render($form['up']) . drupal_render($form['down']);
00810 }
00811 $output .= drupal_render($form['remove']) . '</td>';
00812
00813 if ($with_tr) {
00814 $output = '<tr id="' . $type . '-row-' . $position . '" class="' . $type . '-row ' . ($count % 2 ? 'even' : 'odd') . '">' . $output . '</tr>';
00815 }
00816 return $output;
00817 }
00818
00819
00820
00821
00822 function theme_panels_common_context_item_form($form) {
00823 $output = '';
00824 $type = $form['#panels_context_type'];
00825 $module = $form['#panels_context_module'];
00826 $name = $form['#panel_name'];
00827
00828 $type_info = panels_common_context_info($type);
00829
00830 if (!empty($form[$type]) && empty($form['#only_buttons'])) {
00831 $output .= '<table id="' . $type . '-table">';
00832 $output .= '<thead>';
00833 $output .= '<tr>';
00834 $output .= '<th class="title">' . $type_info['title'] . '</th>';
00835 $output .= '<th class="operation">' . t('Operation') . '</th>';
00836 $output .= '</tr>';
00837 $output .= '</thead>';
00838 $output .= '<tbody>';
00839
00840 $count = 0;
00841 foreach (array_keys($form[$type]) as $id) {
00842 if (!is_numeric($id)) {
00843 continue;
00844 }
00845 $output .= theme('panels_common_context_item_row', $type, $form[$type][$id], $id, $count++);
00846 }
00847
00848 $output .= '</tbody>';
00849 $output .= '</table>';
00850 }
00851
00852 if (!empty($form['buttons'])) {
00853
00854 $row = array();
00855 $row[] = array('data' => drupal_render($form['buttons'][$type]['item']), 'class' => 'title');
00856 $row[] = array('data' => drupal_render($form['buttons'][$type]['add']), 'class' => 'add', 'width' => "60%");
00857 $output .= '<div class="buttons">';
00858 $output .= theme('table', array(), array($row), array('id' => $type . '-add-table'));
00859 $output .= '</div>';
00860 }
00861 if (!empty($form['description'])) {
00862 $output .= drupal_render($form['description']);
00863 }
00864
00865 return $output;
00866 }
00867
00868
00869
00870
00871 function panels_common_ajax_context_item_add($module, $type, $panel_name) {
00872 $object = panels_common_cache_get("panel_object:$module", $panel_name);
00873 if (!$object || !$type) {
00874 panels_ajax_render();
00875 }
00876
00877
00878 if (isset($_POST['buttons'][$type]['item'])) {
00879 $name = $_POST['buttons'][$type]['item'];
00880
00881
00882 unset($_POST);
00883 }
00884 else if (isset($_POST[$type]['name'])) {
00885 $name = $_POST[$type]['name'];
00886 }
00887
00888 if (empty($name)) {
00889 panels_ajax_render();
00890 }
00891
00892 $info = panels_common_context_data($type, $name);
00893 if (empty($info)) {
00894 panels_ajax_render();
00895 }
00896
00897
00898 $keyword = $type . 's';
00899 $ref = &$object->$keyword;
00900
00901
00902
00903 $id = panels_common_get_arg_id($ref, $name) + 1;
00904
00905
00906 $position = empty($ref) ? 0 : max(array_keys($ref)) + 1;
00907
00908
00909 $ref[$position] = array(
00910 'identifier' => $info['title'] . ($id > 1 ? ' ' . $id : ''),
00911 'keyword' => panels_common_get_keyword($object, $info['keyword']),
00912 'id' => $id,
00913 );
00914
00915 $contexts = panels_context_load_contexts($object);
00916
00917 $form_id = 'panels_common_edit_' . $type . '_form';
00918 $form = drupal_retrieve_form($form_id, $object, $info, $position, $contexts);
00919 if ($_POST && $_POST['form_id'] == $form_id) {
00920 $form['#redirect'] = FALSE;
00921 }
00922
00923 $retval = drupal_process_form($form_id, $form);
00924 if ($retval) {
00925
00926
00927
00928 $ref[$position] = $retval;
00929 panels_common_cache_set("panel_object:$module", $panel_name, $object);
00930
00931
00932 $arg_form[$type] = array(
00933 '#tree' => TRUE,
00934 );
00935
00936 panels_common_add_item_to_form($type, $arg_form[$type], $position, $retval);
00937 $arg_form = form_builder($form_id, $arg_form);
00938
00939
00940
00941 $rel_form = array(
00942 '#theme' => 'panels_common_context_item_form',
00943 '#panel_name' => $panel_name,
00944 '#panels_context_type' => 'relationship',
00945 '#panels_context_module' => $module,
00946 '#only_buttons' => TRUE,
00947 );
00948
00949 $rel_form['relationship'] = array(
00950 '#tree' => TRUE,
00951 );
00952
00953 $available_relationships = panels_get_relevant_relationships(panels_context_load_contexts($object));
00954
00955 $output = new stdClass();
00956 if (!empty($available_relationships)) {
00957 panels_common_add_item_table_buttons('relationship', $rel_form, $available_relationships);
00958 $rel_form = form_builder('dummy_form_id', $rel_form);
00959 $output->relationships_table = drupal_render($rel_form);
00960 }
00961
00962 $output->type = 'add';
00963 $output->output = theme('panels_common_context_item_row', $type, $arg_form[$type], $position, $position);
00964 $output->position = $position;
00965 panels_ajax_render($output);
00966 }
00967 else {
00968 $type_info = panels_common_context_info($type);
00969 $title = t('Add @type "@context"', array('@type' => $type_info['singular title'], '@context' => $info['title']));
00970 $output = theme('status_messages');
00971 $output .= drupal_render_form($form_id, $form);
00972 panels_ajax_render($output, $title, url($_GET['q'], NULL, NULL, TRUE));
00973 }
00974 }
00975
00976
00977
00978
00979 function panels_common_ajax_context_item_edit($module, $type, $panel_name) {
00980 $object = panels_common_cache_get("panel_object:$module", $panel_name);
00981 if (!$object) {
00982 panels_ajax_render();
00983 }
00984
00985
00986 if (isset($_POST['position'])) {
00987 $position = $_POST['position'];
00988 }
00989
00990 if (!isset($_POST['form_id'])) {
00991
00992
00993 unset($_POST);
00994 }
00995
00996
00997 $keyword = $type . 's';
00998 $ref = &$object->$keyword;
00999
01000 $name = $ref[$position]['name'];
01001 if (empty($name)) {
01002 panels_ajax_render();
01003 }
01004
01005
01006 $info = panels_common_context_data($type, $name);
01007 if (empty($info)) {
01008 panels_ajax_render();
01009 }
01010
01011 $type_info = panels_common_context_info($type);
01012 $title = t('Edit @type "@context"', array('@type' => $type_info['singular title'], '@context' => $info['title']));
01013
01014 $contexts = panels_context_load_contexts($object);
01015
01016
01017
01018 unset($contexts[panels_context_context_id($ref[$position])]);
01019
01020 $form_id = 'panels_common_edit_' . $type . '_form';
01021 $form = drupal_retrieve_form($form_id, $object, $info, $position, $contexts);
01022 if ($_POST && $_POST['form_id'] == $form_id) {
01023
01024 $form['#redirect'] = FALSE;
01025 }
01026
01027 $retval = drupal_process_form($form_id, $form);
01028 if ($retval) {
01029 $output = new stdClass();
01030
01031
01032
01033 $ref[$position] = $retval;
01034 panels_common_cache_set("panel_object:$module", $panel_name, $object);
01035
01036 $output->type = $output->output = 'dismiss';
01037
01038
01039
01040 $arg_form[$type] = array(
01041 '#tree' => TRUE,
01042 );
01043
01044 panels_common_add_item_to_form($type, $arg_form[$type], $position, $retval);
01045 $arg_form = form_builder($form_id, $arg_form);
01046
01047 $output->replace = theme('panels_common_context_item_row', $type, $arg_form[$type], $position, $position, FALSE);
01048 $output->replace_id = '#' . $type . '-row-' . $position;
01049
01050 panels_ajax_render($output);
01051 }
01052 else {
01053 $output = theme('status_messages');
01054 $output .= drupal_render_form($form_id, $form);
01055 panels_ajax_render($output, $title, url($_GET['q'], NULL, NULL, TRUE));
01056 }
01057 }
01058
01059
01060
01061
01062 function panels_common_edit_context_form($object, $context, $position, $contexts) {
01063 $ctext = $object->contexts[$position];
01064 $form['position'] = array(
01065 '#type' => 'hidden',
01066 '#value' => $position,
01067 );
01068
01069 $form['start_form'] = array('#value' => '<div class="modal-form clear-block">');
01070
01071 $form['description'] = array(
01072 '#prefix' => '<div class="description">',
01073 '#suffix' => '</div>',
01074 '#value' => check_plain($context['description']),
01075 );
01076
01077
01078 $form['context']['#tree'] = TRUE;
01079
01080 $form['context']['name'] = array(
01081 '#type' => 'hidden',
01082 '#value' => $context['name'],
01083 );
01084
01085 $form['context']['id'] = array(
01086 '#type' => 'value',
01087 '#value' => $ctext['id'],
01088 );
01089
01090 $form['context']['identifier'] = array(
01091 '#type' => 'textfield',
01092 '#title' => t('Identifier'),
01093 '#description' => t('Enter a name to identify this !type on administrative screens.', array('!type' =>t('context'))),
01094 '#default_value' => $ctext['identifier'],
01095 );
01096
01097 $form['context']['keyword'] = array(
01098 '#type' => 'textfield',
01099 '#title' => t('Keyword'),
01100 '#description' => t('Enter a keyword to use for substitution in titles.'),
01101 '#default_value' => $ctext['keyword'],
01102 );
01103
01104
01105 $context_settings = array();
01106 if (isset($ctext['context_settings'])) {
01107 $context_settings = $ctext['context_settings'];
01108 }
01109
01110 if (isset($context['settings form']) && function_exists($context['settings form'])) {
01111 $form['context']['context_settings'] = $context['settings form']($context_settings);
01112 $form['context']['context_settings']['#tree'] = TRUE;
01113 }
01114
01115 $form['context_info'] = array(
01116 '#type' => 'value',
01117 '#value' => $context,
01118 );
01119
01120 $form['end_form'] = array('#value' => '</div>');
01121
01122 $form['next'] = array(
01123 '#type' => 'submit',
01124 '#value' => t('Save'),
01125 );
01126 return $form;
01127 }
01128
01129
01130
01131
01132 function panels_common_edit_context_form_validate($form_id, $form_values, $form) {
01133 $context = $form_values['context_info'];
01134
01135 if (isset($context['settings form validate']) && function_exists($context['settings form validate'])) {
01136 $context['settings form validate']($form['context']['context_settings'], $form_values['context']['context_settings']);
01137 }
01138 }
01139
01140
01141
01142
01143 function panels_common_edit_context_form_submit($form_id, $form_values) {
01144 $context = $form_values['context'];
01145 $info = $form_values['context_info'];
01146
01147 if (isset($info['settings form submit']) && function_exists($info['settings form submit'])) {
01148 $info['settings form submit']($form_values['context_settings']);
01149 }
01150
01151 return $context;
01152 }
01153
01154
01155
01156
01157 function panels_common_edit_requiredcontext_form($object, $context, $position, $contexts) {
01158 $ctext = $object->requiredcontexts[$position];
01159 $form['position'] = array(
01160 '#type' => 'hidden',
01161 '#value' => $position,
01162 );
01163
01164 $form['start_form'] = array('#value' => '<div class="modal-form clear-block">');
01165
01166 $form['description'] = array(
01167 '#prefix' => '<div class="description">',
01168 '#suffix' => '</div>',
01169 '#value' => check_plain($context['description']),
01170 );
01171
01172
01173 $form['requiredcontext']['#tree'] = TRUE;
01174
01175 $form['requiredcontext']['name'] = array(
01176 '#type' => 'hidden',
01177 '#value' => $context['name'],
01178 );
01179
01180 $form['requiredcontext']['id'] = array(
01181 '#type' => 'value',
01182 '#value' => $ctext['id'],
01183 );
01184
01185 $form['requiredcontext']['identifier'] = array(
01186 '#type' => 'textfield',
01187 '#title' => t('Identifier'),
01188 '#description' => t('Enter a name to identify this !type on administrative screens.', array('!type' =>t('required context'))),
01189 '#default_value' => $ctext['identifier'],
01190 );
01191
01192 $form['requiredcontext']['keyword'] = array(
01193 '#type' => 'textfield',
01194 '#title' => t('Keyword'),
01195 '#description' => t('Enter a keyword to use for substitution in titles.'),
01196 '#default_value' => $ctext['keyword'],
01197 );
01198
01199 $form['context_info'] = array(
01200 '#type' => 'value',
01201 '#value' => $context,
01202 );
01203
01204 $form['end_form'] = array('#value' => '</div>');
01205
01206 $form['next'] = array(
01207 '#type' => 'submit',
01208 '#value' => t('Save'),
01209 );
01210 return $form;
01211 }
01212
01213
01214
01215
01216 function panels_common_edit_requiredcontext_form_submit($form_id, $form_values) {
01217 $context = $form_values['requiredcontext'];
01218 return $context;
01219 }
01220
01221
01222
01223
01224 function panels_common_edit_relationship_form($panel_page, $relationship, $position, $contexts) {
01225 $rel = $panel_page->relationships[$position];
01226 $form['position'] = array(
01227 '#type' => 'hidden',
01228 '#value' => $position,
01229 );
01230
01231 $form['start_form'] = array('#value' => '<div class="modal-form clear-block">');
01232
01233 $form['description'] = array(
01234 '#prefix' => '<div class="description">',
01235 '#suffix' => '</div>',
01236 '#value' => check_plain($relationship['description']),
01237 );
01238
01239
01240 $form['relationship']['#tree'] = TRUE;
01241
01242 $form['relationship']['context'] = panels_context_selector($contexts, $relationship['required context'], $rel['context']);
01243
01244 $form['relationship']['name'] = array(
01245 '#type' => 'hidden',
01246 '#value' => $relationship['name'],
01247 );
01248
01249 $form['relationship']['id'] = array(
01250 '#type' => 'value',
01251 '#value' => $rel['id'],
01252 );
01253
01254 $form['relationship']['identifier'] = array(
01255 '#type' => 'textfield',
01256 '#title' => t('Identifier'),
01257 '#description' => t('Enter a name to identify this !type on administrative screens.', array('!type' =>t('relationship'))),
01258 '#default_value' => $rel['identifier'],
01259 );
01260
01261 $form['relationship']['keyword'] = array(
01262 '#type' => 'textfield',
01263 '#title' => t('Keyword'),
01264 '#description' => t('Enter a keyword to use for substitution in titles.'),
01265 '#default_value' => $rel['keyword'],
01266 );
01267
01268
01269 $relationship_settings = array();
01270 if (isset($rel['relationship_settings'])) {
01271 $relationship_settings = $rel['relationship_settings'];
01272 }
01273
01274 if (isset($relationship['settings form']) && function_exists($relationship['settings form'])) {
01275 $form['relationship']['relationship_settings'] = $relationship['settings form']($relationship_settings);
01276 $form['relationship']['relationship_settings']['#tree'] = TRUE;
01277 }
01278
01279 $form['relationship_info'] = array(
01280 '#type' => 'value',
01281 '#value' => $relationship,
01282 );
01283
01284 $form['end_form'] = array('#value' => '</div>');
01285
01286 $form['next'] = array(
01287 '#type' => 'submit',
01288 '#value' => t('Save'),
01289 );
01290 return $form;
01291 }
01292
01293
01294
01295
01296 function panels_common_edit_relationship_form_validate($form_id, $form_values, $form) {
01297 $relationship = $form_values['relationship_info'];
01298
01299 if (isset($relationship['settings form validate']) && function_exists($relationship['settings form validate'])) {
01300 $relationship['settings form validate']($form['relationship']['relationship_settings'], $form_values['relationship']['relationship_settings']);
01301 }
01302 }
01303
01304
01305
01306
01307 function panels_common_edit_relationship_form_submit($form_id, $form_values) {
01308 $relationship = $form_values['relationship'];
01309
01310 if (isset($relationship['settings form submit']) && function_exists($relationship['settings form submit'])) {
01311 $relationship['settings form submit']($form_values['relationship_settings']);
01312 }
01313
01314 return $relationship;
01315 }
01316
01317
01318
01319
01320 function panels_common_edit_argument_form($panel_page, $argument, $position) {
01321
01322 $arg = $panel_page->arguments[$position];
01323
01324 $form['position'] = array(
01325 '#type' => 'hidden',
01326 '#value' => $position,
01327 );
01328
01329 $form['start_form'] = array('#value' => '<div class="modal-form">');
01330
01331 $form['description'] = array(
01332 '#prefix' => '<div class="description">',
01333 '#suffix' => '</div>',
01334 '#value' => check_plain($argument['description']),
01335 );
01336
01337
01338 $form['argument']['#tree'] = TRUE;
01339 $form['argument']['name'] = array(
01340 '#type' => 'hidden',
01341 '#value' => $argument['name'],
01342 );
01343
01344 $form['argument']['default'] = array(
01345 '#type' => 'select',
01346 '#title' => t('Default'),
01347 '#options' => array(
01348 'ignore' => t('Ignore it; content that requires this context will not be available.'),
01349 '404' => t('Display page not found.'),
01350 ),
01351 '#default_value' => $arg['default'],
01352 '#description' => t('If the argument is missing or is not valid, select how this should behave.'),
01353 );
01354
01355 $form['argument']['title'] = array(
01356 '#type' => 'textfield',
01357 '#title' => t('Title'),
01358 '#default_value' => $arg['title'],
01359 '#description' => t('Enter a title to use when this argument is present. You may use %KEYWORD substitution, where the keyword is specified by the administrator.'),
01360 );
01361
01362 $form['argument']['id'] = array(
01363 '#type' => 'value',
01364 '#value' => $arg['id'],
01365 );
01366
01367 $form['argument']['identifier'] = array(
01368 '#type' => 'textfield',
01369 '#title' => t('Identifier'),
01370 '#description' => t('Enter a name to identify this !type on administrative screens.', array('!type' =>t('argument'))),
01371 '#default_value' => $arg['identifier'],
01372 );
01373
01374 $form['argument']['keyword'] = array(
01375 '#type' => 'textfield',
01376 '#title' => t('Keyword'),
01377 '#description' => t('Enter a keyword to use for substitution in titles.'),
01378 '#default_value' => $arg['keyword'],
01379 );
01380
01381
01382 $argument_settings = array();
01383 if (isset($arg['argument_settings'])) {
01384 $argument_settings = $arg['argument_settings'];
01385 }
01386
01387 $form['arg'] = array(
01388 '#type' => 'value',
01389 '#value' => $argument,
01390 );
01391
01392 if (isset($argument['settings form']) && function_exists($argument['settings form'])) {
01393 $form['argument']['argument_settings'] = $argument['settings form']($argument_settings);
01394 $form['argument']['argument_settings']['#tree'] = TRUE;
01395 }
01396
01397 $form['end_form'] = array('#value' => '</div>');
01398
01399 $form['next'] = array(
01400 '#type' => 'submit',
01401 '#value' => t('Save'),
01402 );
01403
01404 return $form;
01405 }
01406
01407
01408
01409
01410 function panels_common_edit_argument_form_validate($form_id, $form_values, $form) {
01411 $argument = $form_values['arg'];
01412
01413 if (isset($argument['settings form validate']) && function_exists($argument['settings form validate'])) {
01414 $argument['settings form validate']($form['argument']['argument_settings'], $form_values['argument']['argument_settings']);
01415 }
01416 }
01417
01418
01419
01420
01421 function panels_common_edit_argument_form_submit($form_id, $form_values) {
01422 $argument = $form_values['arg'];
01423 $position = $form_values['position'];
01424
01425 if (isset($argument['settings form submit']) && function_exists($argument['settings form submit'])) {
01426 $argument['settings form submit']($form_values['argument']['argument_settings']);
01427 }
01428
01429
01430 return $form_values['argument'];
01431 }
01432
01433
01434
01435 function panels_common_save_context($type, &$ref, $form_values) {
01436
01437 $ref = array();
01438 if (isset($form_values[$type . '_order']) && $form_values[$type . '_order'] !== '') {
01439 foreach (explode(',', $form_values[$type . '_order']) as $position) {
01440
01441 $ref[$position] = $form_values[$type . 's'][$position];
01442 }
01443 }
01444 }
01445
01446
01447
01448
01449
01450
01451
01452
01453
01454 function panels_common_ajax($module = NULL, $data = NULL, $info = NULL, $info2 = NULL) {
01455 switch ($module) {
01456 case 'edit':
01457 return panels_common_ajax_context_item_edit($data, $info, $info2);
01458
01459 case 'add':
01460 return panels_common_ajax_context_item_add($data, $info, $info2);
01461
01462 case 'panel_settings':
01463 return panels_common_panel_settings_ajax($data, $info);
01464
01465 default:
01466 panels_ajax_render(t('An error occurred'), t('Error'));
01467 }
01468 }
01469
01470
01471 function panels_common_get_arg_id($arguments, $name) {
01472
01473 $id = 0;
01474 foreach ($arguments as $arg) {
01475 if ($arg['name'] == $name) {
01476 if ($arg['id'] > $id) {
01477 $id = $arg['id'];
01478 }
01479 }
01480 }
01481 return $id;
01482 }
01483
01484 function panels_common_get_keyword($page, $word) {
01485
01486 $keywords = array();
01487 foreach (array('arguments', 'relationships', 'contexts', 'requiredcontexts') as $type) {
01488 if (!empty($page->$type) && is_array($page->$type)) {
01489 foreach ($page->$type as $info) {
01490 $keywords[$info['keyword']] = TRUE;
01491 }
01492 }
01493 }
01494
01495 $keyword = $word;
01496 $count = 0;
01497 while ($keywords[$keyword]) {
01498 $keyword = $word . '_' . ++$count;
01499 }
01500 return $keyword;
01501 }
01502
01503
01504
01505
01506
01507 function theme_panels_common_content_list($display) {
01508 $layout = panels_get_layout($display->layout);
01509 $content = '<dl class="content-list">';
01510 foreach (panels_get_panels($layout, $display) as $panel_id => $title) {
01511 $content .= "<dt>$title</dt><dd>";
01512 if ($display->panels[$panel_id]) {
01513 $content .= '<ol>';
01514 foreach ($display->panels[$panel_id] as $pid) {
01515 $content .= '<li>' . panels_get_pane_title($display->content[$pid], $display->context) . '</li>';
01516 }
01517 $content .= '</ol>';
01518 }
01519 else {
01520 $content .= t('Empty');
01521 }
01522 $content .= '</dd>';
01523 }
01524 $content .= '</dl>';
01525 return $content;
01526 }
01527
01528
01529
01530
01531
01532
01533
01534 function theme_panels_common_context_list($object) {
01535 $titles = array();
01536 $output = '';
01537 $count = 1;
01538
01539 if (!empty($object->arguments)) {
01540 foreach ($object->arguments as $argument) {
01541 $output .= '<tr>';
01542 $output .= '<td><em>' . t('Argument @count', array('@count' => $count)) . '</em></td>';
01543 $output .= '<td>' . check_plain($argument['identifier']) . '</td>';
01544 $output .= '</tr>';
01545 $titles[panels_argument_context_id($argument)] = $argument['identifier'];
01546 $count++;
01547 }
01548 }
01549 $count = 1;
01550
01551 if (!empty($object->contexts)) {
01552 foreach ($object->contexts as $context) {
01553 $output .= '<tr>';
01554 $output .= '<td><em>' . t('Context @count', array('@count' => $count)) . '</em></td>';
01555 $output .= '<td>' . check_plain($context['identifier']) . '</td>';
01556 $output .= '</tr>';
01557 $titles[panels_context_context_id($context)] = $context['identifier'];
01558 $count++;
01559 }
01560 }
01561
01562 if (!empty($object->relationships)) {
01563 foreach ($object->relationships as $relationship) {
01564 $output .= '<tr>';
01565 $output .= '<td><em>' . t('From @title', array('@title' => $titles[$relationship['context']])) . '</em></td>';
01566 $output .= '<td>' . check_plain($relationship['identifier']) . '</td>';
01567 $output .= '</tr>';
01568 $titles[panels_relationship_context_id($relationship)] = $relationship['identifier'];
01569 $count++;
01570 }
01571 }
01572 if ($output) {
01573 return "<table><tbody>$output</tbody></table>\n";
01574 }
01575 }
01576