Projet

Général

Profil

Paste
Télécharger (33 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / panels / plugins / task_handlers / panel_context.inc @ 08475715

1
<?php
2

    
3
/**
4
 * @file
5
 *
6
 * This is the task handler plugin to handle attaching a panel to any
7
 * task that advertises itself as a 'context' type, which all of the
8
 * basic page tasks provided by page_manager.module do by default.
9
 */
10

    
11
// Plugin definition
12
$plugin = array(
13
  // is a 'context' handler type, meaning it supports the API of the
14
  // context handlers provided by ctools context plugins.
15
  'handler type' => 'context',
16
  'visible' => TRUE, // may be added up front.
17

    
18
  // Administrative fields.
19
  'title' => t('Panel'),
20
  'admin summary' =>'panels_panel_context_admin_summary',
21
  'admin title' => 'panels_panel_context_title',
22
  'operations' => array(
23
    'settings' => array(
24
      'title' => t('General'),
25
      'description' => t('Change general settings about this variant.'),
26
      'form' => 'panels_panel_context_edit_settings',
27
    ),
28
    'criteria' => array(
29
      'title' => t('Selection rules'),
30
      'description' => t('Control the criteria used to decide whether or not this variant is used.'),
31
      'ajax' => FALSE,
32
      'form' => array(
33
        'order' => array(
34
          'form' => t('Selection rules'),
35
        ),
36
        'forms' => array(
37
          'form' => array(
38
            'include' => drupal_get_path('module', 'ctools') . '/includes/context-task-handler.inc',
39
            'form id' => 'ctools_context_handler_edit_criteria',
40
          ),
41
        ),
42
      ),
43
    ),
44
    'context' => array(
45
      'title' => t('Contexts'),
46
      'ajax' => FALSE,
47
      'description' => t('Add additional context objects to this variant that can be used by the content.'),
48
      'form' => array(
49
        'order' => array(
50
          'form' => t('Context'),
51
        ),
52
        'forms' => array(
53
          'form' => array(
54
            'include' => drupal_get_path('module', 'ctools') . '/includes/context-task-handler.inc',
55
            'form id' => 'ctools_context_handler_edit_context',
56
          ),
57
        ),
58
      ),
59
    ),
60
    'layout' => array(
61
      'title' => t('Layout'),
62
      'description' => t('Change the layout of this panel.'),
63
      // No AJAX so we get our CSS loaded.
64
      'ajax' => FALSE,
65
      'form' => array(
66
        'order' => array(
67
          'choose' => t('Change layout'),
68
          'move' => t('Move content from old layout'),
69
        ),
70
        'forms' => array(
71
          'choose' => array(
72
            'form id' => 'panels_panel_context_edit_layout',
73
          ),
74
          'move' => array(
75
            'include' => array(
76
              drupal_get_path('module', 'panels') . '/includes/display-layout.inc',
77
            ),
78
            'form id' => 'panels_panel_context_edit_move',
79
            'submit' => 'panels_change_layout_submit',
80
          ),
81
        ),
82
      ),
83
    ),
84
    'content' => array(
85
      'title' => t('Content'),
86
      'description' => t('Add content items and change their location with a drag and drop interface.'),
87
      'ajax' => FALSE,
88
      'form' => array(
89
        'order' => array(
90
          'form' => t('Content'),
91
        ),
92
        'forms' => array(
93
          'form' => array(
94
            'include' => array(
95
              drupal_get_path('module', 'panels') . '/includes/display-edit.inc',
96
            ),
97
            'form id' => 'panels_panel_context_edit_content',
98
            'no blocks' => TRUE,
99
          ),
100
        ),
101
      ),
102
    ),
103
    'preview' => array(
104
      'title' => t('Preview'),
105
      'description' => t('Get a preview of what this variant will look like.'),
106
      'form' => 'panels_panel_context_edit_preview',
107
      'ajax' => FALSE,
108
      'silent' => TRUE,
109
      'form info' => array('finish text' => t('Preview')),
110
      'no update and save' => TRUE,
111
    ),
112
  ),
113

    
114
  'tab operation' => 'panels_panel_context_tab_operation',
115

    
116
  // Callback to render the data.
117
  'render' => 'panels_panel_context_render',
118
  // Callback to return addressable data
119
  'addressable callback' => 'panels_panel_context_get_addressable',
120

    
121
  // Various callbacks for operations performed on the handler to ensure
122
  // related data is updated properly.
123
  'save' => 'panels_panel_context_save',
124
  'delete' => 'panels_panel_context_delete',
125
  'export' => 'panels_panel_context_export',
126
  'clone' => 'panels_panel_context_clone',
127

    
128
  'add features' => array(
129
    'criteria' => t('Selection rules'),
130
    'context' => t('Contexts'),
131
  ),
132
  // Where to go when finished.
133
  'add finish' => 'content',
134

    
135
  'required forms' => array(
136
    'choose' => t('Choose layout'),
137
    'settings' => t('Panel settings'),
138
    'content' => t('Panel content'),
139
  ),
140

    
141
  'edit forms' => array(
142
    'content' => t('Panel content'),
143
    'criteria' => t('Selection rules'),
144
    'settings' => t('General'),
145
    'context' => t('Contexts'),
146
    'layout' => t('Change layout'),
147
    'move' => '', // no title makes it a 'hidden' edit form.
148
  ),
149
  'forms' => array(
150
    'settings' => array(
151
      'form id' => 'panels_panel_context_edit_settings',
152
    ),
153
    'choose' => array(
154
      'form id' => 'panels_panel_context_edit_choose',
155
      'no back validate' => TRUE,
156
    ),
157
    'layout' => array(
158
      'no return' => TRUE,
159
      'form id' => 'panels_panel_context_edit_layout',
160
    ),
161
    'move' => array(
162
      'include' => array(
163
        drupal_get_path('module', 'panels') . '/includes/display-layout.inc',
164
      ),
165
      'form id' => 'panels_panel_context_edit_move',
166
      'submit' => 'panels_change_layout_submit',
167
    ),
168
    'content' => array(
169
      'include' => array(
170
        drupal_get_path('module', 'panels') . '/includes/display-edit.inc',
171
      ),
172
      'form id' => 'panels_panel_context_edit_content',
173
      'no blocks' => TRUE,
174
    ),
175
    'context' => array(
176
      'include' => drupal_get_path('module', 'ctools') . '/includes/context-task-handler.inc',
177
      'form id' => 'ctools_context_handler_edit_context',
178
    ),
179
    'criteria' => array(
180
      'include' => drupal_get_path('module', 'ctools') . '/includes/context-task-handler.inc',
181
      'form id' => 'ctools_context_handler_edit_criteria',
182
    ),
183
  ),
184
  'default conf' => array(
185
    'title' => t('Panel'),
186
    'no_blocks' => FALSE,
187
    'pipeline' => variable_get('panels_renderer_default', 'standard'),
188
    'body_classes_to_remove' => '',
189
    'body_classes_to_add' => '',
190
    'css_id' => '',
191
    'css' => '',
192
    'contexts' => array(),
193
    'relationships' => array(),
194
  ),
195
);
196

    
197
/**
198
 * Provide the operation trail for the 'Edit panel' link.
199
 *
200
 * When editing the panel, go directly to the content tab.
201
 */
202
function panels_panel_context_tab_operation($handler, $contexts, $args) {
203
  return array('handlers', $handler->name, 'content');
204
}
205

    
206
/**
207
 * Get the display for a task handler.
208
 *
209
 * There are three methods that the display can be found.
210
 * - In the database. $handler->conf['did'] will be set in this case,
211
 *   and $handler->conf['display'] won't be.
212
 * - In $handler->conf['display'], with $handler->conf['did'] empty. This
213
 *   will be true for a default/imported task handler as well as a handler
214
 *   that has just been created but has not yet been saved.
215
 * - in $handler->conf['display'] with $handler->conf['did' populated. This
216
 *   simply means that the display has been modified and is awaiting
217
 *   save. The modified one should always be used for editing purposes.
218
 * - If none of the above is true, then a new display needs to be created
219
 *   for the handler and pla
220
 */
221
function &panels_panel_context_get_display(&$handler) {
222
  if (!isset($handler->conf['display'])) {
223
    if (isset($handler->conf['did'])) {
224
      $handler->conf['display'] = panels_load_display($handler->conf['did']);
225
    }
226

    
227
    // Check for again for a valid display. If no valid display could be loaded,
228
    // something is wrong and we'll create a new one.
229
    if (empty($handler->conf['display'])) {
230
      $handler->conf['display'] = panels_new_display();
231
    }
232
  }
233

    
234
  $display =& $handler->conf['display'];
235
  $display->storage_type = 'page_manager';
236
  $display->storage_id = !empty($handler->name) ? $handler->name : 'new';
237

    
238
  return $display;
239
}
240

    
241
/**
242
 * Build the cache key so that the editor and IPE can properly find
243
 * everything needed for this display.
244
 */
245
function panels_panel_context_cache_key($task_name, $handler_id, $args) {
246
  $arguments = array();
247
  foreach ($args as $arg) {
248
    // Sadly things like panels everywhere actually use non-string arguments
249
    // and they basically can't be represented here. Luckily, PE also does
250
    // not use a system where this matters, so replace its args with a 0
251
    // for a placeholder.
252
    if (is_string($arg)) {
253
      $arguments[] = $arg;
254
    }
255
    else {
256
      $arguments[] = '0';
257
    }
258
  }
259
  $cache_key = 'panel_context:' . $task_name . '::' . $handler_id . '::' . implode('\\', $arguments) . '::';
260
  return $cache_key;
261
}
262

    
263
/**
264
 * Check selection rules and, if passed, render the contexts.
265
 */
266
function panels_panel_context_render($handler, $base_contexts, $args, $test = TRUE) {
267
  // Go through arguments and see if they match.
268
  ctools_include('context');
269
  ctools_include('context-task-handler');
270
  ctools_include('plugins', 'panels');
271

    
272
  // Add my contexts
273
  $contexts = ctools_context_handler_get_handler_contexts($base_contexts, $handler);
274

    
275
  // Test.
276
  if ($test && !ctools_context_handler_select($handler, $contexts)) {
277
    return;
278
  }
279

    
280
  if (isset($handler->handler)) {
281
    ctools_context_handler_pre_render($handler, $contexts, $args);
282
  }
283

    
284
  // Load the display
285
  $display = panels_panel_context_get_display($handler);
286

    
287
  $display->context = $contexts;
288
  $display->args = $args;
289
  $page_css_id = ctools_context_keyword_substitute($handler->conf['css_id'], array(), $contexts);
290
  $display->css_id = check_plain($page_css_id);
291
  $task_name = page_manager_make_task_name($handler->task, $handler->subtask);
292

    
293
  $display->cache_key = panels_panel_context_cache_key($task_name, $handler->name, $args);
294

    
295
  // Check to see if there is any CSS.
296
  if (!empty($handler->conf['css'])) {
297
    ctools_include('css');
298
    $css_id = 'panel_context:' . $handler->name;
299
    $filename = ctools_css_retrieve($css_id);
300
    if (!$filename) {
301
      // Add keywords from context
302
      $css = ctools_context_keyword_substitute($handler->conf['css'], array(), $contexts, array('css safe' => TRUE));
303
      $filename = ctools_css_store($css_id, $css);
304
    }
305
    drupal_add_css($filename);
306
  }
307

    
308
  // With an argument, this actually sets the display.
309
  panels_get_current_page_display($display);
310

    
311
  $renderer = panels_get_renderer($handler->conf['pipeline'], $display);
312
  // If the IPE is enabled, but the user does not have access to edit
313
  // load the standard renderer instead.
314

    
315
  $parents = class_parents($renderer);
316
  if (!empty($parents['panels_renderer_editor']) && !user_access('user page manager') && !user_access('use ipe with page manager')) {
317
    $renderer = panels_get_renderer_handler('standard', $display);
318
  }
319

    
320
  // Remove and add body element classes
321
  $panel_body_css = &drupal_static('panel_body_css');
322

    
323
  if (isset($handler->conf['body_classes_to_remove'])) {
324
    $classes = ctools_context_keyword_substitute($handler->conf['body_classes_to_remove'], array(), $contexts, array('css safe' => TRUE));
325
    if (!isset($panel_body_css['body_classes_to_remove'])) {
326
      $panel_body_css['body_classes_to_remove'] = check_plain($classes);
327
    }
328
    else{
329
      $panel_body_css['body_classes_to_remove'] .= ' ' . check_plain($classes);
330
    }
331
  }
332
  if (isset($handler->conf['body_classes_to_add'])) {
333
    $classes = ctools_context_keyword_substitute($handler->conf['body_classes_to_add'], array(), $contexts, array('css safe' => TRUE));
334
    if (!isset($panel_body_css['body_classes_to_add'])) {
335
    $panel_body_css['body_classes_to_add'] = check_plain($classes);
336
    }
337
    else {
338
      $panel_body_css['body_classes_to_add'] .= ' '. check_plain($classes);
339
    }
340
  }
341

    
342
  $info = array(
343
    'content' => panels_render_display($display, $renderer),
344
    'no_blocks' => !empty($handler->conf['no_blocks']),
345
  );
346

    
347
  $info['title'] = $display->get_title();
348

    
349
  return $info;
350
}
351

    
352
/**
353
 * Callback to allow the handler to react to being saved.
354
 *
355
 * When a handler with a display is saved, two things have to happen.
356
 * First, we have to save the display so that it becomes a real display,
357
 * not the fake one we started with. Second, we have to cache
358
 * any CSS that the display is using. This CSS can get re-cached
359
 * later if the file disappears, but it's imperative that we do it here
360
 * to make sure that old, dirty CSS cache gets removed.
361
 */
362
function panels_panel_context_save(&$handler, $update) {
363
  // Only save the display if we believe it has been modified.
364
  if (isset($handler->conf['display'])) {
365
    panels_save_display($handler->conf['display']);
366
    $handler->conf['did'] = $handler->conf['display']->did;
367
    unset($handler->conf['display']);
368
  }
369

    
370
  // Delete any previous CSS cache file.
371
  ctools_include('css');
372
  ctools_css_clear('panel_context:' . $handler->name);
373

    
374
  if (isset($handler->conf['temp_layout'])) {
375
    unset($handler->conf['temp_layout']);
376
  }
377
}
378

    
379
/**
380
 * Special handling for exporting a panel task handler.
381
 *
382
 * When a panel is exported, we need to export the display separately
383
 * rather than just letting its object be unpacked, which does not work
384
 * very well.
385
 */
386
function panels_panel_context_export(&$handler, $indent) {
387
  $display = panels_panel_context_get_display($handler);
388
  foreach (array('display', 'did', 'css_cache', 'temp_layout') as $item) {
389
    if (isset($handler->conf[$item])) {
390
      unset($handler->conf[$item]);
391
    }
392
  }
393

    
394
  $output = panels_export_display($display, $indent);
395
  $output .= $indent . '$handler->conf[\'display\'] = $display' . ";\n";
396
  return $output;
397
}
398

    
399
/**
400
 * When a handler is cloned, we have to clone the display.
401
 */
402
  function panels_panel_context_clone(&$handler) {
403
  $old_display = panels_panel_context_get_display($handler);
404
  $code = panels_export_display($old_display);
405
  eval($code);
406
  foreach (array('display', 'did', 'css_cache', 'temp_layout') as $item) {
407
    if (isset($handler->conf[$item])) {
408
      unset($handler->conf[$item]);
409
    }
410
  }
411
  $display = (object) array(
412
    'did' => 'new',
413
    'uuid' => ctools_uuid_generate(),
414
  );
415
  $handler->conf['display'] = $display;
416
}
417

    
418
/**
419
 * Callback to delete the display when a handler is deleted.
420
 */
421
function panels_panel_context_delete(&$handler) {
422
  if (!empty($handler->conf['did'])) {
423
    panels_delete_display($handler->conf['did']);
424
  }
425
}
426

    
427
/**
428
 * Set up a title for the panel based upon the selection rules.
429
 */
430
function panels_panel_context_title($handler, $task, $subtask) {
431
  if (isset($handler->conf['title'])) {
432
    return check_plain($handler->conf['title']);
433
  }
434
  else {
435
    return t('Panel');
436
  }
437
}
438

    
439
/**
440
 * Provide a nice little summary of what's in a panel.
441
 *
442
 * The task handler manager provides a summary of a given handler in a
443
 * collapsible div. This callback provides that. For a Panel, we
444
 * provide a summary of the layout type and content on one side, and
445
 * a summary of the contexts in use on the other.
446
 */
447
function panels_panel_context_admin_summary($handler, $task, $subtask, $page, $show_title = TRUE) {
448
  $task_name = page_manager_make_task_name($task['name'], $subtask['name']);
449
  $output = '';
450

    
451
  $display = panels_panel_context_get_display($handler);
452

    
453
  ctools_include('plugins', 'panels');
454
  ctools_include('context');
455
  ctools_include('context-task-handler');
456

    
457
  // Get the operations
458
  $operations = page_manager_get_operations($page);
459

    
460
  // Get operations for just this handler.
461
  $operations = $operations['handlers']['children'][$handler->name]['children']['actions']['children'];
462
  $args = array('handlers', $handler->name, 'actions');
463
  $rendered_operations = page_manager_render_operations($page, $operations, array(), array('class' => array('actions')), 'actions', $args);
464

    
465
  $layout = panels_get_layout($display->layout);
466

    
467
  $plugin = page_manager_get_task_handler($handler->handler);
468

    
469
  $object = ctools_context_handler_get_task_object($task, $subtask, $handler);
470
  $display->context = ctools_context_load_contexts($object, TRUE);
471

    
472
  $access = ctools_access_group_summary(!empty($handler->conf['access']) ? $handler->conf['access'] : array(), $display->context);
473
  if ($access) {
474
    $access = t('This panel will be selected if @conditions.', array('@conditions' => $access));
475
  }
476
  else {
477
    $access = t('This panel will always be selected.');
478
  }
479

    
480
  $rows = array();
481

    
482
  $type = $handler->type == t('Default') ? t('In code') : $handler->type;
483
  $rows[] = array(
484
    array('class' => t('page-summary-label'), 'data' => t('Storage')),
485
    array('class' => t('page-summary-data'), 'data' => $type),
486
    array('class' => t('page-summary-operation'), 'data' => ''),
487
  );
488

    
489
  if (!empty($handler->disabled)) {
490
    $link = l(t('Enable'), page_manager_edit_url($task_name, array('handlers', $handler->name, 'actions', 'enable')));
491
    $text = t('Disabled');
492
  }
493
  else {
494
    $link = l(t('Disable'), page_manager_edit_url($task_name, array('handlers', $handler->name, 'actions', 'disable')));
495
    $text = t('Enabled');
496
  }
497

    
498
  $rows[] = array(
499
    array('class' => t('page-summary-label'), 'data' => t('Status')),
500
    array('class' => t('page-summary-data'), 'data' => $text),
501
    array('class' => t('page-summary-operation'), 'data' => $link),
502
  );
503

    
504
  $link = l(t('Edit'), page_manager_edit_url($task_name, array('handlers', $handler->name, 'criteria')));
505
  $rows[] = array(
506
    array('class' => t('page-summary-label'), 'data' => t('Selection rule')),
507
    array('class' => t('page-summary-data'), 'data' => $access),
508
    array('class' => t('page-summary-operation'), 'data' => $link),
509
  );
510

    
511
  $link = l(t('Change layout'), page_manager_edit_url($task_name, array('handlers', $handler->name, 'layout')));
512
  $link .= '<br />' . l(t('Edit content'), page_manager_edit_url($task_name, array('handlers', $handler->name, 'content')));
513
  $link .= '<br />' . l(t('Preview'), page_manager_edit_url($task_name, array('handlers', $handler->name, 'preview')));
514
  $rows[] = array(
515
    array('class' => t('page-summary-label'), 'data' => t('Layout')),
516
    array('class' => t('page-summary-data'), 'data' => check_plain($layout['title'])),
517
    array('class' => t('page-summary-operation'), 'data' => $link),
518
  );
519

    
520
  $content_link = ' [' . l(t('Edit'), page_manager_edit_url($task_name, array('handlers', $handler->name, 'content'))) . ']';
521
  $context_link = ' [' . l(t('Edit'), page_manager_edit_url($task_name, array('handlers', $handler->name, 'context'))) . ']';
522

    
523
  $info = theme('table', array('rows' => $rows, 'attributes' => array('class' => 'page-manager-handler-summary')));
524

    
525
  $title = $handler->conf['title'];
526
  if ($title != t('Panel')) {
527
    $title = t('Panel: @title', array('@title' => $title));
528
  }
529

    
530
  $output .= '<div class="clearfix">';
531
  if ($show_title) {
532
  $output .= '<div class="handler-title clearfix">';
533
    $output .= '<div class="actions handler-actions">' . $rendered_operations['actions'] . '</div>';
534
    $output .= '<span class="title-label">' . $title . '</span>';
535
  }
536

    
537
  $output .= '</div>';
538
  $output .= $info;
539
  $output .= '</div>';
540
/*
541
  $output .= '<div class="right-container">';
542
  $output .= '<h3 class="context-title">' . t('Contexts') . $context_link . '</h3>';
543
  $output .= $contexts;
544
  $output .= '</div>';
545

    
546
  $output .= '<div class="left-container">';
547
//  $output .= $icon;
548
  $output .= '<h3 class="handler-title">' . t('Content') . $content_link . '</h3>';
549
  $output .= $content;
550
  $output .= '</div>';
551
*/
552
  return $output;
553
}
554

    
555
// --------------------------------------------------------------------------
556
// Forms
557

    
558
/**
559
 * General notes about forms: The handler is automatically cached by the form
560
 * wizard, so anything we store on $form_state['handler'] anywhere will get
561
 * saved and appear on the next form. The cache is a 'working' cache and
562
 * if the user hits cancel on any page of the multi-page wizard, all
563
 * changes since the last 'update/finish' click will be flushed away.
564
 *
565
 * Many of the Panels forms call through to the real Panels cousins. These
566
 * forms are smart enough to know that they're being wrapped in another
567
 * form and act appropriately. Some of them are so smart that we just let
568
 * their submit and validate handlers do the work rather than writing
569
 * additional ones here.
570
 */
571

    
572
/**
573
 * Choose a layout for this panel.
574
 *
575
 * This is only called during 'add', when we know that there isn't a
576
 * previous layout to choose from. a different, only slightly different
577
 * variant is called to change a pre-existing layout.
578
 */
579
function panels_panel_context_edit_choose($form, &$form_state) {
580
  ctools_include('common', 'panels');
581
  ctools_include('display-layout', 'panels');
582
  ctools_include('plugins', 'panels');
583

    
584
  // @todo -- figure out where/how to deal with this.
585
  $form_state['allowed_layouts'] = 'panels_page';
586

    
587
  $form_state['display'] = &panels_panel_context_get_display($form_state['handler']);
588

    
589
  // Tell the Panels form not to display buttons.
590
  $form_state['no buttons'] = TRUE;
591

    
592
  // Change the #id of the form so the CSS applies properly.
593
  $form['#id'] = 'panels-choose-layout';
594
  $form = panels_choose_layout($form, $form_state);
595

    
596
  return $form;
597
}
598

    
599
/**
600
 * Validate that a layout was chosen.
601
 */
602
function panels_panel_context_edit_choose_validate(&$form, &$form_state) {
603
  if (empty($form_state['values']['layout'])) {
604
    form_error($form['layout'], t('You must select a layout.'));
605
  }
606
}
607

    
608
/**
609
 * A layout has been selected, set it up.
610
 */
611
function panels_panel_context_edit_choose_submit(&$form, &$form_state) {
612
  $form_state['display']->layout = $form_state['values']['layout'];
613
  $form_state['handler']->conf['display'] = $form_state['display'];
614
  if (isset($form_state['page']->display_cache[$form_state['handler_id']])) {
615
    $form_state['page']->display_cache[$form_state['handler_id']]->display = $form_state['display'];
616
  }
617
}
618

    
619
/**
620
 * Change the layout for this panel.
621
 *
622
 * This form is only used if a layout already exists and the user wants
623
 * to change to a different one. The submit handler changes the next form
624
 * to the move content form, which is 'hidden' so it won't be accessed
625
 * directly.
626
 */
627
function panels_panel_context_edit_layout($form, &$form_state) {
628
  ctools_include('common', 'panels');
629
  ctools_include('display-layout', 'panels');
630
  ctools_include('plugins', 'panels');
631

    
632
  // @todo -- figure out where/how to deal with this.
633
  $form_state['allowed_layouts'] = 'panels_page';
634

    
635
  $form_state['display'] = &panels_panel_context_get_display($form_state['handler']);
636

    
637
  // Tell the Panels form not to display buttons.
638
  $form_state['no buttons'] = TRUE;
639

    
640
  // Change the #id of the form so the CSS applies properly.
641
  $form['#id'] = 'panels-choose-layout';
642
  $form = panels_choose_layout($form, $form_state);
643

    
644
  return $form;
645
}
646

    
647
/**
648
 * Validate that a layout was chosen.
649
 */
650
function panels_panel_context_edit_layout_validate(&$form, &$form_state) {
651
  $display = &panels_panel_context_get_display($form_state['handler']);
652

    
653
  if (empty($form_state['values']['layout'])) {
654
    form_error($form['layout'], t('You must select a layout.'));
655
  }
656
  if ($form_state['values']['layout'] == $display->layout) {
657
    form_error($form['layout'], t('You must select a different layout if you wish to change layouts.'));
658
  }
659
}
660

    
661
/**
662
 * A layout has been selected, set it up.
663
 */
664
function panels_panel_context_edit_layout_submit(&$form, &$form_state) {
665
  $display = &panels_panel_context_get_display($form_state['handler']);
666

    
667
  if ($form_state['values']['layout'] != $display->layout) {
668
    $form_state['handler']->conf['temp_layout'] = $form_state['values']['layout'];
669
  }
670
}
671

    
672
/**
673
 * When a layout is changed, the user is given the opportunity to move content.
674
 */
675
function panels_panel_context_edit_move($form, &$form_state) {
676
  $form_state['display'] = &panels_panel_context_get_display($form_state['handler']);
677
  $form_state['layout'] = $form_state['handler']->conf['temp_layout'];
678

    
679
  $form_state['cache_key'] = panels_panel_context_cache_key($form_state['task_name'], $form_state['handler_id'], array());
680

    
681
  ctools_include('common', 'panels');
682
  ctools_include('display-layout', 'panels');
683
  ctools_include('plugins', 'panels');
684

    
685
  // Tell the Panels form not to display buttons.
686
  $form_state['no buttons'] = TRUE;
687

    
688
  // Change the #id of the form so the CSS applies properly.
689
  $form = panels_change_layout($form, $form_state);
690

    
691
  // Change the 'back' button to just go directly to the previous form
692
//  $task_id = $form_state['task']['name'];
693
//  $handler_id = $form_state['handler']->handler;
694
//  $name = $form_state['handler']->name;
695

    
696
  // This form is outside the normal wizard list, so we need to specify the
697
  // previous/next forms.
698
  $form['buttons']['previous']['#next'] = 'layout';
699
  $form['buttons']['next']['#next'] = 'content';
700

    
701
  $form_state['form_info']['return path'] = page_manager_edit_url($form_state['page']->task_name, array('handlers', $form_state['handler_id'], 'content'));
702
  return $form;
703
}
704

    
705
/**
706
 * Present the panels drag & drop editor to edit the display attached
707
 * to the task handler.
708
 */
709
function panels_panel_context_edit_content($form, &$form_state) {
710
  ctools_include('ajax');
711
  ctools_include('plugins', 'panels');
712
  ctools_include('common', 'panels');
713
  ctools_include('context');
714
  ctools_include('context-task-handler');
715

    
716
  $cache = panels_edit_cache_get(panels_panel_context_cache_key($form_state['task_name'], $form_state['handler_id'], array()));
717

    
718
  $form_state['renderer'] = panels_get_renderer_handler('editor', $cache->display);
719
  $form_state['renderer']->cache = &$cache;
720

    
721
  $form_state['display'] = &$cache->display;
722
  $form_state['content_types'] = $cache->content_types;
723
  // Tell the Panels form not to display buttons.
724
  $form_state['no buttons'] = TRUE;
725
  $form_state['display_title'] = !empty($cache->display_title);
726
  $form_state['no preview'] = TRUE;
727
  $form_state['page']->display_cache[$form_state['handler_id']] = $cache;
728

    
729
  $form = panels_edit_display_form($form, $form_state);
730

    
731
  if (!isset($form_state['type']) || $form_state['type'] != 'add' && !empty($form_state['handler_id']) && !empty($form['buttons'])) {
732
    $form['buttons']['preview'] = $form['buttons']['return'];
733
    $form['buttons']['preview']['#value'] = t('Update and preview');
734
  }
735
  return $form;
736
}
737

    
738
/**
739
 * Validate changes to the panel content form.
740
 */
741
function panels_panel_context_edit_content_validate(&$form, &$form_state) {
742
  panels_edit_display_form_validate($form, $form_state);
743
}
744

    
745
function panels_panel_context_edit_content_submit(&$form, &$form_state) {
746
  // Update the storage_id if this is a new variant before saving.
747
  if ($form_state['display']->storage_id == 'new') {
748
    $form_state['display']->storage_id = $form_state['handler_id'];
749
  }
750
  panels_edit_display_form_submit($form, $form_state);
751
  $handler = &$form_state['handler'];
752

    
753
  // update the cached display:
754
  $display = $form_state['page']->display_cache[$form_state['handler_id']]->display;
755
  $handler->conf['display'] = $display;
756
  unset($form_state['page']->display_cache[$form_state['handler_id']]);
757

    
758
  if ($form_state['clicked_button']['#value'] == t('Update and preview')) {
759
    $form_state['new trail'] = array('handlers', $form_state['handler_id'], 'preview');
760
  }
761
}
762

    
763
/**
764
 * General settings for the panel
765
 */
766
function panels_panel_context_edit_settings($form, &$form_state) {
767
  $conf = $form_state['handler']->conf;
768
  $form['conf']['title'] = array(
769
    '#type' => 'textfield',
770
    '#default_value' => $conf['title'],
771
    '#title' => t('Administrative title'),
772
    '#description' => t('Administrative title of this variant.'),
773
  );
774

    
775
  $form['conf']['no_blocks'] = array(
776
    '#type' => 'checkbox',
777
    '#default_value' => $conf['no_blocks'],
778
    '#title' => t('Disable Drupal blocks/regions'),
779
    '#description' => t('Check this to have the page disable all regions displayed in the theme. Note that some themes support this setting better than others. If in doubt, try with stock themes to see.'),
780
  );
781

    
782
  $form['conf']['body_classes_to_remove'] = array(
783
    '#type' => 'textfield',
784
    '#size' => 128,
785
    '#default_value' => empty($conf['body_classes_to_remove']) ? '' : $conf['body_classes_to_remove'],
786
    '#title' => t('Remove body CSS classes'),
787
    '#description' => t('The CSS classes to remove from the body element of this page. Separated by a space. For example: no-sidebars one-sidebar sidebar-first sidebar-second two-sidebars. Keywords from context are allowed.'),
788
  );
789

    
790
  $form['conf']['body_classes_to_add'] = array(
791
    '#type' => 'textfield',
792
    '#size' => 128,
793
    '#default_value' => empty($conf['body_classes_to_add']) ? '' : $conf['body_classes_to_add'],
794
    '#title' => t('Add body CSS classes'),
795
    '#description' => t('The CSS classes to add to the body element of this page. Separated by a space. For example: no-sidebars one-sidebar sidebar-first sidebar-second two-sidebars. Keywords from context are allowed.'),
796
  );
797

    
798
  ctools_include('plugins', 'panels');
799
  $pipelines = panels_get_renderer_pipelines();
800

    
801
  // Handle backward compatibility with the IPE checkbox.
802
  if (empty($conf['pipeline'])) {
803
    $conf['pipeline'] = !empty($conf['use_ipe']) ? 'ipe' : 'standard';
804
  }
805

    
806
  // If there are no pipelines, that probably means we're operating in
807
  // legacy mode.
808
  if (empty($pipelines)) {
809
    // We retain the original pipeline so we don't wreck things by installing
810
    // old modules.
811
    $form['conf']['pipeline'] = array(
812
      '#type' => 'value',
813
      '#value' => $conf['pipeline'],
814
    );
815
  }
816
  else {
817
    $options = array();
818
    foreach ($pipelines as $name => $pipeline) {
819
      $options[$name] = check_plain($pipeline->admin_title) . '<div class="description">' . check_plain($pipeline->admin_description) . '</div>';
820
    }
821

    
822
    $form['conf']['pipeline'] = array(
823
      '#type' => 'radios',
824
      '#options' => $options,
825
      '#title' => t('Renderer'),
826
      '#default_value' => $conf['pipeline'],
827
    );
828
  }
829

    
830
  $form['conf']['css_id'] = array(
831
    '#type' => 'textfield',
832
    '#size' => 35,
833
    '#default_value' => $conf['css_id'],
834
    '#title' => t('CSS ID'),
835
    '#description' => t('The CSS ID to apply to this page. Keywords from context are allowed.'),
836
  );
837

    
838
  $form['conf']['css'] = array(
839
    '#type' => 'textarea',
840
    '#title' => t('CSS code'),
841
    '#description' => t('Enter well-formed CSS code here; this code will be embedded into the page, and should only be used for minor adjustments; it is usually better to try to put CSS for the page into the theme if possible. This CSS will be filtered for safety so some CSS may not work. Keywords from context are allowed.'),
842
    '#default_value' => $conf['css'],
843
  );
844

    
845
  return $form;
846
}
847

    
848
/**
849
 * Submit handler for general settings form.
850
 */
851
function panels_panel_context_edit_settings_submit(&$form, &$form_state) {
852
  $form_state['handler']->conf['no_blocks'] = $form_state['values']['no_blocks'];
853
  $form_state['handler']->conf['body_classes_to_remove'] = $form_state['values']['body_classes_to_remove'];
854
  $form_state['handler']->conf['body_classes_to_add'] = $form_state['values']['body_classes_to_add'];
855
  $form_state['handler']->conf['pipeline'] = $form_state['values']['pipeline'];
856
  $form_state['handler']->conf['css_id'] = $form_state['values']['css_id'];
857
  $form_state['handler']->conf['css'] = $form_state['values']['css'];
858
  $form_state['handler']->conf['title'] = $form_state['values']['title'];
859

    
860
  // Unset the old checkbox so we don't store needless data.
861
  if (isset($form_state['handler']->conf['use_ipe'])) {
862
    unset($form_state['handler']->conf['use_ipe']);
863
  }
864
}
865

    
866
/**
867
 * Form to show a nice preview.
868
 */
869
function panels_panel_context_edit_preview($form, &$form_state) {
870
  ctools_include('context');
871
  ctools_include('context-task-handler');
872

    
873
  $contexts = ctools_context_handler_get_all_contexts($form_state['task'], $form_state['subtask'], $form_state['handler']);
874
  $form['preview'] = array();
875
  ctools_context_replace_form($form['preview'], $contexts);
876

    
877
  // automatically preview if there are no argument placeholders.
878
  if (empty($form['preview'])) {
879
    $display = panels_panel_context_get_display($form_state['handler']);
880
    $display->context = $contexts;
881
    $display->skip_cache = TRUE;
882
    $output = panels_render_display($display);
883
    if (isset($form['buttons'])) {
884
      unset($form['buttons']);
885
    }
886
  }
887
  else {
888
    $form['preview']['#tree'] = TRUE;
889
    $form_state['contexts'] = $contexts;
890
  }
891

    
892
  if (!empty($output)) {
893
    $form['output'] = array(
894
      '#markup' => $output,
895
    );
896
  }
897

    
898
  $form_state['do not cache'] = TRUE;
899

    
900
  return $form;
901
}
902

    
903
/**
904
 * Display a preview upon submit if arguments were needed.
905
 */
906
function panels_panel_context_edit_preview_submit(&$form, &$form_state) {
907
  $display = panels_panel_context_get_display($form_state['handler']);
908
  $display->context = ctools_context_replace_placeholders($form_state['contexts'], $form_state['values']['preview']);
909

    
910
  $form_state['content'] = panels_render_display($display);
911
  $form_state['redirect'] = FALSE;
912
  $form_state['rerender'] = TRUE;
913
}
914

    
915
function panels_panel_context_get_addressable($task, $subtask_name, $handler, $address, $contexts, $arguments, $type) {
916
  // Load the display
917
  $display = panels_panel_context_get_display($handler);
918

    
919
  $display->context = $contexts;
920
  $display->args = $arguments;
921
  $display->css_id = $handler->conf['css_id'];
922
  $display->cache_key = panels_panel_context_cache_key($task->name, $handler->name, $arguments);
923

    
924
  $renderer = panels_get_renderer($handler->conf['pipeline'], $display);
925
  $renderer->prepare();
926

    
927
  if ($address) {
928
    $pid = array_shift($address);
929
    if (!empty($renderer->prepared['panes'][$pid])) {
930
      if ($type == 'content') {
931
        return $renderer->render_pane($renderer->prepared['panes'][$pid]);
932
      }
933
      elseif ($type == 'pane') {
934
        return $renderer->prepared['panes'][$pid];
935
      }
936
    }
937
  }
938
  else {
939
    if ($type == 'content') {
940
      return $renderer->render();
941
    }
942
    elseif ($type == 'renderer') {
943
      return $renderer;
944
    }
945
  }
946
}