Projet

Général

Profil

Paste
Télécharger (64,8 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / panels / plugins / display_renderers / panels_renderer_editor.class.php @ c06bd9a4

1 85ad3d82 Assos Assos
<?php
2
3
/**
4
 * @file
5
 * Class file to control the main Panels editor.
6
 */
7
class panels_renderer_editor extends panels_renderer_standard {
8
9
  /**
10
   * An array of AJAX commands to return. If populated it will automatically
11
   * be used by the AJAX router.
12
   */
13
  var $commands = array();
14
  var $admin = TRUE;
15
16
  /**
17
   * Set to true if edit links (for panes and regions) should not be displayed.
18
   * This can be used for special edit modes such as layout change and layout
19
   * builder that do not actually have real content.
20
   */
21
  var $no_edit_links = FALSE;
22 64156087 Assos Assos
  // -------------------------------------------------------------------------.
23
  /**
24
   * Display edit rendering.
25
   */
26 85ad3d82 Assos Assos
27
  function edit() {
28
    $form_state = array(
29
      'display' => &$this->display,
30
      'renderer' => &$this,
31
      'content_types' => $this->cache->content_types,
32
      'no_redirect' => TRUE,
33
      'display_title' => !empty($this->cache->display_title),
34
      'cache key' => $this->display->cache_key,
35
    );
36
37
    $output = drupal_build_form('panels_edit_display_form', $form_state);
38
    if (empty($form_state['executed']) || !empty($form_state['clicked_button']['preview'])) {
39
      return $output;
40
    }
41
42
    if (!empty($form_state['clicked_button']['#save-display'])) {
43
      drupal_set_message(t('Panel content has been updated.'));
44
      panels_save_display($this->display);
45
    }
46
    else {
47
      drupal_set_message(t('Your changes have been discarded.'));
48
    }
49
50
    panels_cache_clear('display', $this->display->did);
51
    return $this->display;
52
  }
53
54
  function add_meta() {
55
    parent::add_meta();
56
    if ($this->admin) {
57
      ctools_include('ajax');
58
      ctools_include('modal');
59
      ctools_modal_add_js();
60
61
      ctools_add_js('panels-base', 'panels');
62
      ctools_add_js('display_editor', 'panels');
63
      ctools_add_css('panels_dnd', 'panels');
64
      ctools_add_css('panels_admin', 'panels');
65 136a805a Assos Assos
      drupal_add_library('system', 'ui');
66 85ad3d82 Assos Assos
    }
67
  }
68
69
  function render() {
70
    // Pass through to normal rendering if not in admin mode.
71
    if (!$this->admin) {
72
      return parent::render();
73
    }
74
75
    $this->add_meta();
76
77
    $output = '<div class="panels-dnd" id="panels-dnd-main">';
78
    $output .= $this->render_layout();
79
    $output .= '</div>';
80
81
    return $output;
82
  }
83
84
  function render_region($region_id, $panes) {
85
    // Pass through to normal rendering if not in admin mode.
86
    if (!$this->admin) {
87
      return parent::render_region($region_id, $panes);
88
    }
89
90
    $content = implode('', $panes);
91
92
    $panel_buttons = $this->get_region_links($region_id);
93
94
    $output = "<div class='panel-region' id='panel-region-$region_id'>";
95
    $output .= $panel_buttons;
96
    $output .= "<h2 class='label'>" . check_plain($this->plugins['layout']['regions'][$region_id]) . "</h2>";
97
    $output .= $content;
98
    $output .= "</div>";
99
100
    return $output;
101
  }
102
103
  function render_pane(&$pane) {
104
    // Pass through to normal rendering if not in admin mode.
105
    if (!$this->admin) {
106
      return parent::render_pane($pane);
107
    }
108
109
    ctools_include('content');
110
    $content_type = ctools_get_content_type($pane->type);
111
112
    // This is just used for the title bar of the pane, not the content itself.
113
    // If we know the content type, use the appropriate title for that type,
114
    // otherwise, set the title using the content itself.
115
    $title = ctools_content_admin_title($content_type, $pane->subtype, $pane->configuration, $this->display->context);
116
    if (!$title) {
117
      $title = t('Deleted/missing content type @type', array('@type' => $pane->type));
118
    }
119
120
    $buttons = $this->get_pane_links($pane, $content_type);
121
122
    // Render administrative buttons for the pane.
123
    $block = new stdClass();
124
    if (empty($content_type)) {
125
      $block->title = '<em>' . t('Missing content type') . '</em>';
126
      $block->content = t('This pane\'s content type is either missing or has been deleted. This pane will not render.');
127
    }
128
    else {
129
      $block = ctools_content_admin_info($content_type, $pane->subtype, $pane->configuration, $this->display->context);
130
    }
131
132
    $grabber_class = 'grab-title grabber';
133
    // If there are region locks, add them.
134
    if (!empty($pane->locks['type'])) {
135
      if ($pane->locks['type'] == 'regions') {
136
        $settings['Panels']['RegionLock'][$pane->pid] = $pane->locks['regions'];
137
        drupal_add_js($settings, 'setting');
138
      }
139 64156087 Assos Assos
      elseif ($pane->locks['type'] == 'immovable') {
140 85ad3d82 Assos Assos
        $grabber_class = 'grab-title not-grabber';
141
      }
142
    }
143
144
    $output = '';
145
    $class = 'panel-pane';
146
147
    if (empty($pane->shown)) {
148
      $class .= ' hidden-pane';
149
    }
150
151
    if (isset($this->display->title_pane) && $this->display->title_pane == $pane->pid) {
152
      $class .= ' panel-pane-is-title';
153
    }
154
155
    $output = '<div class="' . $class . '" id="panel-pane-' . $pane->pid . '">';
156
157 5a7e6170 Florent Torregrosa
    if (empty($block->title)) {
158 85ad3d82 Assos Assos
      $block->title = t('No title');
159
    }
160
161
    $output .= '<div class="' . $grabber_class . '">';
162
    if ($buttons) {
163
      $output .= '<span class="buttons">' . $buttons . '</span>';
164
    }
165 e4c061ad Assos Assos
    $output .= '<span class="text" title="' . check_plain($title) . '">' . $title . '</span>';
166 64156087 Assos Assos
    $output .= '</div>';
167
    // Grabber.
168 85ad3d82 Assos Assos
    $output .= '<div class="panel-pane-collapsible">';
169
    $output .= '<div class="pane-title">' . $block->title . '</div>';
170
    $output .= '<div class="pane-content">' . filter_xss_admin(render($block->content)) . '</div>';
171 64156087 Assos Assos
    $output .= '</div>';
172
    // panel-pane-collapsible.
173
    $output .= '</div>';
174
    // panel-pane.
175 85ad3d82 Assos Assos
    return $output;
176
  }
177
178
  /**
179
   * Get the style links.
180
   *
181
   * This is abstracted out since we have styles on both panes and regions.
182
   */
183
  function get_style_links($type, $id = NULL) {
184
    $info = $this->get_style($type, $id);
185
    $style = $info[0];
186
    $conf = $info[1];
187
188
    $style_title = isset($style['title']) ? $style['title'] : t('Default');
189
190 5a7e6170 Florent Torregrosa
    $style_links['title'] = array(
191 85ad3d82 Assos Assos
      'title' => $style_title,
192
      'attributes' => array('class' => array('panels-text')),
193
    );
194
195 5a7e6170 Florent Torregrosa
    $style_links['change'] = array(
196 85ad3d82 Assos Assos
      'title' => t('Change'),
197
      'href' => $this->get_url('style-type', $type, $id),
198
      'attributes' => array('class' => array('ctools-use-modal')),
199
    );
200
201
    $function = $type != 'pane' ? 'settings form' : 'pane settings form';
202
    if (panels_plugin_get_function('styles', $style, $function)) {
203 5a7e6170 Florent Torregrosa
      $style_links['settings'] = array(
204 85ad3d82 Assos Assos
        'title' => t('Settings'),
205
        'href' => $this->get_url('style-settings', $type, $id),
206
        'attributes' => array('class' => array('ctools-use-modal')),
207
      );
208
    }
209
210
    return $style_links;
211
  }
212
213
  /**
214
   * Get the links for a panel display.
215
   *
216
   * This is abstracted out for easy ajax replacement.
217
   */
218
  function get_display_links() {
219
    $links = array();
220
221 08475715 Assos Assos
    if (user_access('administer panels display styles')) {
222 85ad3d82 Assos Assos
      $style_links = $this->get_style_links('display');
223
      $links[] = array(
224
        'title' => '<span class="dropdown-header">' . t('Style') . '</span>' . theme_links(array('links' => $style_links, 'attributes' => array(), 'heading' => array())),
225
        'html' => TRUE,
226
        'attributes' => array('class' => array('panels-sub-menu')),
227
      );
228
    }
229
230
    if (user_access('use panels caching features')) {
231
      $links[] = array(
232
        'title' => '<hr />',
233
        'html' => TRUE,
234
      );
235
236
      $method = isset($this->display->cache['method']) ? $this->display->cache['method'] : 0;
237
      $info = panels_get_cache($method);
238
      $cache_method = isset($info['title']) ? $info['title'] : t('No caching');
239
240
      $cache_links[] = array(
241
        'title' => $cache_method,
242
        'attributes' => array('class' => array('panels-text')),
243
      );
244
      $cache_links[] = array(
245
        'title' => t('Change'),
246
        'href' => $this->get_url('cache-method', 'display'),
247
        'attributes' => array('class' => array('ctools-use-modal')),
248
      );
249
      if (panels_plugin_get_function('cache', $info, 'settings form')) {
250
        $cache_links[] = array(
251
          'title' => t('Settings'),
252
          'href' => $this->get_url('cache-settings', 'display'),
253
          'attributes' => array('class' => array('ctools-use-modal')),
254
        );
255
      }
256
257
      $links[] = array(
258
        'title' => '<span class="dropdown-header">' . t('Caching') . '</span>' . theme_links(array('links' => $cache_links, 'attributes' => array(), 'heading' => array())),
259
        'html' => TRUE,
260
        'attributes' => array('class' => array('panels-sub-menu')),
261
      );
262
    }
263
264
    return theme('ctools_dropdown', array('title' => t('Display settings'), 'links' => $links, 'class' => 'panels-display-links'));
265
  }
266
267
  /**
268
   * Render the links to display when editing a region.
269
   */
270
  function get_region_links($region_id) {
271
    if (!empty($this->no_edit_links)) {
272
      return '';
273
    }
274
    $links = array();
275
    $links[] = array(
276
      'title' => t('Add content'),
277
      'href' => $this->get_url('select-content', $region_id),
278
      'attributes' => array(
279
        'class' => array('ctools-use-modal'),
280
      ),
281
    );
282
283 08475715 Assos Assos
    if (user_access('administer panels region styles')) {
284 85ad3d82 Assos Assos
      $links[] = array(
285
        'title' => '<hr />',
286
        'html' => TRUE,
287
      );
288
289
      $style_links = $this->get_style_links('region', $region_id);
290
291
      $links[] = array(
292
        'title' => '<span class="dropdown-header">' . t('Style') . '</span>' . theme_links(array('links' => $style_links, 'attributes' => array(), 'heading' => array())),
293
        'html' => TRUE,
294
        'attributes' => array('class' => array('panels-sub-menu')),
295
      );
296
    }
297
298
    return theme('ctools_dropdown', array('title' => theme('image', array('path' => ctools_image_path('icon-addcontent.png', 'panels'))), 'links' => $links, 'image' => TRUE, 'class' => 'pane-add-link panels-region-links-' . $region_id));
299
  }
300
301
  /**
302
   * Render the links to display when editing a pane.
303
   */
304
  function get_pane_links($pane, $content_type) {
305
    if (!empty($this->no_edit_links)) {
306
      return '';
307
    }
308
    $links = array();
309
310
    if (!empty($pane->shown)) {
311 5a7e6170 Florent Torregrosa
      $links['top']['disabled'] = array(
312 85ad3d82 Assos Assos
        'title' => t('Disable this pane'),
313
        'href' => $this->get_url('hide', $pane->pid),
314
        'attributes' => array('class' => array('use-ajax')),
315
      );
316
    }
317
    else {
318 5a7e6170 Florent Torregrosa
      $links['top']['enable'] = array(
319 85ad3d82 Assos Assos
        'title' => t('Enable this pane'),
320
        'href' => $this->get_url('show', $pane->pid),
321
        'attributes' => array('class' => array('use-ajax')),
322
      );
323
    }
324
325
    if (isset($this->display->title_pane) && $this->display->title_pane == $pane->pid) {
326 5a7e6170 Florent Torregrosa
      $links['top']['panels-set-title'] = array(
327 85ad3d82 Assos Assos
        'title' => t('&#x2713;Panel title'),
328
        'html' => TRUE,
329
      );
330
    }
331
    else {
332 5a7e6170 Florent Torregrosa
      $links['top']['panels-set-title'] = array(
333 85ad3d82 Assos Assos
        'title' => t('Panel title'),
334
        'href' => $this->get_url('panel-title', $pane->pid),
335
        'attributes' => array('class' => array('use-ajax')),
336
      );
337
    }
338
339
    $subtype = ctools_content_get_subtype($content_type, $pane->subtype);
340
341
    if (ctools_content_editable($content_type, $subtype, $pane->configuration)) {
342 5a7e6170 Florent Torregrosa
      $links['top']['settings'] = array(
343 85ad3d82 Assos Assos
        'title' => isset($content_type['edit text']) ? $content_type['edit text'] : t('Settings'),
344
        'href' => $this->get_url('edit-pane', $pane->pid),
345
        'attributes' => array('class' => array('ctools-use-modal')),
346
      );
347
    }
348
349
    if (user_access('administer advanced pane settings')) {
350 5a7e6170 Florent Torregrosa
      $links['top']['css'] = array(
351 85ad3d82 Assos Assos
        'title' => t('CSS properties'),
352
        'href' => $this->get_url('pane-css', $pane->pid),
353
        'attributes' => array('class' => array('ctools-use-modal')),
354
      );
355
    }
356
357
    if (user_access('administer panels styles')) {
358 5a7e6170 Florent Torregrosa
      $links['style'] = $this->get_style_links('pane', $pane->pid);
359 85ad3d82 Assos Assos
    }
360
361
    if (user_access('administer pane access')) {
362
      $contexts = $this->display->context;
363 64156087 Assos Assos
      // Make sure we have the logged in user context.
364 85ad3d82 Assos Assos
      if (!isset($contexts['logged-in-user'])) {
365
        $contexts['logged-in-user'] = ctools_access_get_loggedin_context();
366
      }
367
368
      $visibility_links = array();
369
370
      if (!empty($pane->access['plugins'])) {
371
        foreach ($pane->access['plugins'] as $id => $test) {
372
          $plugin = ctools_get_access_plugin($test['name']);
373 5a7e6170 Florent Torregrosa
          $access_title = isset($plugin['title']) ? $plugin['title'] : t('Broken/missing access plugin %plugin', array('%plugin' => $test['name']));
374 85ad3d82 Assos Assos
          $access_description = ctools_access_summary($plugin, $contexts, $test);
375
376
          $visibility_links[] = array(
377
            'title' => $access_description,
378
            'href' => $this->get_url('access-configure-test', $pane->pid, $id),
379
            'attributes' => array('class' => array('ctools-use-modal', 'panels-italic')),
380
          );
381
        }
382
      }
383
      if (empty($visibility_links)) {
384 5a7e6170 Florent Torregrosa
        $visibility_links['no_rules'] = array(
385 85ad3d82 Assos Assos
          'title' => t('No rules'),
386
          'attributes' => array('class' => array('panels-text')),
387
        );
388
      }
389
390 5a7e6170 Florent Torregrosa
      $visibility_links['add_rule'] = array(
391 85ad3d82 Assos Assos
        'title' => t('Add new rule'),
392
        'href' => $this->get_url('access-add-test', $pane->pid),
393
        'attributes' => array('class' => array('ctools-use-modal')),
394
      );
395
396 5a7e6170 Florent Torregrosa
      $visibility_links['settings'] = array(
397 85ad3d82 Assos Assos
        'title' => t('Settings'),
398
        'href' => $this->get_url('access-settings', $pane->pid),
399
        'attributes' => array('class' => array('ctools-use-modal')),
400
      );
401
402 5a7e6170 Florent Torregrosa
      $links['visibility'] = $visibility_links;
403 85ad3d82 Assos Assos
    }
404
405
    if (user_access('use panels locks')) {
406
      $lock_type = !empty($pane->locks['type']) ? $pane->locks['type'] : 'none';
407
      switch ($lock_type) {
408
        case 'immovable':
409
          $lock_method = t('Immovable');
410
          break;
411 64156087 Assos Assos
412 85ad3d82 Assos Assos
        case 'regions':
413
          $lock_method = t('Regions');
414
          break;
415 64156087 Assos Assos
416 85ad3d82 Assos Assos
        case 'none':
417
        default:
418
          $lock_method = t('No lock');
419
          break;
420
      }
421
422 5a7e6170 Florent Torregrosa
      $lock_links['lock'] = array(
423 85ad3d82 Assos Assos
        'title' => $lock_method,
424
        'attributes' => array('class' => array('panels-text')),
425
      );
426 5a7e6170 Florent Torregrosa
      $lock_links['change'] = array(
427 85ad3d82 Assos Assos
        'title' => t('Change'),
428
        'href' => $this->get_url('lock', $pane->pid),
429
        'attributes' => array('class' => array('ctools-use-modal')),
430
      );
431
432 5a7e6170 Florent Torregrosa
      $links['lock'] = $lock_links;
433 85ad3d82 Assos Assos
    }
434
435
    if (panels_get_caches() && user_access('use panels caching features')) {
436
      $method = isset($pane->cache['method']) ? $pane->cache['method'] : 0;
437
      $info = panels_get_cache($method);
438
      $cache_method = isset($info['title']) ? $info['title'] : t('No caching');
439 5a7e6170 Florent Torregrosa
      $cache_links['title'] = array(
440 85ad3d82 Assos Assos
        'title' => $cache_method,
441
        'attributes' => array('class' => array('panels-text')),
442
      );
443 5a7e6170 Florent Torregrosa
      $cache_links['change'] = array(
444 85ad3d82 Assos Assos
        'title' => t('Change'),
445
        'href' => $this->get_url('cache-method', $pane->pid),
446
        'attributes' => array('class' => array('ctools-use-modal')),
447
      );
448
      if (panels_plugin_get_function('cache', $info, 'settings form')) {
449 5a7e6170 Florent Torregrosa
        $cache_links['settings'] = array(
450 85ad3d82 Assos Assos
          'title' => t('Settings'),
451
          'href' => $this->get_url('cache-settings', $pane->pid),
452
          'attributes' => array('class' => array('ctools-use-modal')),
453
        );
454
      }
455
456 5a7e6170 Florent Torregrosa
      $links['cache'] = $cache_links;
457 85ad3d82 Assos Assos
    }
458
459 5a7e6170 Florent Torregrosa
    $links['bottom']['remove'] = array(
460 85ad3d82 Assos Assos
      'title' => t('Remove'),
461
      'href' => '#',
462
      'attributes' => array(
463
        'class' => array('pane-delete'),
464
        'id' => "pane-delete-panel-pane-$pane->pid",
465
      ),
466
    );
467
468 5a7e6170 Florent Torregrosa
    // Allow others to add/remove links from pane context menu.
469 64156087 Assos Assos
    // Grouped by 'top', 'style', 'visibility', 'lock', 'cache' and 'bottom'.
470 5a7e6170 Florent Torregrosa
    drupal_alter('get_pane_links', $links, $pane, $content_type);
471
472
    $dropdown_links = $links['top'];
473 e4c061ad Assos Assos
    $category_labels = array(
474
      'style' => 'Style',
475
      'visibility' => 'Visibility rules',
476
      'lock' => 'Locking',
477
      'cache' => 'Caching',
478
    );
479
    foreach ($category_labels as $category => $label) {
480
      if (array_key_exists($category, $links)) {
481
        $dropdown_links[] = array(
482
          'title' => '<hr />',
483
          'html' => TRUE,
484
        );
485
        $dropdown_links[] = array(
486
          'title' => '<span class="dropdown-header">' . t($label) . '</span>' . theme_links(array('links' => $links[$category], 'attributes' => array(), 'heading' => array())),
487
          'html' => TRUE,
488
          'attributes' => array('class' => array('panels-sub-menu')),
489
        );
490
      }
491 5a7e6170 Florent Torregrosa
    }
492
493
    $dropdown_links[] = array(
494
      'title' => '<hr />',
495
      'html' => TRUE,
496
    );
497
    $dropdown_links = array_merge($dropdown_links, $links['bottom']);
498
499
    return theme('ctools_dropdown', array('title' => theme('image', array('path' => ctools_image_path('icon-configure.png', 'panels'))), 'links' => $dropdown_links, 'image' => TRUE));
500 85ad3d82 Assos Assos
  }
501
502
  // -----------------------------------------------------------------------
503
  // Display edit AJAX callbacks and helpers.
504
  /**
505
   * Generate a URL path for the AJAX editor.
506
   */
507
  function get_url() {
508
    $args = func_get_args();
509
    $command = array_shift($args);
510
    $url = 'panels/ajax/' . $this->plugin['name'] . '/' . $command . '/' . $this->display->cache_key;
511
    if ($args) {
512
      $url .= '/' . implode('/', $args);
513
    }
514
515
    return $url;
516
  }
517
518 136a805a Assos Assos
  /**
519
   * Get the Panels storage oparation for a given renderer AJAX method.
520
   *
521
   * @param string $method
522
   *   The method name.
523
   *
524
   * @return string
525
   *   The Panels storage op.
526
   */
527
  function get_panels_storage_op_for_ajax($method) {
528
    switch ($method) {
529
      case 'ajax_show':
530
      case 'ajax_hide':
531
      case 'ajax_select_content':
532
      case 'ajax_add_pane':
533
      case 'ajax_edit_pane':
534
      case 'ajax_panel_title':
535
      case 'ajax_cache_method':
536
      case 'ajax_cache_settings':
537
      case 'ajax_style_type':
538
      case 'ajax_style_settings':
539
      case 'ajax_pane_css':
540
      case 'ajax_lock':
541
      case 'ajax_access_settings':
542
      case 'ajax_access_add_test':
543
      case 'ajax_access_configure_test':
544
      case 'ajax_layout':
545
      case 'ajax_style':
546
        return 'update';
547
    }
548
549 2545992a Assos Assos
    return parent::get_panels_storage_op_for_ajax($method);
550 136a805a Assos Assos
  }
551
552 85ad3d82 Assos Assos
  /**
553
   * AJAX command to show a pane.
554
   */
555
  function ajax_show($pid = NULL) {
556
    if (empty($this->display->content[$pid])) {
557
      ctools_ajax_render_error(t('Invalid pane id.'));
558
    }
559
560
    $this->display->content[$pid]->shown = TRUE;
561
    panels_edit_cache_set($this->cache);
562
563
    $this->command_update_pane($pid);
564
  }
565
566
  /**
567
   * AJAX command to show a pane.
568
   */
569
  function ajax_hide($pid = NULL) {
570
    if (empty($this->display->content[$pid])) {
571
      ctools_ajax_render_error(t('Invalid pane id.'));
572
    }
573
574
    $this->display->content[$pid]->shown = FALSE;
575
    panels_edit_cache_set($this->cache);
576
577
    $this->command_update_pane($pid);
578
  }
579
580
  /**
581
   * AJAX command to present a dialog with a list of available content.
582
   */
583
  function ajax_select_content($region = NULL, $category = NULL) {
584
    if (!array_key_exists($region, $this->plugins['layout']['regions'])) {
585
      ctools_modal_render(t('Error'), t('Invalid input'));
586
    }
587
588
    $title = t('Add content to !s', array('!s' => $this->plugins['layout']['regions'][$region]));
589
590
    $categories = $this->get_categories($this->cache->content_types);
591
592
    if (empty($categories)) {
593
      $output = t('There are no content types you may add to this display.');
594
    }
595
    else {
596
      $output = theme('panels_add_content_modal', array('renderer' => $this, 'categories' => $categories, 'category' => $category, 'region' => $region));
597
    }
598
    $this->commands[] = ctools_modal_command_display($title, $output);
599 136a805a Assos Assos
600
    // Give keybord focus to the first item in the category we just loaded.
601
    if (!empty($category)) {
602
      $this->commands[] = ajax_command_invoke(".panels-add-content-modal .panels-section-columns :focusable:first", 'focus');
603
    }
604 85ad3d82 Assos Assos
  }
605
606
  /**
607
   * Return the category name and the category key of a given content
608
   * type.
609
   *
610
   * @todo -- this should be in CTools.
611
   */
612
  function get_category($content_type) {
613 5a7e6170 Florent Torregrosa
    if (!empty($content_type['top level'])) {
614 85ad3d82 Assos Assos
      $category = 'root';
615
    }
616 64156087 Assos Assos
    elseif (isset($content_type['category'])) {
617 85ad3d82 Assos Assos
      if (is_array($content_type['category'])) {
618 c06bd9a4 Assos Assos
        $category = reset($content_type['category']);
619 85ad3d82 Assos Assos
      }
620
      else {
621
        $category = $content_type['category'];
622
      }
623
    }
624
    else {
625
      $category = t('Uncategorized');
626
    }
627
628
    return array(preg_replace('/[^a-z0-9]/', '-', strtolower($category)), $category);
629
  }
630
631
632
  /**
633
   * Create a list of categories from all of the content type.
634
   *
635
   * @return array
636
   *   An array of categories. Each entry in the array will also be an array
637
   *   with 'title' as the printable title of the category, and 'content'
638
   *   being an array of all content in the category. Each item in the 'content'
639
   *   array contain the array plugin definition so that it can be later
640
   *   found in the content array. They will be keyed by the title so that they
641
   *   can be sorted.
642
   */
643
  function get_categories($content_types) {
644
    $categories = array();
645
    $category_names = array();
646
647
    foreach ($content_types as $type_name => $subtypes) {
648
      foreach ($subtypes as $subtype_name => $content_type) {
649
        list($category_key, $category) = $this->get_category($content_type);
650
651
        if (empty($categories[$category_key])) {
652
          $categories[$category_key] = array(
653
            'title' => $category,
654
            'content' => array(),
655
          );
656
          $category_names[$category_key] = $category;
657
        }
658
659
        $content_title = filter_xss_admin($content_type['title']);
660
661
        // Ensure content with the same title doesn't overwrite each other.
662
        while (isset($categories[$category_key]['content'][$content_title])) {
663
          $content_title .= '-';
664
        }
665
666
        $categories[$category_key]['content'][$content_title] = $content_type;
667
        $categories[$category_key]['content'][$content_title]['type_name'] = $type_name;
668
        $categories[$category_key]['content'][$content_title]['subtype_name'] = $subtype_name;
669
      }
670
    }
671
672 64156087 Assos Assos
    // Now sort.
673 85ad3d82 Assos Assos
    natcasesort($category_names);
674
    foreach ($category_names as $category => $name) {
675
      $output[$category] = $categories[$category];
676
    }
677
678
    return $output;
679
  }
680
681
  /**
682
   * AJAX entry point to add a new pane.
683
   */
684
  function ajax_add_pane($region = NULL, $type_name = NULL, $subtype_name = NULL, $step = NULL) {
685
    $content_type = ctools_get_content_type($type_name);
686
    $subtype = ctools_content_get_subtype($content_type, $subtype_name);
687
688 5a7e6170 Florent Torregrosa
    // Determine if we are adding a different pane than previously cached. This
689
    // is used to load the different pane into cache so that multistep forms
690
    // have the correct context instead of a previously cached version that
691
    // does not match the pane currently being added.
692
    $is_different_pane = FALSE;
693
    if (isset($this->cache) && isset($this->cache->new_pane)) {
694
      $diff_type = $type_name != $this->cache->new_pane->type;
695
      $diff_subtype = $subtype_name != $this->cache->new_pane->subtype;
696
697
      $is_different_pane = $diff_type || $diff_subtype;
698
    }
699
700
    if (!isset($step) || !isset($this->cache->new_pane) || $is_different_pane) {
701 85ad3d82 Assos Assos
      $pane = panels_new_pane($type_name, $subtype_name, TRUE);
702
      $this->cache->new_pane = &$pane;
703
    }
704
    else {
705
      $pane = &$this->cache->new_pane;
706
    }
707
708
    $form_state = array(
709
      'display' => &$this->cache->display,
710
      'contexts' => $this->cache->display->context,
711
      'pane' => &$pane,
712
      'cache_key' => $this->display->cache_key,
713
      'display cache' => &$this->cache,
714
      'ajax' => TRUE,
715
      'modal' => TRUE,
716
      // This will force the system to not automatically render.
717
      'modal return' => TRUE,
718
      'commands' => array(),
719
    );
720
721
    $form_info = array(
722
      'path' => $this->get_url('add-pane', $region, $type_name, $subtype_name, '%step'),
723
      'show cancel' => TRUE,
724
      'next callback' => 'panels_ajax_edit_pane_next',
725
      'finish callback' => 'panels_ajax_edit_pane_finish',
726
      'cancel callback' => 'panels_ajax_edit_pane_cancel',
727
    );
728
729
    $output = ctools_content_form('add', $form_info, $form_state, $content_type, $pane->subtype, $subtype, $pane->configuration, $step);
730
731
    // If $rc is FALSE, there was no actual form.
732
    if ($output === FALSE || !empty($form_state['complete'])) {
733
      // References get blown away with AJAX caching. This will fix that.
734
      $pane = $form_state['pane'];
735
      unset($this->cache->new_pane);
736
737 64156087 Assos Assos
      // Add the pane to the display.
738 85ad3d82 Assos Assos
      $this->display->add_pane($pane, $region);
739
      panels_edit_cache_set($this->cache);
740
741 64156087 Assos Assos
      // Tell the client to draw the pane.
742 85ad3d82 Assos Assos
      $this->command_add_pane($pane);
743
744
      // Dismiss the modal.
745
      $this->commands[] = ctools_modal_command_dismiss();
746
    }
747 64156087 Assos Assos
    elseif (!empty($form_state['cancel'])) {
748 85ad3d82 Assos Assos
      // If cancelling, return to the activity.
749
      list($category_key, $category) = $this->get_category($subtype);
750
      $this->ajax_select_content($region, $category_key);
751
    }
752
    else {
753
      // This overwrites any previous commands.
754
      $this->commands = ctools_modal_form_render($form_state, $output);
755
    }
756
  }
757
758
  /**
759
   * AJAX entry point to edit a pane.
760
   */
761
  function ajax_edit_pane($pid = NULL, $step = NULL) {
762
    if (empty($this->cache->display->content[$pid])) {
763
      ctools_modal_render(t('Error'), t('Invalid pane id.'));
764
    }
765
766
    $pane = &$this->cache->display->content[$pid];
767
768
    $content_type = ctools_get_content_type($pane->type);
769
    $subtype = ctools_content_get_subtype($content_type, $pane->subtype);
770
771
    $form_state = array(
772
      'display' => &$this->cache->display,
773
      'contexts' => $this->cache->display->context,
774
      'pane' => &$pane,
775
      'display cache' => &$this->cache,
776
      'ajax' => TRUE,
777
      'modal' => TRUE,
778
      'modal return' => TRUE,
779
      'commands' => array(),
780
    );
781
782
    $form_info = array(
783
      'path' => $this->get_url('edit-pane', $pid, '%step'),
784
      'show cancel' => TRUE,
785
      'next callback' => 'panels_ajax_edit_pane_next',
786
      'finish callback' => 'panels_ajax_edit_pane_finish',
787
      'cancel callback' => 'panels_ajax_edit_pane_cancel',
788
    );
789
790 64156087 Assos Assos
    $output = ctools_content_form('edit', $form_info, $form_state, $content_type, $pane->subtype, $subtype, $pane->configuration, $step);
791 85ad3d82 Assos Assos
792
    // If $rc is FALSE, there was no actual form.
793
    if ($output === FALSE || !empty($form_state['cancel'])) {
794
      // Dismiss the modal.
795
      $this->commands[] = ctools_modal_command_dismiss();
796
    }
797 64156087 Assos Assos
    elseif (!empty($form_state['complete'])) {
798 85ad3d82 Assos Assos
      // References get blown away with AJAX caching. This will fix that.
799
      $this->cache->display->content[$pid] = $form_state['pane'];
800
801 5a7e6170 Florent Torregrosa
      // Conditionally overwrite the context for this panel if present in the form state.
802
      if (!empty($form_state['display_cache']->display->context)) {
803
        $this->cache->display->context = $form_state['display_cache']->display->context;
804
      }
805
806 85ad3d82 Assos Assos
      panels_edit_cache_set($this->cache);
807
      $this->command_update_pane($pid);
808
      $this->commands[] = ctools_modal_command_dismiss();
809
    }
810
    else {
811
      // This overwrites any previous commands.
812
      $this->commands = ctools_modal_form_render($form_state, $output);
813
    }
814
  }
815
816
  /**
817
   * AJAX entry point to select which pane is currently the title.
818
   *
819
   * @param string $pid
820
   *   The pane id for the pane object whose title state we're setting.
821
   */
822
  function ajax_panel_title($pid = NULL) {
823
    if (empty($this->display->content[$pid])) {
824
      ctools_ajax_render_error(t('Invalid pane id.'));
825
    }
826
827
    $pane = &$this->display->content[$pid];
828
829
    $old_title = !empty($this->display->title_pane) ? $this->display->title_pane : NULL;
830
    $this->display->title_pane = $pid;
831
832
    panels_edit_cache_set($this->cache);
833
834
    $this->command_update_pane($pane);
835
836
    if ($old_title && !empty($this->cache->display->content[$old_title])) {
837
      $this->command_update_pane($this->cache->display->content[$old_title]);
838
    }
839
  }
840
841
  /**
842
   * AJAX entry point to configure the cache method for a pane or the display.
843
   *
844
   * @param string $pid
845
   *   Either a pane id for a pane in the display, or 'display' to edit the
846
   *   display cache settings.
847
   */
848
  function ajax_cache_method($pid = NULL) {
849
    ctools_include('content');
850
    // This lets us choose whether we're doing the display's cache or
851
    // a pane's.
852
    if ($pid == 'display') {
853
      $conf = &$this->display->cache;
854
      $title = t('Cache method for this display');
855
    }
856 64156087 Assos Assos
    elseif (!empty($this->display->content[$pid])) {
857 85ad3d82 Assos Assos
      $pane = &$this->display->content[$pid];
858
      $subtype = ctools_content_get_subtype($pane->type, $pane->subtype);
859
      $conf = &$pane->cache;
860
      $title = t('Cache method for !subtype_title', array('!subtype_title' => $subtype['title']));
861
    }
862
    else {
863
      ctools_modal_render(t('Error'), t('Invalid pane id.'));
864
    }
865
866
    $form_state = array(
867
      'display' => &$this->display,
868
      'conf' => &$conf,
869
      'title' => $title,
870
      'ajax' => TRUE,
871
    );
872
873
    $output = ctools_modal_form_wrapper('panels_edit_cache_method_form', $form_state);
874
    if (empty($form_state['executed'])) {
875
      $this->commands = $output;
876
      return;
877
    }
878
879
    // Preserve this; this way we don't actually change the method until they
880
    // have saved the form.
881
    $info = panels_get_cache($form_state['method']);
882
    $function = panels_plugin_get_function('cache', $info, 'settings form');
883
    if (!$function) {
884
      $conf['method'] = $form_state['method'];
885
      $conf['settings'] = array();
886
      panels_edit_cache_set($this->cache);
887
888
      $this->commands[] = ctools_modal_command_dismiss();
889
890
      if ($pid != 'display') {
891
        $this->command_update_pane($pane);
892
      }
893
      else {
894
        $this->command_update_display_links();
895
      }
896
    }
897
    else {
898
      $this->cache->method = $form_state['method'];
899
      panels_edit_cache_set($this->cache);
900 64156087 Assos Assos
      // Send them to next form.
901 85ad3d82 Assos Assos
      return $this->ajax_cache_settings($pid);
902
    }
903
  }
904
905
  /**
906
   * AJAX entry point to configure the cache settings for a pane or the display.
907
   *
908
   * @param string $pid
909
   *   Either a pane id for a pane in the display, or 'display' to edit the
910
   *   display cache settings.
911
   */
912
  function ajax_cache_settings($pid = 0) {
913
    ctools_include('content');
914
915
    // This lets us choose whether we're doing the display's cache or
916
    // a pane's.
917
    if ($pid == 'display') {
918
      $conf = &$this->display->cache;
919
      $title = t('Cache settings for this display');
920
    }
921 64156087 Assos Assos
    elseif (!empty($this->display->content[$pid])) {
922 85ad3d82 Assos Assos
      $pane = &$this->display->content[$pid];
923
      $subtype = ctools_content_get_subtype($pane->type, $pane->subtype);
924
925
      $conf = &$pane->cache;
926
      $title = t('Cache settings for !subtype_title', array('!subtype_title' => $subtype['title']));
927
    }
928
    else {
929
      ctools_modal_render(t('Error'), t('Invalid pane id.'));
930
    }
931
932
    if (isset($this->cache->method) && (empty($conf['method']) || $conf['method'] != $this->cache->method)) {
933
      $conf['method'] = $this->cache->method;
934
      $info = panels_get_cache($conf['method']);
935
      $conf['settings'] = isset($info['defaults']) ? $info['defaults'] : array();
936
    }
937
938
    $form_state = array(
939
      'display' => &$this->display,
940
      'pid' => $pid,
941
      'conf' => &$conf,
942
      'ajax' => TRUE,
943
      'title' => $title,
944
      'url' => url($this->get_url('cache-settings', $pid), array('absolute' => TRUE)),
945
    );
946
947
    $output = ctools_modal_form_wrapper('panels_edit_cache_settings_form', $form_state);
948
    if (empty($form_state['executed'])) {
949
      $this->commands = $output;
950
      return;
951
    }
952
953
    panels_edit_cache_set($this->cache);
954
955
    $this->commands[] = ctools_modal_command_dismiss();
956
957
    if ($pid != 'display') {
958
      $this->command_update_pane($pane);
959
    }
960
    else {
961
      $this->command_update_display_links();
962
    }
963
  }
964
965
  /**
966
   * AJAX entry point to select the style for a display, region or pane.
967
   *
968
   * @param string $type
969
   *   Either display, region or pane
970
   * @param $pid
971
   *   The pane id, if a pane. The region id, if a region.
972
   */
973
  function ajax_style_type($type, $pid = NULL) {
974
    // This lets us choose whether we're doing the display's cache or
975
    // a pane's.
976
    switch ($type) {
977
      case 'display':
978
        $style = isset($this->display->panel_settings['style']) ? $this->display->panel_settings['style'] : 'default';
979
        $title = t('Default style for this display');
980
        break;
981
982
      case 'region':
983 64156087 Assos Assos
        $style = isset($this->display->panel_settings[$pid]['style']) ? $this->display->panel_settings[$pid]['style'] : '-1';
984
        // -1 signifies to use the default setting.
985 85ad3d82 Assos Assos
        $title = t('Panel style for region "!region"', array('!region' => $this->plugins['layout']['regions'][$pid]));
986
        break;
987
988
      case 'pane':
989
        ctools_include('content');
990
        $pane = &$this->display->content[$pid];
991
        $style = isset($pane->style['style']) ? $pane->style['style'] : 'default';
992 e4c061ad Assos Assos
        $title = ctools_content_admin_title($pane->type, $pane->subtype, $pane->configuration, $this->display->context);
993
        if (!$title) {
994
          $title = $pane->type;
995
        }
996
        $title = t('Pane style for "!title"', array('!title' => $title));
997 85ad3d82 Assos Assos
        break;
998
999
      default:
1000
        ctools_modal_render(t('Error'), t('Invalid pane id.'));
1001
    }
1002
    $info = $this->get_style($type, $pid);
1003
    $style_plugin = $info[0];
1004
    $style_settings = $info[1];
1005
1006
    // Backward compatibility: Translate old-style stylizer to new style
1007
    // stylizer.
1008
    if ($style == 'stylizer' && !empty($style_settings['style']) && $style_settings['style'] != '$') {
1009
      $style = 'stylizer:' . $style_settings['style'];
1010
    }
1011
1012
    $form_state = array(
1013
      'display' => &$this->display,
1014
      'style' => $style,
1015
      'pane' => ($type == 'pane') ? $this->display->content[$pid] : NULL,
1016
      'title' => $title,
1017
      'ajax' => TRUE,
1018
      'type' => $type,
1019
    );
1020
1021
    $output = ctools_modal_form_wrapper('panels_edit_style_type_form', $form_state);
1022
    if (empty($form_state['executed'])) {
1023
      $this->commands = $output;
1024
      return;
1025
    }
1026
1027
    // Preserve this; this way we don't actually change the method until they
1028
    // have saved the form.
1029
    $style = panels_get_style($form_state['style']);
1030
    $function = panels_plugin_get_function('styles', $style, ($type == 'pane') ? 'pane settings form' : 'settings form');
1031
    if (!$function) {
1032
      if (isset($this->cache->style)) {
1033
        unset($this->cache->style);
1034
      }
1035
1036
      // If there's no settings form, just change the style and exit.
1037 64156087 Assos Assos
      switch ($type) {
1038 85ad3d82 Assos Assos
        case 'display':
1039
          $this->display->panel_settings['style'] = $form_state['style'];
1040
          if (isset($this->display->panel_settings['style_settings']['default'])) {
1041
            unset($this->display->panel_settings['style_settings']['default']);
1042
          }
1043
          break;
1044
1045
        case 'region':
1046
          $this->display->panel_settings[$pid]['style'] = $form_state['style'];
1047
          if (isset($this->display->panel_settings['style_settings'][$pid])) {
1048
            unset($this->display->panel_settings['style_settings'][$pid]);
1049
          }
1050
          break;
1051
1052
        case 'pane':
1053
          $pane->style['style'] = $form_state['style'];
1054
          if (isset($pane->style['settings'])) {
1055 c06bd9a4 Assos Assos
            $pane->style['settings'] = NULL;
1056 85ad3d82 Assos Assos
          }
1057
          break;
1058
      }
1059
      panels_edit_cache_set($this->cache);
1060
1061
      $this->commands[] = ctools_modal_command_dismiss();
1062
1063
      if ($type == 'pane') {
1064
        $this->command_update_pane($pane);
1065
      }
1066 64156087 Assos Assos
      elseif ($type == 'region') {
1067 85ad3d82 Assos Assos
        $this->command_update_region_links($pid);
1068
      }
1069
      else {
1070
        $this->command_update_display_links();
1071
      }
1072
    }
1073
    else {
1074
      if ($form_state['style'] != $form_state['old_style']) {
1075
        $this->cache->style = $form_state['style'];
1076
        panels_edit_cache_set($this->cache);
1077
      }
1078
1079 64156087 Assos Assos
      // Send them to next form.
1080 85ad3d82 Assos Assos
      return $this->ajax_style_settings($type, $pid);
1081
    }
1082
  }
1083
1084
  /**
1085
   * Get the appropriate style from the panel in the cache.
1086
   *
1087
   * Since we have styles for regions, panes and the display itself, and
1088
   * they are stored differently, we use this method to simplify getting
1089
   * style information into a way that's easy to cope with.
1090
   */
1091
  function get_style($type, $pid = '') {
1092
    if (isset($this->cache->style)) {
1093
      $style = panels_get_style($this->cache->style);
1094
      $defaults = isset($style['defaults']) ? $style['defaults'] : array();
1095
      // Get the &$conf variable based upon whose style we're editing.
1096
      switch ($type) {
1097
        case 'display':
1098
          $this->display->panel_settings['style'] = $this->cache->style;
1099
          $this->display->panel_settings['style_settings']['default'] = $defaults;
1100
          break;
1101
1102
        case 'region':
1103
          $this->display->panel_settings[$pid]['style'] = $this->cache->style;
1104
          $this->display->panel_settings['style_settings'][$pid] = $defaults;
1105
          break;
1106
1107
        case 'pane':
1108
          $pane = &$this->display->content[$pid];
1109
          $pane->style['style'] = $this->cache->style;
1110
          $pane->style['settings'] = $defaults;
1111
          $conf = &$pane->style['settings'];
1112
          break;
1113
      }
1114
    }
1115
    else {
1116
      switch ($type) {
1117
        case 'display':
1118
          $style = panels_get_style((!empty($this->display->panel_settings['style'])) ? $this->display->panel_settings['style'] : 'default');
1119
          break;
1120
1121
        case 'region':
1122
          $style = panels_get_style((!empty($this->display->panel_settings[$pid]['style'])) ? $this->display->panel_settings[$pid]['style'] : '-1');
1123
          break;
1124
1125
        case 'pane':
1126
          $pane = &$this->display->content[$pid];
1127
          $style = panels_get_style(!empty($pane->style['style']) ? $pane->style['style'] : 'default');
1128
          break;
1129
      }
1130
    }
1131
1132
    // Set up our $conf reference.
1133
    switch ($type) {
1134
      case 'display':
1135
        $conf = &$this->display->panel_settings['style_settings']['default'];
1136
        break;
1137
1138
      case 'region':
1139
        $conf = &$this->display->panel_settings['style_settings'][$pid];
1140
        break;
1141
1142
      case 'pane':
1143
        ctools_include('content');
1144
        $pane = &$this->display->content[$pid];
1145
        $conf = &$pane->style['settings'];
1146
        break;
1147
    }
1148
1149
    // Backward compatibility: Translate old-style stylizer to new style
1150
    // stylizer.
1151 c06bd9a4 Assos Assos
    if (isset($style['name']) && $style['name'] == 'stylizer' && !empty($conf['style']) && $conf['style'] != '$') {
1152 85ad3d82 Assos Assos
      $style = panels_get_style('stylizer:' . $conf['style']);
1153
    }
1154
1155
    return array($style, &$conf);
1156
  }
1157
1158
  /**
1159
   * AJAX entry point to configure the style for a display, region or pane.
1160
   *
1161
   * @param string $type
1162
   *   Either display, region or pane
1163
   * @param $pid
1164
   *   The pane id, if a pane. The region id, if a region.
1165
   */
1166
  function ajax_style_settings($type, $pid = '') {
1167
    $info = $this->get_style($type, $pid);
1168
    $style = $info[0];
1169
    $conf = &$info[1];
1170
1171
    switch ($type) {
1172
      case 'display':
1173
        $title = t('Style settings for @style (display)', array('@style' => $style['title']));
1174
        break;
1175
1176
      case 'region':
1177
        $title = t('Style settings for style @style (Region "!region")', array('@style' => $style['title'], '!region' => $this->plugins['layout']['regions'][$pid]));
1178
        break;
1179
1180
      case 'pane':
1181
        ctools_include('content');
1182
        $pane = &$this->display->content[$pid];
1183
        $subtype = ctools_content_get_subtype($pane->type, $pane->subtype);
1184
        $title = t('Style settings for style @style (Pane "!pane")', array('@style' => $style['title'], '!pane' => $subtype['title']));
1185
        break;
1186
    }
1187
1188
    $form_state = array(
1189
      'display' => &$this->display,
1190
      'type' => $type,
1191
      'pid' => $pid,
1192
      'conf' => &$conf,
1193
      'style' => $style,
1194
      'ajax' => TRUE,
1195
      'title' => $title,
1196
      'url' => url($this->get_url('style-settings', $type, $pid), array('absolute' => TRUE)),
1197
      'renderer' => &$this,
1198
    );
1199
1200
    $output = ctools_modal_form_wrapper('panels_edit_style_settings_form', $form_state);
1201
    if (empty($form_state['executed'])) {
1202
      $this->commands = $output;
1203
      return;
1204
    }
1205
1206
    if (isset($this->cache->style)) {
1207
      unset($this->cache->style);
1208
    }
1209
1210 e4c061ad Assos Assos
    if (!empty($form_state['cancel'])) {
1211
      // The cache must be saved prior to dismissing the modal.
1212
      panels_edit_cache_set($this->cache);
1213
      $this->commands[] = ctools_modal_command_dismiss();
1214
      return;
1215
    }
1216
1217 5a7e6170 Florent Torregrosa
    // Copy settings from form state back into the cache.
1218 64156087 Assos Assos
    if (!empty($form_state['values']['settings'])) {
1219 e4c061ad Assos Assos
      if ($type == 'pane') {
1220
        $this->cache->display->content[$pid]->style['settings'] = $form_state['values']['settings'];
1221
      }
1222 64156087 Assos Assos
      elseif ($type == 'region') {
1223 e4c061ad Assos Assos
        $this->cache->display->panel_settings['style_settings'][$pid] = $form_state['values']['settings'];
1224
      }
1225 5a7e6170 Florent Torregrosa
    }
1226
1227 85ad3d82 Assos Assos
    panels_edit_cache_set($this->cache);
1228
1229
    $this->commands[] = ctools_modal_command_dismiss();
1230
1231
    if ($type == 'pane') {
1232
      $this->command_update_pane($pane);
1233
    }
1234 64156087 Assos Assos
    elseif ($type == 'region') {
1235 85ad3d82 Assos Assos
      $this->command_update_region_links($pid);
1236
    }
1237
    else {
1238
      $this->command_update_display_links();
1239
    }
1240
  }
1241
1242
  /**
1243
   * AJAX entry point to configure CSS for a pane.
1244
   *
1245
   * @param $pid
1246
   *   The pane id to edit.
1247
   */
1248
  function ajax_pane_css($pid = NULL) {
1249
    if (empty($this->display->content[$pid])) {
1250
      ctools_modal_render(t('Error'), t('Invalid pane id.'));
1251
    }
1252
1253
    $pane = &$this->display->content[$pid];
1254
    $subtype = ctools_content_get_subtype($pane->type, $pane->subtype);
1255
1256
    $form_state = array(
1257
      'display' => &$this->display,
1258
      'pane' => &$pane,
1259
      'ajax' => TRUE,
1260
      'title' => t('Configure CSS on !subtype_title', array('!subtype_title' => $subtype['title'])),
1261
    );
1262
1263
    $output = ctools_modal_form_wrapper('panels_edit_configure_pane_css_form', $form_state);
1264
    if (empty($form_state['executed'])) {
1265
      $this->commands = $output;
1266
      return;
1267
    }
1268
1269
    panels_edit_cache_set($this->cache);
1270
    $this->command_update_pane($pid);
1271
    $this->commands[] = ctools_modal_command_dismiss();
1272
  }
1273
1274
  /**
1275
   * AJAX entry point to configure CSS for a pane.
1276
   *
1277
   * @param $pid
1278
   *   The pane id to edit.
1279
   */
1280
  function ajax_lock($pid = NULL) {
1281
    if (empty($this->display->content[$pid])) {
1282
      ctools_modal_render(t('Error'), t('Invalid pane id.'));
1283
    }
1284
1285
    $pane = &$this->display->content[$pid];
1286
    $subtype = ctools_content_get_subtype($pane->type, $pane->subtype);
1287
1288
    $form_state = array(
1289
      'display' => &$this->display,
1290
      'pane' => &$pane,
1291
      'ajax' => TRUE,
1292
      'title' => t('Configure lock on !subtype_title', array('!subtype_title' => $subtype['title'])),
1293
    );
1294
1295
    $output = ctools_modal_form_wrapper('panels_edit_configure_pane_lock_form', $form_state);
1296
    if (empty($form_state['executed'])) {
1297
      $this->commands = $output;
1298
      return;
1299
    }
1300
1301
    panels_edit_cache_set($this->cache);
1302
    $this->command_update_pane($pid);
1303
    $this->commands[] = ctools_modal_command_dismiss();
1304
  }
1305
1306
  /**
1307
   * AJAX entry point to configure access settings for a pane.
1308
   *
1309
   * @param $pid
1310
   *   The pane id to edit.
1311
   */
1312
  function ajax_access_settings($pid = NULL) {
1313
    if (empty($this->display->content[$pid])) {
1314
      ctools_modal_render(t('Error'), t('Invalid pane id.'));
1315
    }
1316
1317
    $pane = &$this->display->content[$pid];
1318
    $subtype = ctools_content_get_subtype($pane->type, $pane->subtype);
1319
1320
    $form_state = array(
1321
      'display' => &$this->display,
1322
      'pane' => &$pane,
1323
      'ajax' => TRUE,
1324
      'title' => t('Access settings on !subtype_title', array('!subtype_title' => $subtype['title'])),
1325
    );
1326
1327
    $output = ctools_modal_form_wrapper('panels_edit_configure_access_settings_form', $form_state);
1328
    if (empty($form_state['executed'])) {
1329
      $this->commands = $output;
1330
      return;
1331
    }
1332
1333
    panels_edit_cache_set($this->cache);
1334
    $this->command_update_pane($pid);
1335
    $this->commands[] = ctools_modal_command_dismiss();
1336
  }
1337
1338
  /**
1339
   * AJAX entry point for to add a visibility rule.
1340
   */
1341
  function ajax_access_add_test($pid = NULL) {
1342
    if (empty($this->display->content[$pid])) {
1343
      ctools_modal_render(t('Error'), t('Invalid pane id.'));
1344
    }
1345
1346
    $pane = &$this->display->content[$pid];
1347
    $subtype = ctools_content_get_subtype($pane->type, $pane->subtype);
1348
1349
    $form_state = array(
1350
      'display' => &$this->display,
1351
      'pane' => &$pane,
1352
      'ajax' => TRUE,
1353
      'title' => t('Add visibility rule for !subtype_title', array('!subtype_title' => $subtype['title'])),
1354
    );
1355
1356
    $output = ctools_modal_form_wrapper('panels_edit_add_access_test_form', $form_state);
1357
    if (!empty($form_state['executed'])) {
1358 64156087 Assos Assos
      // Set up the plugin in cache.
1359 85ad3d82 Assos Assos
      $plugin = ctools_get_access_plugin($form_state['values']['type']);
1360
      $this->cache->new_plugin = ctools_access_new_test($plugin);
1361
      panels_edit_cache_set($this->cache);
1362
1363 64156087 Assos Assos
      // Go to the next step.
1364 85ad3d82 Assos Assos
      return $this->ajax_access_configure_test($pid, 'add');
1365
    }
1366
1367
    $this->commands = $output;
1368
  }
1369
1370
  /**
1371
   * AJAX entry point for to configure vsibility rule.
1372
   */
1373
  function ajax_access_configure_test($pid = NULL, $id = NULL) {
1374
    if (empty($this->display->content[$pid])) {
1375
      ctools_modal_render(t('Error'), t('Invalid pane id.'));
1376
    }
1377
1378
    $pane = &$this->display->content[$pid];
1379
    $subtype = ctools_content_get_subtype($pane->type, $pane->subtype);
1380
1381
    // Set this up here because $id gets changed later.
1382
    $url = $this->get_url('access-configure-test', $pid, $id);
1383
1384
    // If we're adding a new one, get the stored data from cache and
1385
    // add it. It's stored as a cache so that if this is closed
1386
    // we don't accidentally add an unconfigured plugin.
1387
    if ($id == 'add') {
1388
      $pane->access['plugins'][] = $this->cache->new_plugin;
1389
      $id = max(array_keys($pane->access['plugins']));
1390
    }
1391 64156087 Assos Assos
    elseif (empty($pane->access['plugins'][$id])) {
1392 85ad3d82 Assos Assos
      ctools_modal_render(t('Error'), t('Invalid test id.'));
1393
    }
1394
1395
    $form_state = array(
1396
      'display' => &$this->display,
1397
      'pane' => &$pane,
1398
      'ajax' => TRUE,
1399
      'title' => t('Configure visibility rule for !subtype_title', array('!subtype_title' => $subtype['title'])),
1400
      'test' => &$pane->access['plugins'][$id],
1401
      'plugin' => ctools_get_access_plugin($pane->access['plugins'][$id]['name']),
1402
      'url' => url($url, array('absolute' => TRUE)),
1403
    );
1404
1405
    $output = ctools_modal_form_wrapper('panels_edit_configure_access_test_form', $form_state);
1406 c06bd9a4 Assos Assos
    $pane->access['plugins'][$id] = $form_state['test'];
1407
1408 85ad3d82 Assos Assos
    if (empty($form_state['executed'])) {
1409
      $this->commands = $output;
1410
      return;
1411
    }
1412
1413 64156087 Assos Assos
    // Unset the new plugin.
1414 85ad3d82 Assos Assos
    if (isset($this->cache->new_plugin)) {
1415
      unset($this->cache->new_plugin);
1416
    }
1417
1418
    if (!empty($form_state['remove'])) {
1419
      unset($pane->access['plugins'][$id]);
1420
    }
1421
1422
    panels_edit_cache_set($this->cache);
1423
    $this->command_update_pane($pid);
1424
    $this->commands[] = ctools_modal_command_dismiss();
1425
  }
1426
1427
  /**
1428
   * AJAX Router function for layout owned AJAX calls.
1429
   *
1430
   * Layouts like the flexible layout builder need callbacks of their own.
1431
   * This allows those layouts to simply declare their callbacks and use
1432
   * them with $this->get_url('layout', $command).
1433
   */
1434
  function ajax_layout() {
1435
    $args = func_get_args();
1436
    if (empty($args)) {
1437
      return MENU_NOT_FOUND;
1438
    }
1439
1440
    $command = array_shift($args);
1441
    if (empty($this->plugins['layout']['ajax'][$command]) || !function_exists($this->plugins['layout']['ajax'][$command])) {
1442
      return MENU_NOT_FOUND;
1443
    }
1444
1445
    // Make sure the this is always available to the called functions.
1446
    array_unshift($args, $this);
1447
    return call_user_func_array($this->plugins['layout']['ajax'][$command], $args);
1448
  }
1449
1450
  /**
1451
   * AJAX Router function for style owned AJAX calls.
1452
   *
1453
   * Styles like the stylizer need AJAX callbacks of their own. This
1454
   * allows the system to figure out which style is being referenced,
1455
   * load it, and execute the callback.
1456
   *
1457
   * This allows those layouts to simply declare their callbacks and use
1458
   * them using $this->get_url('style', $command, $type, $pid).
1459
   */
1460
  function ajax_style() {
1461
    $args = func_get_args();
1462
    if (count($args) < 3) {
1463
      return MENU_NOT_FOUND;
1464
    }
1465
1466
    $command = array_shift($args);
1467
    $type = array_shift($args);
1468
    $pid = array_shift($args);
1469
1470
    $info = $this->get_style($type, $pid);
1471
1472
    $style = $info[0];
1473
    $conf = &$info[1];
1474
1475
    if (empty($style['ajax'][$command]) || !function_exists($style['ajax'][$command])) {
1476
      return MENU_NOT_FOUND;
1477
    }
1478
1479
    // Make sure the this is always available to the called functions.
1480
    $args = array_merge(array(&$this, $style, &$conf, $type, $pid), $args);
1481
    return call_user_func_array($style['ajax'][$command], $args);
1482
  }
1483
1484
  // ------------------------------------------------------------------------
1485
  // AJAX command generators
1486
  //
1487
  // These are used to make sure that child implementations can control their
1488
  // own AJAX commands as needed.
1489
  /**
1490
   * Create a command array to redraw a pane.
1491
   */
1492
  function command_update_pane($pid) {
1493
    if (is_object($pid)) {
1494
      $pane = $pid;
1495
    }
1496
    else {
1497
      $pane = $this->display->content[$pid];
1498
    }
1499
1500
    $this->commands[] = ajax_command_replace("#panel-pane-$pane->pid", $this->render_pane($pane));
1501
    $this->commands[] = ajax_command_changed("#panel-pane-$pane->pid", "div.grab-title span.text");
1502
  }
1503
1504
  /**
1505
   * Create a command array to add a new pane.
1506
   */
1507
  function command_add_pane($pid) {
1508
    if (is_object($pid)) {
1509
      $pane = $pid;
1510
    }
1511
    else {
1512
      $pane = $this->display->content[$pid];
1513
    }
1514
1515
    $this->commands[] = ajax_command_append("#panel-region-$pane->panel", $this->render_pane($pane));
1516
    $this->commands[] = ajax_command_changed("#panel-pane-$pane->pid", "div.grab-title span.text");
1517
  }
1518
1519
  /**
1520
   * Create a command to update the links on a display after a change was made.
1521
   */
1522
  function command_update_display_links() {
1523
    $this->commands[] = ajax_command_replace('.panels-display-links', $this->get_display_links());
1524
  }
1525
1526
  /**
1527
   * Create a command to update the links on a region after a change was made.
1528
   */
1529
  function command_update_region_links($id) {
1530
    $this->commands[] = ajax_command_replace('.panels-region-links-' . $id, $this->get_region_links($id));
1531
  }
1532 64156087 Assos Assos
1533 85ad3d82 Assos Assos
}
1534
1535
/**
1536
 * Handle the 'next' click on the add/edit pane form wizard.
1537
 *
1538
 * All we need to do is store the updated pane in the cache.
1539
 */
1540
function panels_ajax_edit_pane_next(&$form_state) {
1541
  $form_state['display cache']->new_pane = $form_state['pane'];
1542
  panels_edit_cache_set($form_state['display cache']);
1543
}
1544
1545
/**
1546 136a805a Assos Assos
 * Handle the 'finish' click on the add/edit pane form wizard.
1547 85ad3d82 Assos Assos
 *
1548
 * All we need to do is set a flag so the return can handle adding
1549
 * the pane.
1550
 */
1551
function panels_ajax_edit_pane_finish(&$form_state) {
1552
  $form_state['complete'] = TRUE;
1553
  return;
1554
}
1555
1556
/**
1557
 * Handle the 'cancel' click on the add/edit pane form wizard.
1558
 */
1559
function panels_ajax_edit_pane_cancel(&$form_state) {
1560
  $form_state['cancel'] = TRUE;
1561
  return;
1562
}
1563
1564
// --------------------------------------------------------------------------
1565 64156087 Assos Assos
// Forms for the editor object.
1566 85ad3d82 Assos Assos
/**
1567 64156087 Assos Assos
 * Choose cache method form.
1568 85ad3d82 Assos Assos
 */
1569
function panels_edit_cache_method_form($form, &$form_state) {
1570 5a7e6170 Florent Torregrosa
  ctools_form_include($form_state, 'plugins', 'panels');
1571
  form_load_include($form_state, 'php', 'panels', '/plugins/display_renderers/panels_renderer_editor.class');
1572 85ad3d82 Assos Assos
  $display = &$form_state['display'];
1573
  $conf = &$form_state['conf'];
1574
1575
  // Set to 0 to ensure we get a selected radio.
1576
  if (!isset($conf['method'])) {
1577
    $conf['method'] = 0;
1578
  }
1579
1580
  $caches = panels_get_caches();
1581
  if (empty($caches)) {
1582
    $form['markup'] = array('#value' => t('No caching options are available at this time. Please enable a panels caching module in order to use caching options.'));
1583
    return $form;
1584
  }
1585
1586
  $options[0] = t('No caching');
1587
  foreach ($caches as $cache => $info) {
1588
    $options[$cache] = check_plain($info['title']);
1589
  }
1590
1591
  $form['method'] = array(
1592
    '#prefix' => '<div class="no-float">',
1593
    '#suffix' => '</div>',
1594
    '#type' => 'radios',
1595
    '#title' => t('Method'),
1596
    '#options' => $options,
1597
    '#default_value' => $conf['method'],
1598
  );
1599
1600
  $form['submit'] = array(
1601
    '#type' => 'submit',
1602
    '#value' => t('Next'),
1603
  );
1604
  return $form;
1605
}
1606
1607
/**
1608
 * Submit callback for panels_edit_cache_method_form.
1609
 *
1610
 * All this needs to do is return the method.
1611
 */
1612
function panels_edit_cache_method_form_submit($form, &$form_state) {
1613
  $form_state['method'] = $form_state['values']['method'];
1614
}
1615
1616
/**
1617 64156087 Assos Assos
 * Cache settings form.
1618 85ad3d82 Assos Assos
 */
1619
function panels_edit_cache_settings_form($form, &$form_state) {
1620 5a7e6170 Florent Torregrosa
  ctools_form_include($form_state, 'plugins', 'panels');
1621
  form_load_include($form_state, 'php', 'panels', '/plugins/display_renderers/panels_renderer_editor.class');
1622 85ad3d82 Assos Assos
  $display = &$form_state['display'];
1623
  $conf = &$form_state['conf'];
1624
  $pid = $form_state['pid'];
1625
  $info = panels_get_cache($conf['method']);
1626
1627
  $form['#action'] = $form_state['url'];
1628
1629
  $form['description'] = array(
1630
    '#prefix' => '<div class="description">',
1631
    '#suffix' => '</div>',
1632
    '#value' => check_plain($info['description']),
1633
  );
1634
1635
  $function = panels_plugin_get_function('cache', $conf['method'], 'settings form');
1636
1637
  $form['settings'] = $function($conf['settings'], $display, $pid);
1638
  $form['settings']['#tree'] = TRUE;
1639
1640
  $form['display'] = array(
1641
    '#type' => 'value',
1642
    '#value' => $display,
1643
  );
1644
1645
  $form['pid'] = array(
1646
    '#type' => 'value',
1647
    '#value' => $pid,
1648
  );
1649
1650
  $form['submit'] = array(
1651
    '#type' => 'submit',
1652
    '#value' => t('Save'),
1653
  );
1654
1655
  return $form;
1656
}
1657
1658
/**
1659
 * Validate cache settings.
1660
 */
1661
function panels_edit_cache_settings_form_validate($form, &$form_state) {
1662
  if ($function = panels_plugin_get_function('cache', $form_state['conf']['method'], 'settings form validate')) {
1663
    $function($form, $form_state['values']['settings']);
1664
  }
1665
}
1666
1667
/**
1668
 * Allows panel styles to validate their style settings.
1669
 */
1670
function panels_edit_cache_settings_form_submit($form, &$form_state) {
1671
  if ($function = panels_plugin_get_function('cache', $form_state['conf']['method'], 'settings form submit')) {
1672
    $function($form_state['values']['settings']);
1673
  }
1674
1675
  $form_state['conf']['settings'] = $form_state['values']['settings'];
1676
}
1677
1678
/**
1679 64156087 Assos Assos
 * Choose style form.
1680 85ad3d82 Assos Assos
 */
1681
function panels_edit_style_type_form($form, &$form_state) {
1682 5a7e6170 Florent Torregrosa
  ctools_form_include($form_state, 'plugins', 'panels');
1683
  form_load_include($form_state, 'php', 'panels', '/plugins/display_renderers/panels_renderer_editor.class');
1684 85ad3d82 Assos Assos
  $display = &$form_state['display'];
1685
  $style = $form_state['style'];
1686
  $type = $form_state['type'];
1687
1688
  $styles = panels_get_styles();
1689
1690
  $function = ($type == 'pane' ? 'render pane' : 'render region');
1691
  $options = array();
1692
  if ($type == 'region') {
1693
    $options[-1] = t('Use display default style');
1694
  }
1695
1696
  uasort($styles, 'ctools_plugin_sort');
1697
1698
  foreach ($styles as $id => $info) {
1699
    if (empty($info['hidden']) && (!empty($info[$function]) || $id == 'default')) {
1700
      $options[$id] = check_plain($info['title']);
1701
    }
1702
  }
1703
1704
  $form['style'] = array(
1705
    '#prefix' => '<div class="no-float">',
1706
    '#suffix' => '</div>',
1707
    '#type' => 'radios',
1708
    '#title' => t('Style'),
1709
    '#options' => $options,
1710
    '#default_value' => $style,
1711
  );
1712
1713
  $form['submit'] = array(
1714
    '#type' => 'submit',
1715
    '#value' => t('Next'),
1716
  );
1717
  return $form;
1718
}
1719
1720
/**
1721
 * Submit callback for panels_edit_style_type_form.
1722
 *
1723
 * All this needs to do is return the method.
1724
 */
1725
function panels_edit_style_type_form_submit($form, &$form_state) {
1726
  $form_state['old_style'] = $form_state['style'];
1727
  $form_state['style'] = $form_state['values']['style'];
1728
}
1729
1730
/**
1731 64156087 Assos Assos
 * Style settings form.
1732 85ad3d82 Assos Assos
 */
1733
function panels_edit_style_settings_form($form, &$form_state) {
1734 5a7e6170 Florent Torregrosa
  ctools_form_include($form_state, 'plugins', 'panels');
1735
  form_load_include($form_state, 'php', 'panels', '/plugins/display_renderers/panels_renderer_editor.class');
1736 85ad3d82 Assos Assos
  $display = &$form_state['display'];
1737
  $conf = &$form_state['conf'];
1738
  $pid = $form_state['pid'];
1739
  $style = $form_state['style'];
1740
  $type = $form_state['type'];
1741
1742
  $form['#action'] = $form_state['url'];
1743
1744
  $form['description'] = array(
1745
    '#prefix' => '<div class="description">',
1746
    '#suffix' => '</div>',
1747
    '#value' => check_plain($style['description']),
1748
  );
1749
1750
  $function = panels_plugin_get_function('styles', $style, ($type == 'pane') ? 'pane settings form' : 'settings form');
1751
1752
  $form['settings'] = $function($conf, $display, $pid, $type, $form_state);
1753
  $form['settings']['#tree'] = TRUE;
1754
1755
  $form['submit'] = array(
1756
    '#type' => 'submit',
1757
    '#value' => t('Save'),
1758
  );
1759
1760 e4c061ad Assos Assos
  // Need a cancel button since the style cache can persist and impact the wrong
1761
  // pane (or region, or display).
1762
  $form['cancel_style'] = array(
1763
    '#type' => 'submit',
1764
    '#value' => t('Cancel'),
1765
    '#submit' => array('panels_edit_style_settings_form_cancel'),
1766
  );
1767
1768 85ad3d82 Assos Assos
  return $form;
1769
}
1770
1771 e4c061ad Assos Assos
/**
1772
 * Cancel style settings form.
1773
 *
1774
 * Clears the editing cache to prevent styles being applied to incorrect regions
1775
 * or panes.
1776
 */
1777
function panels_edit_style_settings_form_cancel($form, &$form_state) {
1778
  $form_state['cancel'] = TRUE;
1779
}
1780
1781 85ad3d82 Assos Assos
/**
1782
 * Validate style settings.
1783
 */
1784
function panels_edit_style_settings_form_validate($form, &$form_state) {
1785
  $name = $form_state['type'] == 'pane' ? 'pane settings form validate' : 'settings form validate';
1786
  if ($function = panels_plugin_get_function('styles', $form_state['style'], $name)) {
1787
    $function($form, $form_state['values']['settings'], $form_state);
1788
  }
1789
}
1790
1791
/**
1792
 * Allows panel styles to validate their style settings.
1793
 */
1794
function panels_edit_style_settings_form_submit($form, &$form_state) {
1795
  $name = $form_state['type'] == 'pane' ? 'pane settings form submit' : 'settings form submit';
1796
  if ($function = panels_plugin_get_function('styles', $form_state['style'], $name)) {
1797
    $function($form, $form_state['values']['settings'], $form_state);
1798
  }
1799
1800
  $form_state['conf'] = $form_state['values']['settings'];
1801
}
1802
1803
1804
/**
1805
 * Configure CSS on a pane form.
1806
 */
1807
function panels_edit_configure_pane_css_form($form, &$form_state) {
1808 5a7e6170 Florent Torregrosa
  ctools_form_include($form_state, 'plugins', 'panels');
1809
  form_load_include($form_state, 'php', 'panels', '/plugins/display_renderers/panels_renderer_editor.class');
1810 85ad3d82 Assos Assos
  $display = &$form_state['display'];
1811
  $pane = &$form_state['pane'];
1812
1813
  $form['css_id'] = array(
1814
    '#type' => 'textfield',
1815
    '#default_value' => isset($pane->css['css_id']) ? $pane->css['css_id'] : '',
1816
    '#title' => t('CSS ID'),
1817 136a805a Assos Assos
    '#description' => t('CSS ID to apply to this pane. This may be blank. Keywords from context are allowed.'),
1818 85ad3d82 Assos Assos
  );
1819
  $form['css_class'] = array(
1820
    '#type' => 'textfield',
1821
    '#default_value' => isset($pane->css['css_class']) ? $pane->css['css_class'] : '',
1822
    '#title' => t('CSS class'),
1823 136a805a Assos Assos
    '#description' => t('CSS class to apply to this pane. This may be blank. Keywords from context are allowed.'),
1824 85ad3d82 Assos Assos
  );
1825
1826
  $form['next'] = array(
1827
    '#type' => 'submit',
1828
    '#value' => t('Save'),
1829
  );
1830
1831
  return $form;
1832
}
1833
1834
/**
1835
 * FAPI submission function for the CSS configure form.
1836
 *
1837
 * All this does is set up $pane properly. The caller is responsible for
1838
 * actually storing this somewhere.
1839
 */
1840
function panels_edit_configure_pane_css_form_submit($form, &$form_state) {
1841
  $pane = &$form_state['pane'];
1842
  $display = $form_state['display'];
1843
1844
  $pane->css['css_id'] = $form_state['values']['css_id'];
1845
  $pane->css['css_class'] = $form_state['values']['css_class'];
1846
}
1847
1848
/**
1849
 * Configure lock on a pane form.
1850
 */
1851
function panels_edit_configure_pane_lock_form($form, &$form_state) {
1852 5a7e6170 Florent Torregrosa
  ctools_form_include($form_state, 'plugins', 'panels');
1853
  form_load_include($form_state, 'php', 'panels', '/plugins/display_renderers/panels_renderer_editor.class');
1854 85ad3d82 Assos Assos
  $display = &$form_state['display'];
1855
  $pane = &$form_state['pane'];
1856
1857
  if (empty($pane->locks)) {
1858
    $pane->locks = array('type' => 'none', 'regions' => array());
1859
  }
1860
1861
  $form['type'] = array(
1862
    '#type' => 'radios',
1863
    '#title' => t('Lock type'),
1864
    '#options' => array(
1865
      'none' => t('No lock'),
1866
      'immovable' => t('Immovable'),
1867
      'regions' => t('Regions'),
1868
    ),
1869
    '#default_value' => $pane->locks['type'],
1870
  );
1871
1872
  $layout = panels_get_layout($display->layout);
1873
  $regions = panels_get_regions($layout, $display);
1874
1875
  $form['regions'] = array(
1876
    '#type' => 'checkboxes',
1877
    '#title' => t('Regions'),
1878
    '#options' => $regions,
1879
    '#description' => t('Select which regions this pane can be moved to.'),
1880
    '#dependency' => array(
1881
      'radio:type' => array('regions'),
1882
    ),
1883
    '#default_value' => $pane->locks['regions'],
1884
  );
1885
1886
  $form['#after_build'][] = 'panels_edit_configure_pane_lock_form_after_build';
1887
  $form['next'] = array(
1888
    '#type' => 'submit',
1889
    '#value' => t('Save'),
1890
  );
1891
1892
  return $form;
1893
}
1894
1895
function panels_edit_configure_pane_lock_form_after_build($element, $form_state) {
1896
  $region = $form_state['pane']->panel;
1897
  $element['regions'][$region]['#required'] = TRUE;
1898
  $element['regions'][$region]['#disabled'] = TRUE;
1899
  $element['regions'][$region]['#value'] = TRUE;
1900
  $element['regions'][$region]['#checked'] = TRUE;
1901
  $element['regions'][$region]['#attributes']['disabled'] = TRUE;
1902
  return $element;
1903
}
1904
1905
/**
1906
 * FAPI submission function for the lock configure form.
1907
 *
1908
 * All this does is set up $pane properly. The caller is responsible for
1909
 * actually storing this somewhere.
1910
 */
1911
function panels_edit_configure_pane_lock_form_submit($form, &$form_state) {
1912
  $pane = &$form_state['pane'];
1913
  $display = $form_state['display'];
1914
1915
  // We set this to true but forms do not submit disabled checkboxes
1916
  // and fapi is ignoring the #value directive probably because it
1917
  // is checkboxes:
1918
  $region = $form_state['pane']->panel;
1919
  $form_state['values']['regions'][$region] = $region;
1920
1921
  $pane->locks['type'] = $form_state['values']['type'];
1922
  $pane->locks['regions'] = array_filter($form_state['values']['regions']);
1923
}
1924
1925
/**
1926
 * Form to control basic visibility settings.
1927
 */
1928
function panels_edit_configure_access_settings_form($form, &$form_state) {
1929 5a7e6170 Florent Torregrosa
  ctools_form_include($form_state, 'plugins', 'panels');
1930
  form_load_include($form_state, 'php', 'panels', '/plugins/display_renderers/panels_renderer_editor.class');
1931 85ad3d82 Assos Assos
  $display = &$form_state['display'];
1932
  $pane = &$form_state['pane'];
1933
1934
  $form['logic'] = array(
1935
    '#type' => 'radios',
1936
    '#options' => array(
1937
      'and' => t('All criteria must pass.'),
1938
      'or' => t('Only one criterion must pass.'),
1939
    ),
1940
    '#default_value' => isset($pane->access['logic']) ? $pane->access['logic'] : 'and',
1941
  );
1942
1943
  $form['next'] = array(
1944
    '#type' => 'submit',
1945
    '#value' => t('Save'),
1946
  );
1947
1948
  return $form;
1949
}
1950
1951
/**
1952
 * FAPI submission function for the edit access settings form.
1953
 *
1954
 * All this does is set up $pane properly. The caller is responsible for
1955
 * actually storing this somewhere.
1956
 */
1957
function panels_edit_configure_access_settings_form_submit($form, &$form_state) {
1958
  $pane = &$form_state['pane'];
1959
  $display = $form_state['display'];
1960
1961
  $pane->access['logic'] = $form_state['values']['logic'];
1962
}
1963
1964
/**
1965
 * Form to add a visibility rule.
1966
 */
1967
function panels_edit_add_access_test_form($form, &$form_state) {
1968 5a7e6170 Florent Torregrosa
  ctools_form_include($form_state, 'plugins', 'panels');
1969
  form_load_include($form_state, 'php', 'panels', '/plugins/display_renderers/panels_renderer_editor.class');
1970 85ad3d82 Assos Assos
  $display = &$form_state['display'];
1971
  $pane = &$form_state['pane'];
1972
1973
  $plugins = ctools_get_relevant_access_plugins($display->context);
1974
  $options = array();
1975
  foreach ($plugins as $id => $plugin) {
1976
    $options[$id] = $plugin['title'];
1977
  }
1978
1979
  asort($options);
1980
1981
  $form['type'] = array(
1982
    // This ensures that the form item is added to the URL.
1983
    '#type' => 'radios',
1984
    '#options' => $options,
1985
  );
1986
1987
  $form['next'] = array(
1988
    '#type' => 'submit',
1989
    '#value' => t('Next'),
1990
  );
1991
1992
  return $form;
1993
}
1994
1995
/**
1996
 * Form to configure a visibility rule.
1997
 */
1998
function panels_edit_configure_access_test_form($form, &$form_state) {
1999 5a7e6170 Florent Torregrosa
  ctools_form_include($form_state, 'plugins', 'panels');
2000
  form_load_include($form_state, 'php', 'panels', '/plugins/display_renderers/panels_renderer_editor.class');
2001 85ad3d82 Assos Assos
  $display = &$form_state['display'];
2002
  $test = &$form_state['test'];
2003
  $plugin = &$form_state['plugin'];
2004
2005
  $form['#action'] = $form_state['url'];
2006
2007
  $contexts = $display->context;
2008
  if (!isset($contexts['logged-in-user'])) {
2009
    $contexts['logged-in-user'] = ctools_access_get_loggedin_context();
2010
  }
2011
2012
  if (isset($plugin['required context'])) {
2013
    $form['context'] = ctools_context_selector($contexts, $plugin['required context'], $test['context']);
2014
  }
2015
2016
  $form['settings'] = array('#tree' => TRUE);
2017
  if ($function = ctools_plugin_get_function($plugin, 'settings form')) {
2018
    $form = $function($form, $form_state, $test['settings']);
2019
  }
2020
2021
  $form['not'] = array(
2022
    '#type' => 'checkbox',
2023
    '#title' => t('Reverse (NOT)'),
2024
    '#default_value' => !empty($test['not']),
2025
  );
2026
2027
  $form['save'] = array(
2028
    '#type' => 'submit',
2029
    '#value' => t('Save'),
2030
  );
2031
2032
  $form['remove'] = array(
2033
    '#type' => 'submit',
2034
    '#value' => t('Remove'),
2035
    '#remove' => TRUE,
2036
  );
2037
2038
  return $form;
2039
}
2040
2041
/**
2042 64156087 Assos Assos
 * Validate handler for visibility rule settings.
2043 85ad3d82 Assos Assos
 */
2044
function panels_edit_configure_access_test_form_validate(&$form, &$form_state) {
2045
  if (!empty($form_state['clicked_button']['#remove'])) {
2046
    return;
2047
  }
2048
2049
  if ($function = ctools_plugin_get_function($form_state['plugin'], 'settings form validate')) {
2050
    $function($form, $form_state);
2051
  }
2052
}
2053
2054
/**
2055 64156087 Assos Assos
 * Submit handler for visibility rule settings.
2056 85ad3d82 Assos Assos
 */
2057
function panels_edit_configure_access_test_form_submit(&$form, &$form_state) {
2058
  if (!empty($form_state['clicked_button']['#remove'])) {
2059
    $form_state['remove'] = TRUE;
2060
    return;
2061
  }
2062
2063
  if ($function = ctools_plugin_get_function($form_state['plugin'], 'settings form submit')) {
2064
    $function($form, $form_state);
2065
  }
2066
2067 c06bd9a4 Assos Assos
  if (!isset($form_state['values']['settings'])) {
2068
    $form_state['values']['settings'] = array();
2069
  }
2070 85ad3d82 Assos Assos
  $form_state['test']['settings'] = $form_state['values']['settings'];
2071
  if (isset($form_state['values']['context'])) {
2072
    $form_state['test']['context'] = $form_state['values']['context'];
2073
  }
2074
  $form_state['test']['not'] = !empty($form_state['values']['not']);
2075
}