Projet

Général

Profil

Paste
Télécharger (32,2 ko) Statistiques
| Branche: | Révision:

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

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'])) {
321
    if (!isset($panel_body_css['body_classes_to_remove'])) {
322
      $panel_body_css['body_classes_to_remove'] = $handler->conf['body_classes_to_remove'];
323
    }
324
    else{
325
      $panel_body_css['body_classes_to_remove'] .= ' ' . $handler->conf['body_classes_to_remove'];
326
    }
327
  }
328
  if (isset($handler->conf['body_classes_to_add'])) {
329
    if (!isset($panel_body_css['body_classes_to_add'])) {
330
      $panel_body_css['body_classes_to_add'] = $handler->conf['body_classes_to_add'];
331
    }
332
    else {
333
      $panel_body_css['body_classes_to_add'] .= ' '. $handler->conf['body_classes_to_add'];
334
    }
335
  }
336

    
337
  $info = array(
338
    'content' => panels_render_display($display, $renderer),
339
    'no_blocks' => !empty($handler->conf['no_blocks']),
340
  );
341

    
342
  $info['title'] = $display->get_title();
343

    
344
  return $info;
345
}
346

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

    
365
  // Delete any previous CSS cache file.
366
  ctools_include('css');
367
  ctools_css_clear('panel_context:' . $handler->name);
368

    
369
  if (isset($page->conf['temp_layout'])) {
370
    unset($page->conf['temp_layout']);
371
  }
372
}
373

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

    
389
  $output = panels_export_display($display, $indent);
390
  $output .= $indent . '$handler->conf[\'display\'] = $display' . ";\n";
391
  return $output;
392
}
393

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

    
413
/**
414
 * Callback to delete the display when a handler is deleted.
415
 */
416
function panels_panel_context_delete(&$handler) {
417
  if (!empty($handler->conf['did'])) {
418
    panels_delete_display($handler->conf['did']);
419
  }
420
}
421

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

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

    
446
  $display = panels_panel_context_get_display($handler);
447

    
448
  ctools_include('plugins', 'panels');
449
  ctools_include('context');
450
  ctools_include('context-task-handler');
451

    
452
  // Get the operations
453
  $operations = page_manager_get_operations($page);
454

    
455
  // Get operations for just this handler.
456
  $operations = $operations['handlers']['children'][$handler->name]['children']['actions']['children'];
457
  $args = array('handlers', $handler->name, 'actions');
458
  $rendered_operations = page_manager_render_operations($page, $operations, array(), array('class' => array('actions')), 'actions', $args);
459

    
460
  $layout = panels_get_layout($display->layout);
461

    
462
  $plugin = page_manager_get_task_handler($handler->handler);
463

    
464
  $object = ctools_context_handler_get_task_object($task, $subtask, $handler);
465
  $display->context = ctools_context_load_contexts($object, TRUE);
466

    
467
  $access = ctools_access_group_summary(!empty($handler->conf['access']) ? $handler->conf['access'] : array(), $display->context);
468
  if ($access) {
469
    $access = t('This panel will be selected if @conditions.', array('@conditions' => $access));
470
  }
471
  else {
472
    $access = t('This panel will always be selected.');
473
  }
474

    
475
  $rows = array();
476

    
477
  $type = $handler->type == t('Default') ? t('In code') : $handler->type;
478
  $rows[] = array(
479
    array('class' => t('page-summary-label'), 'data' => t('Storage')),
480
    array('class' => t('page-summary-data'), 'data' => $type),
481
    array('class' => t('page-summary-operation'), 'data' => ''),
482
  );
483

    
484
  if (!empty($handler->disabled)) {
485
    $link = l(t('Enable'), page_manager_edit_url($task_name, array('handlers', $handler->name, 'actions', 'enable')));
486
    $text = t('Disabled');
487
  }
488
  else {
489
    $link = l(t('Disable'), page_manager_edit_url($task_name, array('handlers', $handler->name, 'actions', 'disable')));
490
    $text = t('Enabled');
491
  }
492

    
493
  $rows[] = array(
494
    array('class' => t('page-summary-label'), 'data' => t('Status')),
495
    array('class' => t('page-summary-data'), 'data' => $text),
496
    array('class' => t('page-summary-operation'), 'data' => $link),
497
  );
498

    
499
  $link = l(t('Edit'), page_manager_edit_url($task_name, array('handlers', $handler->name, 'criteria')));
500
  $rows[] = array(
501
    array('class' => t('page-summary-label'), 'data' => t('Selection rule')),
502
    array('class' => t('page-summary-data'), 'data' => $access),
503
    array('class' => t('page-summary-operation'), 'data' => $link),
504
  );
505

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

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

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

    
520
  $title = $handler->conf['title'];
521
  if ($title != t('Panel')) {
522
    $title = t('Panel: @title', array('@title' => $title));
523
  }
524

    
525
  $output .= '<div class="clearfix">';
526
  if ($show_title) {
527
  $output .= '<div class="handler-title clearfix">';
528
    $output .= '<div class="actions handler-actions">' . $rendered_operations['actions'] . '</div>';
529
    $output .= '<span class="title-label">' . $title . '</span>';
530
  }
531

    
532
  $output .= '</div>';
533
  $output .= $info;
534
  $output .= '</div>';
535
/*
536
  $output .= '<div class="right-container">';
537
  $output .= '<h3 class="context-title">' . t('Contexts') . $context_link . '</h3>';
538
  $output .= $contexts;
539
  $output .= '</div>';
540

    
541
  $output .= '<div class="left-container">';
542
//  $output .= $icon;
543
  $output .= '<h3 class="handler-title">' . t('Content') . $content_link . '</h3>';
544
  $output .= $content;
545
  $output .= '</div>';
546
*/
547
  return $output;
548
}
549

    
550
// --------------------------------------------------------------------------
551
// Forms
552

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

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

    
579
  // @todo -- figure out where/how to deal with this.
580
  $form_state['allowed_layouts'] = 'panels_page';
581

    
582
  $form_state['display'] = &panels_panel_context_get_display($form_state['handler']);
583

    
584
  // Tell the Panels form not to display buttons.
585
  $form_state['no buttons'] = TRUE;
586

    
587
  // Change the #id of the form so the CSS applies properly.
588
  $form['#id'] = 'panels-choose-layout';
589
  $form = panels_choose_layout($form, $form_state);
590

    
591
  return $form;
592
}
593

    
594
/**
595
 * Validate that a layout was chosen.
596
 */
597
function panels_panel_context_edit_choose_validate(&$form, &$form_state) {
598
  if (empty($form_state['values']['layout'])) {
599
    form_error($form['layout'], t('You must select a layout.'));
600
  }
601
}
602

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

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

    
627
  // @todo -- figure out where/how to deal with this.
628
  $form_state['allowed_layouts'] = 'panels_page';
629

    
630
  $form_state['display'] = &panels_panel_context_get_display($form_state['handler']);
631

    
632
  // Tell the Panels form not to display buttons.
633
  $form_state['no buttons'] = TRUE;
634

    
635
  // Change the #id of the form so the CSS applies properly.
636
  $form['#id'] = 'panels-choose-layout';
637
  $form = panels_choose_layout($form, $form_state);
638

    
639
  return $form;
640
}
641

    
642
/**
643
 * Validate that a layout was chosen.
644
 */
645
function panels_panel_context_edit_layout_validate(&$form, &$form_state) {
646
  $display = &panels_panel_context_get_display($form_state['handler']);
647

    
648
  if (empty($form_state['values']['layout'])) {
649
    form_error($form['layout'], t('You must select a layout.'));
650
  }
651
  if ($form_state['values']['layout'] == $display->layout) {
652
    form_error($form['layout'], t('You must select a different layout if you wish to change layouts.'));
653
  }
654
}
655

    
656
/**
657
 * A layout has been selected, set it up.
658
 */
659
function panels_panel_context_edit_layout_submit(&$form, &$form_state) {
660
  $display = &panels_panel_context_get_display($form_state['handler']);
661

    
662
  if ($form_state['values']['layout'] != $display->layout) {
663
    $form_state['handler']->conf['temp_layout'] = $form_state['values']['layout'];
664
  }
665
}
666

    
667
/**
668
 * When a layout is changed, the user is given the opportunity to move content.
669
 */
670
function panels_panel_context_edit_move($form, &$form_state) {
671
  $form_state['display'] = &panels_panel_context_get_display($form_state['handler']);
672
  $form_state['layout'] = $form_state['handler']->conf['temp_layout'];
673

    
674
  $form_state['cache_key'] = panels_panel_context_cache_key($form_state['task_name'], $form_state['handler_id'], array());
675

    
676
  ctools_include('common', 'panels');
677
  ctools_include('display-layout', 'panels');
678
  ctools_include('plugins', 'panels');
679

    
680
  // Tell the Panels form not to display buttons.
681
  $form_state['no buttons'] = TRUE;
682

    
683
  // Change the #id of the form so the CSS applies properly.
684
  $form = panels_change_layout($form, $form_state);
685

    
686
  // Change the 'back' button to just go directly to the previous form
687
//  $task_id = $form_state['task']['name'];
688
//  $handler_id = $form_state['handler']->handler;
689
//  $name = $form_state['handler']->name;
690

    
691
  // This form is outside the normal wizard list, so we need to specify the
692
  // previous/next forms.
693
  $form['buttons']['previous']['#next'] = 'layout';
694
  $form['buttons']['next']['#next'] = 'content';
695

    
696
  $form_state['form_info']['return path'] = page_manager_edit_url($form_state['page']->task_name, array('handlers', $form_state['handler_id'], 'content'));
697
  return $form;
698
}
699

    
700
/**
701
 * Present the panels drag & drop editor to edit the display attached
702
 * to the task handler.
703
 */
704
function panels_panel_context_edit_content($form, &$form_state) {
705
  ctools_include('ajax');
706
  ctools_include('plugins', 'panels');
707
  ctools_include('common', 'panels');
708
  ctools_include('context');
709
  ctools_include('context-task-handler');
710

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

    
713
  $form_state['renderer'] = panels_get_renderer_handler('editor', $cache->display);
714
  $form_state['renderer']->cache = &$cache;
715

    
716
  $form_state['display'] = &$cache->display;
717
  $form_state['content_types'] = $cache->content_types;
718
  // Tell the Panels form not to display buttons.
719
  $form_state['no buttons'] = TRUE;
720
  $form_state['display_title'] = !empty($cache->display_title);
721
  $form_state['no preview'] = TRUE;
722
  $form_state['page']->display_cache[$form_state['handler_id']] = $cache;
723

    
724
  $form = panels_edit_display_form($form, $form_state);
725

    
726
  if (!isset($form_state['type']) || $form_state['type'] != 'add' && !empty($form_state['handler_id']) && !empty($form['buttons'])) {
727
    $form['buttons']['preview'] = $form['buttons']['return'];
728
    $form['buttons']['preview']['#value'] = t('Update and preview');
729
  }
730
  return $form;
731
}
732

    
733
/**
734
 * Validate changes to the panel content form.
735
 */
736
function panels_panel_context_edit_content_validate(&$form, &$form_state) {
737
  panels_edit_display_form_validate($form, $form_state);
738
}
739

    
740
function panels_panel_context_edit_content_submit(&$form, &$form_state) {
741
  panels_edit_display_form_submit($form, $form_state);
742
  $handler = &$form_state['handler'];
743

    
744
  // update the cached display:
745
  $display = $form_state['page']->display_cache[$form_state['handler_id']]->display;
746
  $handler->conf['display'] = $display;
747
  unset($form_state['page']->display_cache[$form_state['handler_id']]);
748

    
749
  if ($form_state['clicked_button']['#value'] == t('Update and preview')) {
750
    $form_state['new trail'] = array('handlers', $form_state['handler_id'], 'preview');
751
  }
752
}
753

    
754
/**
755
 * General settings for the panel
756
 */
757
function panels_panel_context_edit_settings($form, &$form_state) {
758
  $conf = $form_state['handler']->conf;
759
  $form['conf']['title'] = array(
760
    '#type' => 'textfield',
761
    '#default_value' => $conf['title'],
762
    '#title' => t('Administrative title'),
763
    '#description' => t('Administrative title of this variant.'),
764
  );
765

    
766
  $form['conf']['no_blocks'] = array(
767
    '#type' => 'checkbox',
768
    '#default_value' => $conf['no_blocks'],
769
    '#title' => t('Disable Drupal blocks/regions'),
770
    '#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.'),
771
  );
772

    
773
  $form['conf']['body_classes_to_remove'] = array(
774
    '#type' => 'textfield',
775
    '#size' => 128,
776
    '#default_value' => empty($conf['body_classes_to_remove']) ? '' : $conf['body_classes_to_remove'],
777
    '#title' => t('Remove body CSS classes'),
778
    '#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.'),
779
  );
780

    
781
  $form['conf']['body_classes_to_add'] = array(
782
    '#type' => 'textfield',
783
    '#size' => 128,
784
    '#default_value' => empty($conf['body_classes_to_add']) ? '' : $conf['body_classes_to_add'],
785
    '#title' => t('Add body CSS classes'),
786
    '#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.'),
787
  );
788

    
789
  ctools_include('plugins', 'panels');
790
  $pipelines = panels_get_renderer_pipelines();
791

    
792
  // Handle backward compatibility with the IPE checkbox.
793
  if (empty($conf['pipeline'])) {
794
    $conf['pipeline'] = !empty($conf['use_ipe']) ? 'ipe' : 'standard';
795
  }
796

    
797
  // If there are no pipelines, that probably means we're operating in
798
  // legacy mode.
799
  if (empty($pipelines)) {
800
    // We retain the original pipeline so we don't wreck things by installing
801
    // old modules.
802
    $form['conf']['pipeline'] = array(
803
      '#type' => 'value',
804
      '#value' => $conf['pipeline'],
805
    );
806
  }
807
  else {
808
    $options = array();
809
    foreach ($pipelines as $name => $pipeline) {
810
      $options[$name] = check_plain($pipeline->admin_title) . '<div class="description">' . check_plain($pipeline->admin_description) . '</div>';
811
    }
812

    
813
    $form['conf']['pipeline'] = array(
814
      '#type' => 'radios',
815
      '#options' => $options,
816
      '#title' => t('Renderer'),
817
      '#default_value' => $conf['pipeline'],
818
    );
819
  }
820

    
821
  $form['conf']['css_id'] = array(
822
    '#type' => 'textfield',
823
    '#size' => 35,
824
    '#default_value' => $conf['css_id'],
825
    '#title' => t('CSS ID'),
826
    '#description' => t('The CSS ID to apply to this page'),
827
  );
828

    
829
  $form['conf']['css'] = array(
830
    '#type' => 'textarea',
831
    '#title' => t('CSS code'),
832
    '#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.'),
833
    '#default_value' => $conf['css'],
834
  );
835

    
836
  return $form;
837
}
838

    
839
/**
840
 * Submit handler for general settings form.
841
 */
842
function panels_panel_context_edit_settings_submit(&$form, &$form_state) {
843
  $form_state['handler']->conf['no_blocks'] = $form_state['values']['no_blocks'];
844
  $form_state['handler']->conf['body_classes_to_remove'] = $form_state['values']['body_classes_to_remove'];
845
  $form_state['handler']->conf['body_classes_to_add'] = $form_state['values']['body_classes_to_add'];
846
  $form_state['handler']->conf['pipeline'] = $form_state['values']['pipeline'];
847
  $form_state['handler']->conf['css_id'] = $form_state['values']['css_id'];
848
  $form_state['handler']->conf['css'] = $form_state['values']['css'];
849
  $form_state['handler']->conf['title'] = $form_state['values']['title'];
850

    
851
  // Unset the old checkbox so we don't store needless data.
852
  if (isset($form_state['handler']->conf['use_ipe'])) {
853
    unset($form_state['handler']->conf['use_ipe']);
854
  }
855
}
856

    
857
/**
858
 * Form to show a nice preview.
859
 */
860
function panels_panel_context_edit_preview($form, &$form_state) {
861
  ctools_include('context');
862
  ctools_include('context-task-handler');
863

    
864
  $contexts = ctools_context_handler_get_all_contexts($form_state['task'], $form_state['subtask'], $form_state['handler']);
865
  $form['preview'] = array();
866
  ctools_context_replace_form($form['preview'], $contexts);
867

    
868
  // automatically preview if there are no argument placeholders.
869
  if (empty($form['preview'])) {
870
    $display = panels_panel_context_get_display($form_state['handler']);
871
    $display->context = $contexts;
872
    $display->skip_cache = TRUE;
873
    $output = panels_render_display($display);
874
    if (isset($form['buttons'])) {
875
      unset($form['buttons']);
876
    }
877
  }
878
  else {
879
    $form['preview']['#tree'] = TRUE;
880
    $form_state['contexts'] = $contexts;
881
  }
882

    
883
  if (!empty($output)) {
884
    $form['output'] = array(
885
      '#markup' => $output,
886
    );
887
  }
888

    
889
  $form_state['do not cache'] = TRUE;
890

    
891
  return $form;
892
}
893

    
894
/**
895
 * Display a preview upon submit if arguments were needed.
896
 */
897
function panels_panel_context_edit_preview_submit(&$form, &$form_state) {
898
  $display = panels_panel_context_get_display($form_state['handler']);
899
  $display->context = ctools_context_replace_placeholders($form_state['contexts'], $form_state['values']['preview']);
900

    
901
  $form_state['content'] = panels_render_display($display);
902
  $form_state['redirect'] = FALSE;
903
  $form_state['rerender'] = TRUE;
904
}
905

    
906
function panels_panel_context_get_addressable($task, $subtask_name, $handler, $address, $contexts, $arguments, $type) {
907
  // Load the display
908
  $display = panels_panel_context_get_display($handler);
909

    
910
  $display->context = $contexts;
911
  $display->args = $arguments;
912
  $display->css_id = $handler->conf['css_id'];
913
  $display->cache_key = panels_panel_context_cache_key($task->name, $handler->name, $arguments);
914

    
915
  $renderer = panels_get_renderer($handler->conf['pipeline'], $display);
916
  $renderer->prepare();
917

    
918
  if ($address) {
919
    $pid = array_shift($address);
920
    if (!empty($renderer->prepared['panes'][$pid])) {
921
      if ($type == 'content') {
922
        return $renderer->render_pane($renderer->prepared['panes'][$pid]);
923
      }
924
      elseif ($type == 'pane') {
925
        return $renderer->prepared['panes'][$pid];
926
      }
927
    }
928
  }
929
  else {
930
    if ($type == 'content') {
931
      return $renderer->render();
932
    }
933
    elseif ($type == 'renderer') {
934
      return $renderer;
935
    }
936
  }
937
}