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 85ad3d82 Assos Assos
<?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 5a7e6170 Florent Torregrosa
    'pipeline' => variable_get('panels_renderer_default', 'standard'),
188 85ad3d82 Assos Assos
    '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 5a7e6170 Florent Torregrosa
/**
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 85ad3d82 Assos Assos
/**
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 5a7e6170 Florent Torregrosa
  $display->cache_key = panels_panel_context_cache_key($task_name, $handler->name, $args);
293 85ad3d82 Assos Assos
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 5a7e6170 Florent Torregrosa
  // 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 85ad3d82 Assos Assos
317
  // Remove and add body element classes
318
  $panel_body_css = &drupal_static('panel_body_css');
319
320 e4c061ad Assos Assos
  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 85ad3d82 Assos Assos
  }
328 e4c061ad Assos Assos
  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 85ad3d82 Assos Assos
  }
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 5a7e6170 Florent Torregrosa
  $display = (object) array(
407
    'did' => 'new',
408
    'uuid' => ctools_uuid_generate(),
409
  );
410 85ad3d82 Assos Assos
  $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 5a7e6170 Florent Torregrosa
  $form_state['cache_key'] = panels_panel_context_cache_key($form_state['task_name'], $form_state['handler_id'], array());
675 85ad3d82 Assos Assos
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 5a7e6170 Florent Torregrosa
  $cache = panels_edit_cache_get(panels_panel_context_cache_key($form_state['task_name'], $form_state['handler_id'], array()));
712 85ad3d82 Assos Assos
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 e4c061ad Assos Assos
    '#default_value' => empty($conf['body_classes_to_remove']) ? '' : $conf['body_classes_to_remove'],
777 85ad3d82 Assos Assos
    '#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 e4c061ad Assos Assos
    '#default_value' => empty($conf['body_classes_to_add']) ? '' : $conf['body_classes_to_add'],
785 85ad3d82 Assos Assos
    '#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 5a7e6170 Florent Torregrosa
  $display->cache_key = panels_panel_context_cache_key($task->name, $handler->name, $arguments);
914 85ad3d82 Assos Assos
915
  $renderer = panels_get_renderer($handler->conf['pipeline'], $display);
916 5a7e6170 Florent Torregrosa
  $renderer->prepare();
917 85ad3d82 Assos Assos
918 5a7e6170 Florent Torregrosa
  if ($address) {
919 85ad3d82 Assos Assos
    $pid = array_shift($address);
920
    if (!empty($renderer->prepared['panes'][$pid])) {
921 5a7e6170 Florent Torregrosa
      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 85ad3d82 Assos Assos
    }
936
  }
937
}