Projet

Général

Profil

Paste
Télécharger (31,9 ko) Statistiques
| Branche: | Révision:

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

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
    return $handler->conf['display'];
224
  }
225

    
226
  if (isset($handler->conf['did'])) {
227
    $handler->conf['display'] = panels_load_display($handler->conf['did']);
228

    
229
    // Check for a valid display. If no valid display can be loaded, something
230
    // is wrong and we'll create a new one.
231
    if (!empty($handler->conf['display'])) {
232
      return $handler->conf['display'];
233
    }
234
  }
235

    
236
  $handler->conf['display'] = panels_new_display();
237

    
238
  return $handler->conf['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
  $display->css_id = $handler->conf['css_id'];
290
  $task_name = page_manager_make_task_name($handler->task, $handler->subtask);
291

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

    
294
  // Check to see if there is any CSS.
295
  if (!empty($handler->conf['css'])) {
296
    ctools_include('css');
297
    $css_id = 'panel_context:' . $handler->name;
298
    $filename = ctools_css_retrieve($css_id);
299
    if (!$filename) {
300
      $filename = ctools_css_store($css_id, $handler->conf['css']);
301
    }
302
    drupal_add_css($filename);
303
  }
304

    
305
  // With an argument, this actually sets the display.
306
  panels_get_current_page_display($display);
307

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

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

    
317
  // Remove and add body element classes
318
  $panel_body_css = &drupal_static('panel_body_css');
319

    
320
  if (isset($handler->conf['body_classes_to_remove']) && !isset($panel_body_css['body_classes_to_remove'])) {
321
    $panel_body_css['body_classes_to_remove'] = $handler->conf['body_classes_to_remove'];
322
  }
323
  if (isset($handler->conf['body_classes_to_add']) && !isset($panel_body_css['body_classes_to_add'])) {
324
    $panel_body_css['body_classes_to_add'] = $handler->conf['body_classes_to_add'];
325
  }
326

    
327
  $info = array(
328
    'content' => panels_render_display($display, $renderer),
329
    'no_blocks' => !empty($handler->conf['no_blocks']),
330
  );
331

    
332
  $info['title'] = $display->get_title();
333

    
334
  return $info;
335
}
336

    
337
/**
338
 * Callback to allow the handler to react to being saved.
339
 *
340
 * When a handler with a display is saved, two things have to happen.
341
 * First, we have to save the display so that it becomes a real display,
342
 * not the fake one we started with. Second, we have to cache
343
 * any CSS that the display is using. This CSS can get re-cached
344
 * later if the file disappears, but it's imperative that we do it here
345
 * to make sure that old, dirty CSS cache gets removed.
346
 */
347
function panels_panel_context_save(&$handler, $update) {
348
  // Only save the display if we believe it has been modified.
349
  if (isset($handler->conf['display'])) {
350
    panels_save_display($handler->conf['display']);
351
    $handler->conf['did'] = $handler->conf['display']->did;
352
    unset($handler->conf['display']);
353
  }
354

    
355
  // Delete any previous CSS cache file.
356
  ctools_include('css');
357
  ctools_css_clear('panel_context:' . $handler->name);
358

    
359
  if (isset($page->conf['temp_layout'])) {
360
    unset($page->conf['temp_layout']);
361
  }
362
}
363

    
364
/**
365
 * Special handling for exporting a panel task handler.
366
 *
367
 * When a panel is exported, we need to export the display separately
368
 * rather than just letting its object be unpacked, which does not work
369
 * very well.
370
 */
371
function panels_panel_context_export(&$handler, $indent) {
372
  $display = panels_panel_context_get_display($handler);
373
  foreach (array('display', 'did', 'css_cache', 'temp_layout') as $item) {
374
    if (isset($handler->conf[$item])) {
375
      unset($handler->conf[$item]);
376
    }
377
  }
378

    
379
  $output = panels_export_display($display, $indent);
380
  $output .= $indent . '$handler->conf[\'display\'] = $display' . ";\n";
381
  return $output;
382
}
383

    
384
/**
385
 * When a handler is cloned, we have to clone the display.
386
 */
387
  function panels_panel_context_clone(&$handler) {
388
  $old_display = panels_panel_context_get_display($handler);
389
  $code = panels_export_display($old_display);
390
  eval($code);
391
  foreach (array('display', 'did', 'css_cache', 'temp_layout') as $item) {
392
    if (isset($handler->conf[$item])) {
393
      unset($handler->conf[$item]);
394
    }
395
  }
396
  $display = (object) array(
397
    'did' => 'new',
398
    'uuid' => ctools_uuid_generate(),
399
  );
400
  $handler->conf['display'] = $display;
401
}
402

    
403
/**
404
 * Callback to delete the display when a handler is deleted.
405
 */
406
function panels_panel_context_delete(&$handler) {
407
  if (!empty($handler->conf['did'])) {
408
    panels_delete_display($handler->conf['did']);
409
  }
410
}
411

    
412
/**
413
 * Set up a title for the panel based upon the selection rules.
414
 */
415
function panels_panel_context_title($handler, $task, $subtask) {
416
  if (isset($handler->conf['title'])) {
417
    return check_plain($handler->conf['title']);
418
  }
419
  else {
420
    return t('Panel');
421
  }
422
}
423

    
424
/**
425
 * Provide a nice little summary of what's in a panel.
426
 *
427
 * The task handler manager provides a summary of a given handler in a
428
 * collapsible div. This callback provides that. For a Panel, we
429
 * provide a summary of the layout type and content on one side, and
430
 * a summary of the contexts in use on the other.
431
 */
432
function panels_panel_context_admin_summary($handler, $task, $subtask, $page, $show_title = TRUE) {
433
  $task_name = page_manager_make_task_name($task['name'], $subtask['name']);
434
  $output = '';
435

    
436
  $display = panels_panel_context_get_display($handler);
437

    
438
  ctools_include('plugins', 'panels');
439
  ctools_include('context');
440
  ctools_include('context-task-handler');
441

    
442
  // Get the operations
443
  $operations = page_manager_get_operations($page);
444

    
445
  // Get operations for just this handler.
446
  $operations = $operations['handlers']['children'][$handler->name]['children']['actions']['children'];
447
  $args = array('handlers', $handler->name, 'actions');
448
  $rendered_operations = page_manager_render_operations($page, $operations, array(), array('class' => array('actions')), 'actions', $args);
449

    
450
  $layout = panels_get_layout($display->layout);
451

    
452
  $plugin = page_manager_get_task_handler($handler->handler);
453

    
454
  $object = ctools_context_handler_get_task_object($task, $subtask, $handler);
455
  $display->context = ctools_context_load_contexts($object, TRUE);
456

    
457
  $access = ctools_access_group_summary(!empty($handler->conf['access']) ? $handler->conf['access'] : array(), $display->context);
458
  if ($access) {
459
    $access = t('This panel will be selected if @conditions.', array('@conditions' => $access));
460
  }
461
  else {
462
    $access = t('This panel will always be selected.');
463
  }
464

    
465
  $rows = array();
466

    
467
  $type = $handler->type == t('Default') ? t('In code') : $handler->type;
468
  $rows[] = array(
469
    array('class' => t('page-summary-label'), 'data' => t('Storage')),
470
    array('class' => t('page-summary-data'), 'data' => $type),
471
    array('class' => t('page-summary-operation'), 'data' => ''),
472
  );
473

    
474
  if (!empty($handler->disabled)) {
475
    $link = l(t('Enable'), page_manager_edit_url($task_name, array('handlers', $handler->name, 'actions', 'enable')));
476
    $text = t('Disabled');
477
  }
478
  else {
479
    $link = l(t('Disable'), page_manager_edit_url($task_name, array('handlers', $handler->name, 'actions', 'disable')));
480
    $text = t('Enabled');
481
  }
482

    
483
  $rows[] = array(
484
    array('class' => t('page-summary-label'), 'data' => t('Status')),
485
    array('class' => t('page-summary-data'), 'data' => $text),
486
    array('class' => t('page-summary-operation'), 'data' => $link),
487
  );
488

    
489
  $link = l(t('Edit'), page_manager_edit_url($task_name, array('handlers', $handler->name, 'criteria')));
490
  $rows[] = array(
491
    array('class' => t('page-summary-label'), 'data' => t('Selection rule')),
492
    array('class' => t('page-summary-data'), 'data' => $access),
493
    array('class' => t('page-summary-operation'), 'data' => $link),
494
  );
495

    
496
  $link = l(t('Change layout'), page_manager_edit_url($task_name, array('handlers', $handler->name, 'layout')));
497
  $link .= '<br />' . l(t('Edit content'), page_manager_edit_url($task_name, array('handlers', $handler->name, 'content')));
498
  $link .= '<br />' . l(t('Preview'), page_manager_edit_url($task_name, array('handlers', $handler->name, 'preview')));
499
  $rows[] = array(
500
    array('class' => t('page-summary-label'), 'data' => t('Layout')),
501
    array('class' => t('page-summary-data'), 'data' => check_plain($layout['title'])),
502
    array('class' => t('page-summary-operation'), 'data' => $link),
503
  );
504

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

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

    
510
  $title = $handler->conf['title'];
511
  if ($title != t('Panel')) {
512
    $title = t('Panel: @title', array('@title' => $title));
513
  }
514

    
515
  $output .= '<div class="clearfix">';
516
  if ($show_title) {
517
  $output .= '<div class="handler-title clearfix">';
518
    $output .= '<div class="actions handler-actions">' . $rendered_operations['actions'] . '</div>';
519
    $output .= '<span class="title-label">' . $title . '</span>';
520
  }
521

    
522
  $output .= '</div>';
523
  $output .= $info;
524
  $output .= '</div>';
525
/*
526
  $output .= '<div class="right-container">';
527
  $output .= '<h3 class="context-title">' . t('Contexts') . $context_link . '</h3>';
528
  $output .= $contexts;
529
  $output .= '</div>';
530

    
531
  $output .= '<div class="left-container">';
532
//  $output .= $icon;
533
  $output .= '<h3 class="handler-title">' . t('Content') . $content_link . '</h3>';
534
  $output .= $content;
535
  $output .= '</div>';
536
*/
537
  return $output;
538
}
539

    
540
// --------------------------------------------------------------------------
541
// Forms
542

    
543
/**
544
 * General notes about forms: The handler is automatically cached by the form
545
 * wizard, so anything we store on $form_state['handler'] anywhere will get
546
 * saved and appear on the next form. The cache is a 'working' cache and
547
 * if the user hits cancel on any page of the multi-page wizard, all
548
 * changes since the last 'update/finish' click will be flushed away.
549
 *
550
 * Many of the Panels forms call through to the real Panels cousins. These
551
 * forms are smart enough to know that they're being wrapped in another
552
 * form and act appropriately. Some of them are so smart that we just let
553
 * their submit and validate handlers do the work rather than writing
554
 * additional ones here.
555
 */
556

    
557
/**
558
 * Choose a layout for this panel.
559
 *
560
 * This is only called during 'add', when we know that there isn't a
561
 * previous layout to choose from. a different, only slightly different
562
 * variant is called to change a pre-existing layout.
563
 */
564
function panels_panel_context_edit_choose($form, &$form_state) {
565
  ctools_include('common', 'panels');
566
  ctools_include('display-layout', 'panels');
567
  ctools_include('plugins', 'panels');
568

    
569
  // @todo -- figure out where/how to deal with this.
570
  $form_state['allowed_layouts'] = 'panels_page';
571

    
572
  $form_state['display'] = &panels_panel_context_get_display($form_state['handler']);
573

    
574
  // Tell the Panels form not to display buttons.
575
  $form_state['no buttons'] = TRUE;
576

    
577
  // Change the #id of the form so the CSS applies properly.
578
  $form['#id'] = 'panels-choose-layout';
579
  $form = panels_choose_layout($form, $form_state);
580

    
581
  return $form;
582
}
583

    
584
/**
585
 * Validate that a layout was chosen.
586
 */
587
function panels_panel_context_edit_choose_validate(&$form, &$form_state) {
588
  if (empty($form_state['values']['layout'])) {
589
    form_error($form['layout'], t('You must select a layout.'));
590
  }
591
}
592

    
593
/**
594
 * A layout has been selected, set it up.
595
 */
596
function panels_panel_context_edit_choose_submit(&$form, &$form_state) {
597
  $form_state['display']->layout = $form_state['values']['layout'];
598
  $form_state['handler']->conf['display'] = $form_state['display'];
599
  if (isset($form_state['page']->display_cache[$form_state['handler_id']])) {
600
    $form_state['page']->display_cache[$form_state['handler_id']]->display = $form_state['display'];
601
  }
602
}
603

    
604
/**
605
 * Change the layout for this panel.
606
 *
607
 * This form is only used if a layout already exists and the user wants
608
 * to change to a different one. The submit handler changes the next form
609
 * to the move content form, which is 'hidden' so it won't be accessed
610
 * directly.
611
 */
612
function panels_panel_context_edit_layout($form, &$form_state) {
613
  ctools_include('common', 'panels');
614
  ctools_include('display-layout', 'panels');
615
  ctools_include('plugins', 'panels');
616

    
617
  // @todo -- figure out where/how to deal with this.
618
  $form_state['allowed_layouts'] = 'panels_page';
619

    
620
  $form_state['display'] = &panels_panel_context_get_display($form_state['handler']);
621

    
622
  // Tell the Panels form not to display buttons.
623
  $form_state['no buttons'] = TRUE;
624

    
625
  // Change the #id of the form so the CSS applies properly.
626
  $form['#id'] = 'panels-choose-layout';
627
  $form = panels_choose_layout($form, $form_state);
628

    
629
  return $form;
630
}
631

    
632
/**
633
 * Validate that a layout was chosen.
634
 */
635
function panels_panel_context_edit_layout_validate(&$form, &$form_state) {
636
  $display = &panels_panel_context_get_display($form_state['handler']);
637

    
638
  if (empty($form_state['values']['layout'])) {
639
    form_error($form['layout'], t('You must select a layout.'));
640
  }
641
  if ($form_state['values']['layout'] == $display->layout) {
642
    form_error($form['layout'], t('You must select a different layout if you wish to change layouts.'));
643
  }
644
}
645

    
646
/**
647
 * A layout has been selected, set it up.
648
 */
649
function panels_panel_context_edit_layout_submit(&$form, &$form_state) {
650
  $display = &panels_panel_context_get_display($form_state['handler']);
651

    
652
  if ($form_state['values']['layout'] != $display->layout) {
653
    $form_state['handler']->conf['temp_layout'] = $form_state['values']['layout'];
654
  }
655
}
656

    
657
/**
658
 * When a layout is changed, the user is given the opportunity to move content.
659
 */
660
function panels_panel_context_edit_move($form, &$form_state) {
661
  $form_state['display'] = &panels_panel_context_get_display($form_state['handler']);
662
  $form_state['layout'] = $form_state['handler']->conf['temp_layout'];
663

    
664
  $form_state['cache_key'] = panels_panel_context_cache_key($form_state['task_name'], $form_state['handler_id'], array());
665

    
666
  ctools_include('common', 'panels');
667
  ctools_include('display-layout', 'panels');
668
  ctools_include('plugins', 'panels');
669

    
670
  // Tell the Panels form not to display buttons.
671
  $form_state['no buttons'] = TRUE;
672

    
673
  // Change the #id of the form so the CSS applies properly.
674
  $form = panels_change_layout($form, $form_state);
675

    
676
  // Change the 'back' button to just go directly to the previous form
677
//  $task_id = $form_state['task']['name'];
678
//  $handler_id = $form_state['handler']->handler;
679
//  $name = $form_state['handler']->name;
680

    
681
  // This form is outside the normal wizard list, so we need to specify the
682
  // previous/next forms.
683
  $form['buttons']['previous']['#next'] = 'layout';
684
  $form['buttons']['next']['#next'] = 'content';
685

    
686
  $form_state['form_info']['return path'] = page_manager_edit_url($form_state['page']->task_name, array('handlers', $form_state['handler_id'], 'content'));
687
  return $form;
688
}
689

    
690
/**
691
 * Present the panels drag & drop editor to edit the display attached
692
 * to the task handler.
693
 */
694
function panels_panel_context_edit_content($form, &$form_state) {
695
  ctools_include('ajax');
696
  ctools_include('plugins', 'panels');
697
  ctools_include('common', 'panels');
698
  ctools_include('context');
699
  ctools_include('context-task-handler');
700

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

    
703
  $form_state['renderer'] = panels_get_renderer_handler('editor', $cache->display);
704
  $form_state['renderer']->cache = &$cache;
705

    
706
  $form_state['display'] = &$cache->display;
707
  $form_state['content_types'] = $cache->content_types;
708
  // Tell the Panels form not to display buttons.
709
  $form_state['no buttons'] = TRUE;
710
  $form_state['display_title'] = !empty($cache->display_title);
711
  $form_state['no preview'] = TRUE;
712
  $form_state['page']->display_cache[$form_state['handler_id']] = $cache;
713

    
714
  $form = panels_edit_display_form($form, $form_state);
715

    
716
  if (!isset($form_state['type']) || $form_state['type'] != 'add' && !empty($form_state['handler_id']) && !empty($form['buttons'])) {
717
    $form['buttons']['preview'] = $form['buttons']['return'];
718
    $form['buttons']['preview']['#value'] = t('Update and preview');
719
  }
720
  return $form;
721
}
722

    
723
/**
724
 * Validate changes to the panel content form.
725
 */
726
function panels_panel_context_edit_content_validate(&$form, &$form_state) {
727
  panels_edit_display_form_validate($form, $form_state);
728
}
729

    
730
function panels_panel_context_edit_content_submit(&$form, &$form_state) {
731
  panels_edit_display_form_submit($form, $form_state);
732
  $handler = &$form_state['handler'];
733

    
734
  // update the cached display:
735
  $display = $form_state['page']->display_cache[$form_state['handler_id']]->display;
736
  $handler->conf['display'] = $display;
737
  unset($form_state['page']->display_cache[$form_state['handler_id']]);
738

    
739
  if ($form_state['clicked_button']['#value'] == t('Update and preview')) {
740
    $form_state['new trail'] = array('handlers', $form_state['handler_id'], 'preview');
741
  }
742
}
743

    
744
/**
745
 * General settings for the panel
746
 */
747
function panels_panel_context_edit_settings($form, &$form_state) {
748
  $conf = $form_state['handler']->conf;
749
  $form['conf']['title'] = array(
750
    '#type' => 'textfield',
751
    '#default_value' => $conf['title'],
752
    '#title' => t('Administrative title'),
753
    '#description' => t('Administrative title of this variant.'),
754
  );
755

    
756
  $form['conf']['no_blocks'] = array(
757
    '#type' => 'checkbox',
758
    '#default_value' => $conf['no_blocks'],
759
    '#title' => t('Disable Drupal blocks/regions'),
760
    '#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.'),
761
  );
762

    
763
  $form['conf']['body_classes_to_remove'] = array(
764
    '#type' => 'textfield',
765
    '#size' => 128,
766
    '#default_value' => $conf['body_classes_to_remove'],
767
    '#title' => t('Remove body CSS classes'),
768
    '#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.'),
769
  );
770

    
771
  $form['conf']['body_classes_to_add'] = array(
772
    '#type' => 'textfield',
773
    '#size' => 128,
774
    '#default_value' => $conf['body_classes_to_add'],
775
    '#title' => t('Add body CSS classes'),
776
    '#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.'),
777
  );
778

    
779
  ctools_include('plugins', 'panels');
780
  $pipelines = panels_get_renderer_pipelines();
781

    
782
  // Handle backward compatibility with the IPE checkbox.
783
  if (empty($conf['pipeline'])) {
784
    $conf['pipeline'] = !empty($conf['use_ipe']) ? 'ipe' : 'standard';
785
  }
786

    
787
  // If there are no pipelines, that probably means we're operating in
788
  // legacy mode.
789
  if (empty($pipelines)) {
790
    // We retain the original pipeline so we don't wreck things by installing
791
    // old modules.
792
    $form['conf']['pipeline'] = array(
793
      '#type' => 'value',
794
      '#value' => $conf['pipeline'],
795
    );
796
  }
797
  else {
798
    $options = array();
799
    foreach ($pipelines as $name => $pipeline) {
800
      $options[$name] = check_plain($pipeline->admin_title) . '<div class="description">' . check_plain($pipeline->admin_description) . '</div>';
801
    }
802

    
803
    $form['conf']['pipeline'] = array(
804
      '#type' => 'radios',
805
      '#options' => $options,
806
      '#title' => t('Renderer'),
807
      '#default_value' => $conf['pipeline'],
808
    );
809
  }
810

    
811
  $form['conf']['css_id'] = array(
812
    '#type' => 'textfield',
813
    '#size' => 35,
814
    '#default_value' => $conf['css_id'],
815
    '#title' => t('CSS ID'),
816
    '#description' => t('The CSS ID to apply to this page'),
817
  );
818

    
819
  $form['conf']['css'] = array(
820
    '#type' => 'textarea',
821
    '#title' => t('CSS code'),
822
    '#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.'),
823
    '#default_value' => $conf['css'],
824
  );
825

    
826
  return $form;
827
}
828

    
829
/**
830
 * Submit handler for general settings form.
831
 */
832
function panels_panel_context_edit_settings_submit(&$form, &$form_state) {
833
  $form_state['handler']->conf['no_blocks'] = $form_state['values']['no_blocks'];
834
  $form_state['handler']->conf['body_classes_to_remove'] = $form_state['values']['body_classes_to_remove'];
835
  $form_state['handler']->conf['body_classes_to_add'] = $form_state['values']['body_classes_to_add'];
836
  $form_state['handler']->conf['pipeline'] = $form_state['values']['pipeline'];
837
  $form_state['handler']->conf['css_id'] = $form_state['values']['css_id'];
838
  $form_state['handler']->conf['css'] = $form_state['values']['css'];
839
  $form_state['handler']->conf['title'] = $form_state['values']['title'];
840

    
841
  // Unset the old checkbox so we don't store needless data.
842
  if (isset($form_state['handler']->conf['use_ipe'])) {
843
    unset($form_state['handler']->conf['use_ipe']);
844
  }
845
}
846

    
847
/**
848
 * Form to show a nice preview.
849
 */
850
function panels_panel_context_edit_preview($form, &$form_state) {
851
  ctools_include('context');
852
  ctools_include('context-task-handler');
853

    
854
  $contexts = ctools_context_handler_get_all_contexts($form_state['task'], $form_state['subtask'], $form_state['handler']);
855
  $form['preview'] = array();
856
  ctools_context_replace_form($form['preview'], $contexts);
857

    
858
  // automatically preview if there are no argument placeholders.
859
  if (empty($form['preview'])) {
860
    $display = panels_panel_context_get_display($form_state['handler']);
861
    $display->context = $contexts;
862
    $display->skip_cache = TRUE;
863
    $output = panels_render_display($display);
864
    if (isset($form['buttons'])) {
865
      unset($form['buttons']);
866
    }
867
  }
868
  else {
869
    $form['preview']['#tree'] = TRUE;
870
    $form_state['contexts'] = $contexts;
871
  }
872

    
873
  if (!empty($output)) {
874
    $form['output'] = array(
875
      '#markup' => $output,
876
    );
877
  }
878

    
879
  $form_state['do not cache'] = TRUE;
880

    
881
  return $form;
882
}
883

    
884
/**
885
 * Display a preview upon submit if arguments were needed.
886
 */
887
function panels_panel_context_edit_preview_submit(&$form, &$form_state) {
888
  $display = panels_panel_context_get_display($form_state['handler']);
889
  $display->context = ctools_context_replace_placeholders($form_state['contexts'], $form_state['values']['preview']);
890

    
891
  $form_state['content'] = panels_render_display($display);
892
  $form_state['redirect'] = FALSE;
893
  $form_state['rerender'] = TRUE;
894
}
895

    
896
function panels_panel_context_get_addressable($task, $subtask_name, $handler, $address, $contexts, $arguments, $type) {
897
  // Load the display
898
  $display = panels_panel_context_get_display($handler);
899

    
900
  $display->context = $contexts;
901
  $display->args = $arguments;
902
  $display->css_id = $handler->conf['css_id'];
903
  $display->cache_key = panels_panel_context_cache_key($task->name, $handler->name, $arguments);
904

    
905
  $renderer = panels_get_renderer($handler->conf['pipeline'], $display);
906
  $renderer->prepare();
907

    
908
  if ($address) {
909
    $pid = array_shift($address);
910
    if (!empty($renderer->prepared['panes'][$pid])) {
911
      if ($type == 'content') {
912
        return $renderer->render_pane($renderer->prepared['panes'][$pid]);
913
      }
914
      elseif ($type == 'pane') {
915
        return $renderer->prepared['panes'][$pid];
916
      }
917
    }
918
  }
919
  else {
920
    if ($type == 'content') {
921
      return $renderer->render();
922
    }
923
    elseif ($type == 'renderer') {
924
      return $renderer;
925
    }
926
  }
927
}