Projet

Général

Profil

Révision 5a7e6170

Ajouté par Florent Torregrosa il y a environ 10 ans

Update :

  • panels : 7.x-3.3 -> 7.x-3.4
  • pdf_reader : 7.x-1.0-rc4 -> 7.x-1.0-rc5

Voir les différences:

drupal7/sites/all/modules/panels/i18n_panels/README.txt
1

  
2
This module provides by default the ability to translate panel display and
3
panel pane titles.
4
Further it introduced an extension to the ctools content_types plugin.
5
You can now define translatable settings which will be registered in i18n.
6
Out of the box the module extends the custom content content_type to allow
7
translation of the content.
8

  
9
Requirements:
10
   Ctools 7.x-1.x-dev (Jan 28-2014 or newer)
11
   Panels 7.x-3.x-dev (Jan 28-2014 or newer)
12

  
13
Plugin definition extension:
14
------------------------------
15

  
16
This example shows how the content_type custom is extended:
17

  
18
#### Default: ####
19
/**
20
 * Plugins are described by creating a $plugin array which will be used
21
 * by the system that includes this file.
22
 */
23
$plugin = array(
24
  'title' => t('Custom content'),
25
  'no title override' => TRUE,
26
  'defaults' => array('admin_title' => '', 'title' => '', 'body' => '', 'format' => filter_fallback_format(), 'substitute' => TRUE),
27
  'js' => array('misc/autocomplete.js', 'misc/textarea.js', 'misc/collapse.js'),
28
  // Make sure the edit form is only used for some subtypes.
29
  'edit form' => '',
30
  'add form' => '',
31
  'edit text' => t('Edit'),
32
  'all contexts' => TRUE,
33
);
34

  
35
#### Extended Configuration: ####
36
/**
37
 * Plugins are described by creating a $plugin array which will be used
38
 * by the system that includes this file.
39
 */
40
$plugin = array(
41
  'title' => t('Custom content'),
42
  'no title override' => TRUE,
43
  'defaults' => array('admin_title' => '', 'title' => '', 'body' => '', 'format' => filter_fallback_format(), 'substitute' => TRUE),
44
  'js' => array('misc/autocomplete.js', 'misc/textarea.js', 'misc/collapse.js'),
45
  // Make sure the edit form is only used for some subtypes.
46
  'edit form' => '',
47
  'add form' => '',
48
  'edit text' => t('Edit'),
49
  'all contexts' => TRUE,
50
  'i18n_settings' = array(
51
    'title',
52
    'body' => array('format' => 'plain_text'),
53
    'items|0|title'
54
  ),
55
);
56

  
57
The new key "i18n_settings" defines an array with the settings that are
58
translatable. The array contains the names of the settings, they have to be
59
available in the "defaults" array of the content definition. If you need to
60
define a format use the name of the setting as the array item key and as item
61
another array with the detail configuration. E.g
62
'i18n_settings' = array('body' => array('format' => 'plain_text'))
63

  
64
If i18n_settings is a string it's used as callback. The expected return is an
65
array equal to the one used in the fix configuration.
66
You can even declare nested settings  as translatable, to do so use '|' as
67
delimiter.
68
E.g. 'items|0|title' is evaluated as $settings['items'][0]['title']
69

  
70
#### Callback: ####
71
/**
72
 * Plugins are described by creating a $plugin array which will be used
73
 * by the system that includes this file.
74
 */
75
$plugin = array(
76
  'title' => t('Custom content'),
77
  'no title override' => TRUE,
78
  'defaults' => array('admin_title' => '', 'title' => '', 'body' => '', 'format' => filter_fallback_format(), 'substitute' => TRUE),
79
  'js' => array('misc/autocomplete.js', 'misc/textarea.js', 'misc/collapse.js'),
80
  // Make sure the edit form is only used for some subtypes.
81
  'edit form' => '',
82
  'add form' => '',
83
  'edit text' => t('Edit'),
84
  'all contexts' => TRUE,
85
  'i18n_settings' => 'ctools_custom_content_type_i18n_settings',
86
);
87

  
88
function ctools_custom_content_type_i18n_settings($conf) {
89
  return array(
90
    'title',
91
    'body' => array('format' => $conf['format']),
92
  );
93
}
drupal7/sites/all/modules/panels/i18n_panels/i18n_panels.i18n.inc
1
<?php
2
/**
3
 * @file
4
 * Internationalization (i18n) hooks
5
 */
6

  
7
/**
8
 * Implements hook_i18n_object_info().
9
 */
10
function i18n_panels_i18n_object_info() {
11
  $info['pane_configuration'] = array(
12
    'title' => t('Pane Configuration'),
13
    'key' => 'uuid',
14
    'string translation' => array(
15
      'textgroup' => 'panels',
16
      'type' => 'pane_configuration',
17
      'properties' => array(
18
        'title' => t('Pane Title'),
19
      ),
20
    ),
21
  );
22
  $info['display_configuration'] = array(
23
    'title' => t('Display Configuration'),
24
    'key' => 'uuid',
25
    'string translation' => array(
26
      'textgroup' => 'panels',
27
      'type' => 'display_configuration',
28
      'properties' => array(
29
        'title' => t('Display Title'),
30
      ),
31
    ),
32
  );
33

  
34
  return $info;
35
}
36

  
37
/**
38
 * Implements hook_i18n_string_info().
39
 */
40
function i18n_panels_i18n_string_info() {
41
  $groups['panels'] = array(
42
    'title' => t('Panels'),
43
    'description' => t('Translatable panels items: display and pane configuration items. E.g. Title.'),
44
    // This group doesn't have strings with format.
45
    'format' => FALSE,
46
    // This group can list all strings.
47
    'list' => FALSE,
48
  );
49
  return $groups;
50
}
drupal7/sites/all/modules/panels/i18n_panels/i18n_panels.info
1
name = Panels translation
2
description = Supports translatable panels items.
3
dependencies[] = i18n
4
dependencies[] = panels
5
dependencies[] = i18n_string
6
dependencies[] = i18n_translation
7
package = Multilingual - Internationalization
8
core = 7.x
9

  
10
; Information added by Drupal.org packaging script on 2014-02-12
11
version = "7.x-3.4"
12
core = "7.x"
13
project = "panels"
14
datestamp = "1392221614"
15

  
drupal7/sites/all/modules/panels/i18n_panels/i18n_panels.install
1
<?php
2

  
3
/**
4
 * @file
5
 * Internationalization (i18n) submodule: Panels translation.
6
 */
7

  
8
/**
9
 * Implements hook_requirements().
10
 */
11
function i18n_panels_requirements($phase) {
12
  $requirements = array();
13
  // Check only for status report, to allow update / install.
14
  if ($phase == 'runtime') {
15
    // Check if the panels module runs with uuids.
16
    $requirements['uuid'] = array(
17
      'title' => t('Panels uuid support.'),
18
      'severity' => REQUIREMENT_OK,
19
      'value' => t('Available'),
20
    );
21
    if (!db_field_exists('panels_pane', 'uuid')) {
22
      $requirements['uuid']['severity'] = REQUIREMENT_ERROR;
23
      $requirements['uuid']['value'] = t('Not found. Please apply the provided patches and run the update script.');
24
    }
25
  }
26
  return $requirements;
27
}
drupal7/sites/all/modules/panels/i18n_panels/i18n_panels.module
1
<?php
2

  
3
/**
4
 * @file
5
 * Internationalization (i18n) submodule: Panels translation.
6
 */
7

  
8
/**
9
 * Fetch the i18n_settings of the content type if there are any.
10
 *
11
 * @param stdClass $pane
12
 *   The pane to deal with.
13
 *
14
 * @return array|false
15
 *   Settings or FALSE if none are present.
16
 */
17
function i18n_panels_get_i18n_settings($pane) {
18
  ctools_include('content');
19
  $content_type = ctools_get_content_type($pane->type);
20
  if (isset($content_type['i18n_settings'])) {
21
    if (is_string($content_type['i18n_settings']) && function_exists($content_type['i18n_settings'])) {
22
      $content_type['i18n_settings'] = $content_type['i18n_settings']($pane->configuration);
23
    }
24
  }
25
  // Provide the override title string as translation for all panes that have
26
  // this setting enabled.
27
  if (isset($pane->configuration['override_title']) && $pane->configuration['override_title']) {
28
    if (isset($content_type['i18n_settings']) && is_array($content_type['i18n_settings'])) {
29
      $content_type['i18n_settings'][] = 'override_title_text';
30
    }
31
    else {
32
      $content_type['i18n_settings'] = array('override_title_text');
33
    }
34
  }
35
  return isset($content_type['i18n_settings']) ? $content_type['i18n_settings'] : FALSE;
36
}
37

  
38
/**
39
 * Returns the translation object of the pane.
40
 *
41
 * @param stdClass $pane
42
 *   The pane to deal with.
43
 *
44
 * @return stdClass|FALSE
45
 *   Returns FALSE if no translation is necessary.
46
 */
47
function i18n_panels_get_i18n_translation_object($pane) {
48
  $translation_object = array();
49

  
50
  // Handle content type specific i18n settings.
51
  if ($i18n_settings = i18n_panels_get_i18n_settings($pane)) {
52
    // Register translatable settings.
53
    foreach ($i18n_settings as $i18n_setting => $settings) {
54
      if (!is_array($settings)) {
55
        $i18n_setting = $settings;
56
        $settings = array('format' => 'plain_text');
57
      }
58
      $translation_object[$i18n_setting] = NULL;
59
      $key_exists = FALSE;
60
      // Ensure a nested setting is "unpacked".
61
      $config_value = drupal_array_get_nested_value($pane->configuration, explode('|', $i18n_setting), $key_exists);
62
      // If we reached the end of the nested setting use the value as source.
63
      if ($key_exists) {
64
        $translation_object[$i18n_setting] = array(
65
          'string' => $config_value,
66
          'format' => $settings['format'],
67
        );
68
        $translation_object['panels_i18n_settings'][$i18n_setting] = $settings;
69
      }
70
    }
71
  }
72

  
73
  // Check if this pane has a custom title enabled.
74
  if (!empty($pane->configuration['override_title'])) {
75
    $translation_object['title']['string'] = $pane->configuration['override_title_text'];
76
  }
77
  if (!empty($translation_object)) {
78
    return (object) $translation_object;
79
  }
80
  return FALSE;
81
}
82

  
83
/**
84
 * Implements hook_panels_pane_insert().
85
 *
86
 * @param stdClass $pane
87
 *   The pane to deal with.
88
 */
89
function i18n_panels_panels_pane_insert($pane) {
90
  i18n_panels_panels_pane_update($pane);
91
}
92

  
93
/**
94
 * Implements hook_panels_pane_update().
95
 *
96
 * @param stdClass $pane
97
 *   The pane to deal with.
98
 */
99
function i18n_panels_panels_pane_update($pane) {
100
  if ($translation_object = i18n_panels_get_i18n_translation_object($pane)) {
101
    $translation_object->uuid = $pane->uuid;
102
    $status = i18n_string_object_update('pane_configuration', $translation_object);
103
  }
104
}
105

  
106
/**
107
 * Implements hook_panels_pane_delete().
108
 *
109
 * @param array $pids
110
 *   Array with the panel ids to delete.
111
 */
112
function i18n_panels_panels_pane_delete($pids) {
113
  if (!empty($pids)) {
114
    // Fetch the uuids from the db.
115
    $uuids = db_select('panels_pane')
116
      ->fields('panels_pane', array('uuid'))
117
      ->condition('pid', $pids)
118
      ->execute()
119
      ->fetchCol();
120
    foreach ($uuids as $uuid) {
121
      // Create dummy pane with uuid as property.
122
      $pane = (object) array('uuid' => $uuid);
123
      i18n_string_object_remove('pane_configuration', $pane);
124
    }
125
  }
126
}
127

  
128
/**
129
 * Implements hook_panels_pane_prerender().
130
 *
131
 * @param stdClass $pane
132
 *   The pane to deal with.
133
 */
134
function i18n_panels_panels_pane_prerender($pane) {
135
  // Check if this pane has translations.
136
  if (isset($pane->uuid) && $translation_object = i18n_panels_get_i18n_translation_object($pane)) {
137
    $translation_object->uuid = $pane->uuid;
138
    // Send to translation.
139
    $translation_object = i18n_string_object_translate('pane_configuration', $translation_object);
140
    unset($translation_object->uuid, $translation_object->i18n_settings);
141
    foreach ($translation_object as $i18n_setting => $translated_setting) {
142
      if ($i18n_setting != 'panels_i18n_settings') {
143
        if (is_array($translated_setting)) {
144
          $translated_setting = $translated_setting['string'];
145
        }
146
        drupal_array_set_nested_value($pane->configuration, explode('|', $i18n_setting), $translated_setting);
147
      }
148
    }
149
  }
150
}
151

  
152
/**
153
 * Implements hook_panels_display_save().
154
 *
155
 * @param panels_display $display
156
 *   The display to deal with.
157
 */
158
function i18n_panels_panels_display_save($display) {
159
  $status = i18n_string_object_update('display_configuration', $display);
160
}
161

  
162
/**
163
 * Implements hook_panels_display_delete().
164
 *
165
 * @param int $did
166
 *   Id of the display to delete.
167
 */
168
function i18n_panels_panels_delete_display($did) {
169
  // Fetch uuid to delete the translations.
170
  $uuid = db_select('panels_display')
171
    ->fields('panels_display', array('uuid'))
172
    ->condition('did', $did)
173
    ->execute()
174
    ->fetchColumn();
175
  // Build a dummy display.
176
  $display = (object) array('uuid' => $uuid);
177

  
178
  // Check if this display was just saved in the db.
179
  if (!_18n_panels_is_exported_panels_display($display)) {
180
    // If the display was just saved in the db remove all translations.
181
    i18n_string_object_remove('display_configuration', $display);
182
    // Remove related pane translations too.
183
    $pids = db_select('panels_pane')
184
      ->fields('panels_pane', array('pid'))
185
      ->condition('did', $did)
186
      ->execute()
187
      ->fetchCol();
188
    i18n_panels_panels_pane_delete($pids);
189
  }
190
  else {
191
    // If the display is exported leave the translated strings but give the user
192
    // a hint how to clean up.
193
    drupal_set_message(
194
      t(
195
        'The reverted panels display(s) were exported, please run a <a href="!link">string refresh</a> to update the translatable strings.',
196
        array('!link' => url('admin/config/regional/translate/i18n_string'))
197
      ),
198
      'warning',
199
      FALSE
200
    );
201
  }
202
}
203

  
204
/**
205
 * Implements hook_panels_pre_render().
206
 *
207
 * This function must not rely on the passed $renderer parameter. The parameter
208
 * could be empty because this function is reused in i18n_ctools_render_alter().
209
 * @todo Check if a drupal_alter() in panels_display::get_title() is applicable.
210
 *
211
 * @see i18n_ctools_render_alter()
212
 *
213
 * @param panels_display $display
214
 *   The display to deal with.
215
 * @param panels_renderer_standard $renderer
216
 *   The renderer to deal with.
217
 */
218
function i18n_panels_panels_pre_render(&$display, $renderer) {
219
  // Avoid double translations.
220
  if (!isset($display->i18n_panels_title_translated)) {
221
    $translation = i18n_string_object_translate('display_configuration', $display);
222
    if (is_array($translation->title)) {
223
      $display->title = $translation->title['string'];
224
    }
225
    else {
226
      $display->title = $translation->title;
227
    }
228
    $display->i18n_panels_title_translated = TRUE;
229
  }
230
}
231

  
232
/**
233
 * Implements hook_ctools_render_alter().
234
 *
235
 * Under some circumstances the title of the panel page is set before
236
 * hook_panels_pre_render() is fired. Such cases can be handled with this hook.
237
 * @todo Check if a drupal_alter() in panels_display::get_title() is applicable.
238
 */
239
function i18n_ctools_render_alter(&$info, $page, $context) {
240
  // @todo Find a better way to detect a panels page.
241
  if ($page === TRUE && !empty($info['content']['#display']) && $info['content']['#display'] instanceof panels_display) {
242
    i18n_panels_panels_pre_render($info['content']['#display'], NULL);
243
    // Set the info title. This is used to set the page title.
244
    $info['title'] = $info['content']['#display']->get_title();
245
  }
246
}
247

  
248

  
249
/**
250
 * Implements hook_ctools_plugin_post_alter().
251
 *
252
 * Register some translatable configuration settings for plugins.
253
 *
254
 */
255
function i18n_panels_ctools_plugin_post_alter(&$plugin, $plugin_type_info) {
256
  if ($plugin_type_info['type'] == 'content_types') {
257
    // Modify custom content.
258
    if ($plugin['name'] == 'custom') {
259
      // Register callback to get the translatable settings.
260
      $plugin['i18n_settings'] = 'ctools_custom_content_type_i18n_settings';
261
    }
262
  }
263
}
264

  
265
/**
266
 * Callback to provide the translatable settings appropriate to the config.
267
 *
268
 * @param array $conf
269
 *   Content type configuration.
270
 *
271
 * @return array
272
 *   i18n_settings configuration.
273
 */
274
function ctools_custom_content_type_i18n_settings($conf) {
275
  return array(
276
    'title',
277
    'body' => array('format' => $conf['format']),
278
  );
279
}
280

  
281
/**
282
 * Implements hook_i18n_string_list_TEXTGROUP_alter().
283
 *
284
 * Necessary to support the dynamic translatable settings defined by ctools
285
 * content types.
286
 */
287
function i18n_panels_i18n_string_list_panels_alter(&$strings, $type = NULL, $object = NULL) {
288
  if (isset($object->panels_i18n_settings)) {
289
    foreach ($object->panels_i18n_settings as $i18n_setting => $settings) {
290
      if (isset($object->{$i18n_setting})) {
291
        $strings['panels'][$type][$object->uuid][$i18n_setting] = $object->{$i18n_setting};
292
      }
293
    }
294
  }
295
}
296

  
297
/**
298
 * Implements hook_i18n_string_list().
299
 *
300
 * @todo Figure out a generic solution to fetch exported displays.
301
 */
302
function i18n_panels_i18n_string_list($group) {
303
  $strings = array();
304
  if ($group == 'panels') {
305

  
306
    // Fetch all available displays.
307
    $displays = _18n_panels_fetch_all_panel_displays();
308

  
309
    foreach ($displays as $display) {
310
      if (empty($display->uuid)) {
311
        drupal_set_message(t('The display %display has no uuid, please resave or re-export it.', array('%display' => $display->did)), 'warning');
312
        continue;
313
      }
314
      // Avoid duplicated runs _18n_panels_fetch_all_panel_displays() probably
315
      // returns the same display twice, one for the db based and one for the
316
      // exported one.
317
      if (isset($strings['panels']['display_configuration'][$display->uuid])) {
318
        continue;
319
      }
320
      $strings['panels']['display_configuration'][$display->uuid]['title']['string'] = $display->title;
321
      foreach ($display->content as $pane) {
322
        if (empty($pane->uuid)) {
323
          // Fetch exported uuid and validate it.
324
          $uuid = str_replace('new-', '', $pane->pid);
325
          if (!panels_uuid_is_valid($uuid)) {
326
            drupal_set_message(t('The pane %pane has no uuid, please resave or re-export it.', array('%pane' => $pane->pid)), 'warning');
327
            continue;
328
          }
329
          $pane->uuid = $uuid;
330
        }
331
        if ($translation_object = i18n_panels_get_i18n_translation_object($pane)) {
332
          // Split up all strings and add them to the list.
333
          $pane_strings = (array) $translation_object;
334
          unset($pane_strings['panels_i18n_settings']);
335
          foreach ($pane_strings as $key => $pane_string) {
336
            $strings['panels']['pane_configuration'][$pane->uuid][$key] = $pane_string;
337
          }
338
        }
339
      }
340
    }
341
  }
342
  return $strings;
343
}
344

  
345
/**
346
 * Checks if the give display is exported or only stored in the db.
347
 *
348
 * @return boolean
349
 *   TRUE if the display is available from code.
350
 */
351
function _18n_panels_is_exported_panels_display($display) {
352
  if (isset($display->uuid)) {
353
    $displays = _18n_panels_fetch_all_panel_displays();
354
    return isset($displays['exported-' . $display->uuid]);
355
  }
356
  return FALSE;
357
}
358

  
359
/**
360
 * Returns a list of really all available panel displays.
361
 *
362
 * The list is statically cached. Use the parameter $reset to refresh the list
363
 * during the same request.
364
 * Probably returns the same display twice - once with the db based and once
365
 * the exported one.
366
 *
367
 * @todo I bet there are better ways to solve this mess.
368
 *
369
 * @param boolean $reset
370
 *   Reset the static cache.
371
 *
372
 * @return array
373
 *   List of all panel displays.
374
 */
375
function _18n_panels_fetch_all_panel_displays($reset = FALSE) {
376
  $displays = &drupal_static(__FUNCTION__, array());
377
  if (!empty($displays) && !$reset) {
378
    return $displays;
379
  }
380

  
381
  // Fetch db based displays.
382
  $dids = db_select('panels_display')->fields('panels_display', array('did'))->execute()->fetchCol();
383
  $displays = panels_load_displays($dids);
384

  
385
  // Fetch exported displays.
386
  ctools_include('export');
387
  foreach (ctools_export_crud_load_all('panels_display') as $panels_display) {
388
    if (!empty($panels_display->uuid)) {
389
      $displays['exported-' . $panels_display->uuid] = $panels_display;
390
    }
391
  }
392

  
393
  // Fetch mini panels.
394
  $mini_panels = ctools_export_crud_load_all('panels_mini');
395
  foreach ($mini_panels as $pane) {
396
    if (!empty($pane->display->uuid)) {
397
      $displays['exported-' . $pane->display->uuid] = $pane->display;
398
    }
399
  }
400

  
401
  // Fetch in page manager embedded displays.
402
  if (module_exists('page_manager')) {
403
    module_load_include('inc', 'page_manager', 'page_manager.admin');
404
    $tasks = page_manager_get_tasks_by_type('page');
405
    $pages = array('operations' => array(), 'tasks' => array());
406
    page_manager_get_pages($tasks, $pages);
407

  
408
    foreach ($pages['tasks'] as $task) {
409
      $page = page_manager_cache_load($task);
410
      $task_info = page_manager_get_task_subtasks($page->task);
411
      foreach ($page->handler_info as $id => $info) {
412
        $page_manager_handler = $page->handlers[$id];
413
        if ($page_manager_handler->handler == 'panel_context') {
414

  
415
          // @todo Is there really no better way to check this?
416
          $is_exported = ($page_manager_handler->export_type == (EXPORT_IN_CODE | EXPORT_IN_DATABASE) || (isset($page->subtask['storage']) && $page->subtask['storage'] == t('Overridden')));
417

  
418
          if (!empty($page_manager_handler->conf['display'])) {
419
            $panels_display = $page_manager_handler->conf['display'];
420
            $displays['exported-' . $panels_display->uuid] = $panels_display;
421
          }
422
          elseif ($is_exported && isset($page_manager_handler->conf['did'])) {
423
            $panels_display = panels_load_display($page_manager_handler->conf['did']);
424
            if (isset($panels_display->uuid)) {
425
              $displays['exported-' . $panels_display->uuid] = $panels_display;
426
            }
427
          }
428
        }
429
      }
430
    }
431
  }
432

  
433
  // Fetch panelizer displays.
434
  if (module_exists('panelizer')) {
435
    // Fetch all default handlers.
436
    $panelizer_defaults = ctools_export_crud_load_all('panelizer_defaults');
437
    foreach ($panelizer_defaults as $panelizer_default) {
438
      $displays['exported-' . $panelizer_default->display->uuid] = $panelizer_default->display;
439
    }
440
  }
441
  return $displays;
442
}
drupal7/sites/all/modules/panels/includes/callbacks.inc
172 172
    }
173 173
  }
174 174

  
175
  ctools_include('plugins', 'panels');
176
  $pipelines = panels_get_renderer_pipelines();
177
  $options = array();
178
  foreach ($pipelines as $key => $value) {
179
    $options[$key] = $value->admin_title;
180
  }
181
  if (count($options) > 1) {
182
    $form['panels_renderer_default'] = array(
183
      '#type' => 'select',
184
      '#title' => t('Default renderer'),
185
      '#options' => $options,
186
      '#default_value' => variable_get('panels_renderer_default', 'standard'),
187
      '#description' => t('The default renderer for new panel pages.'),
188
    );
189
  }
190

  
175 191
  if (empty($form)) {
176 192
    return array('#value' => t('There are currently no settings to change, but additional plugins or modules may provide them in the future.'));
177 193
  }
drupal7/sites/all/modules/panels/includes/common.inc
477 477
 * Get the allowed layouts for the given module.
478 478
 */
479 479
function panels_common_get_allowed_layouts($module_name) {
480
  ctools_include('plugins', 'panels');
480 481
  $available_layouts = panels_get_layouts();
481 482
  if (empty($module_name)) {
482 483
    return $available_layouts;
drupal7/sites/all/modules/panels/includes/plugins.inc
173 173
    $start = $this->js;
174 174
    $this->js = array();
175 175

  
176
    // Use the advanced mapping function from Drupal >= 7.23 if available.
177
    $array_mapping_func = function_exists('drupal_array_diff_assoc_recursive') ? 'drupal_array_diff_assoc_recursive' : 'array_diff_assoc';
178

  
176 179
    // If there are any differences between the old and the new javascript then
177 180
    // store them to be added later.
178
    if ($diff = array_diff_assoc($js, $start)) {
179
      $this->js = $diff;
180
    }
181

  
182
    // Special case the settings key and get the difference of the data.
183
    if ($settings_diff = array_diff_assoc($js['settings']['data'], $start['settings']['data'])) {
184
      $this->js['settings'] = $settings_diff;
181
    if ($diff = $array_mapping_func($js, $start)) {
182
      // Iterate over the diff to ensure we keep the keys on merge and don't add
183
      // unnecessary items.
184
      foreach ($diff as $key => $diff_data) {
185
        // Special case the settings key and get the difference of the data.
186
        if ($key === 'settings') {
187
          // Iterate over the diff to ensure we keep the keys on merge and don't
188
          // add unnecessary items.
189
          if (isset($diff[$key]['data'])) {
190
            foreach ($diff[$key]['data'] as $settings_key => $settings_data) {
191
              // Merge the changes with the base to get a complete settings
192
              // array.
193
              $this->js[$key]['data'][] = drupal_array_merge_deep($settings_data, $diff[$key]['data'][$settings_key]);
194
            }
195
          }
196
        }
197
        else {
198
          $this->js[$key] = $diff_data;
199
          // Check if the key was present already and if so merge the changes
200
          // with the original data to get the full settings array.
201
          if (isset($start[$key])) {
202
            $this->js[$key] = drupal_array_merge_deep($start[$key], $this->js[$key]);
203
          }
204
        }
205
      }
185 206
    }
186 207

  
187 208
    // And for tokens:
......
213 234
          drupal_add_js($args['data'], $args);
214 235
        }
215 236
        else {
216
          foreach ($args as $setting) {
237
          foreach ($args['data'] as $setting) {
217 238
            drupal_add_js($setting, 'setting');
218 239
          }
219 240
        }
drupal7/sites/all/modules/panels/js/display_editor.js
16 16
  $('a.pane-delete:not(.pane-delete-processed)', context)
17 17
    .addClass('pane-delete-processed')
18 18
    .click(function() {
19
    if (confirm('Remove this pane?')) {
19
    if (confirm(Drupal.t('Remove this pane?'))) {
20 20
      var id = '#' + $(this).attr('id').replace('pane-delete-', '');
21 21
      $(id).remove();
22 22
      Drupal.Panels.Draggable.savePositions();
drupal7/sites/all/modules/panels/js/panels.js
1

  
2
(function ($) {
3
  Drupal.Panels = Drupal.Panels || {};
4

  
5
  Drupal.Panels.autoAttach = function() {
6
    if ($.browser.msie) {
7
      // If IE, attach a hover event so we can see our admin links.
8
      $("div.panel-pane").hover(
9
        function() {
10
          $('div.panel-hide', this).addClass("panel-hide-hover"); return true;
11
        },
12
        function() {
13
          $('div.panel-hide', this).removeClass("panel-hide-hover"); return true;
14
        }
15
      );
16
      $("div.admin-links").hover(
17
        function() {
18
          $(this).addClass("admin-links-hover"); return true;
19
        },
20
        function(){
21
          $(this).removeClass("admin-links-hover"); return true;
22
        }
23
      );
24
    }
25
  };
26

  
27
  $(Drupal.Panels.autoAttach);
28
})(jQuery);
drupal7/sites/all/modules/panels/panels.api.php
1
<?php
2

  
3
/**
4
 * @file
5
 * Hooks provided by Panels.
6
 */
7

  
8
/**
9
 * Allow modules to provide their own caching mechanism for the display editor.
10
 *
11
 * @param string $argument
12
 *   The second half of the cache key. Full key module:TASK_NAME:HANDLER_NAME
13
 *   passed part: TASK_NAME:HANDLER_NAME
14
 * @param stdClass $cache
15
 *   The display to cache.
16
 */
17
function hook_panels_cache_set($argument, $cache) {
18
  list($handler, $item) = _panels_mini_panels_cache_get($argument);
19
  $item->mini_panels_display_cache = $cache;
20
  $handler->edit_cache_set_key($item, $argument);
21
}
22

  
23
/**
24
 * Allow modules to provide their own caching mechanism for the display editor.
25
 *
26
 * @param string $argument
27
 *   The second half of the cache key. Full key module:TASK_NAME:HANDLER_NAME
28
 *   passed part: TASK_NAME:HANDLER_NAME
29
 *
30
 * @return stdClass|NULL
31
 *   The cached display or NULL if the cache wasn't hit.
32
 */
33
function hook_panels_cache_get($argument) {
34
  ctools_include('common', 'panels');
35
  list($handler, $item) = _panels_mini_panels_cache_get($argument);
36
  if (isset($item->mini_panels_display_cache)) {
37
    return $item->mini_panels_display_cache;
38
  }
39

  
40
  $cache = new stdClass();
41
  $cache->display = $item->display;
42
  $cache->display->context = ctools_context_load_contexts($item);
43
  $cache->display->cache_key = 'panels_mini:' . $argument;
44
  $cache->content_types = panels_common_get_allowed_types('panels_mini', $cache->display->context);
45
  $cache->display_title = TRUE;
46

  
47
  // @TODO support locking.
48
  $cache->locked = FALSE;
49

  
50
  return $cache;
51
}
52

  
53
/**
54
 * Allow modules to provide their own caching mechanism for the display editor.
55
 *
56
 * @param string $argument
57
 *   The second half of the cache key. Full key module:TASK_NAME:HANDLER_NAME
58
 *   passed part: TASK_NAME:HANDLER_NAME
59
 * @param stdClass $cache
60
 *   The display to cache.
61
 *
62
 * @return stdClass
63
 *   The cached display.
64
 */
65
function hook_panels_cache_save($argument, $cache) {
66
  list($handler, $item) = _panels_mini_panels_cache_get($argument);
67
  $item->display = $cache->display;
68
  panels_mini_save($item);
69

  
70
  $handler->edit_cache_clear($item);
71

  
72
  return $item;
73
}
74

  
75
/**
76
 * Allow modules to provide their own caching mechanism for the display editor.
77
 *
78
 * @param string $argument
79
 *   The second half of the cache key. Full key module:TASK_NAME:HANDLER_NAME
80
 *   passed part: TASK_NAME:HANDLER_NAME
81
 * @param stdClass $cache
82
 *   The cached display.
83
 */
84
function hook_panels_cache_clear($argument, $cache) {
85
  list($handler, $item) = _panels_mini_panels_cache_get($argument);
86
  $handler->edit_cache_clear($item);
87
}
88

  
89
/**
90
 * Allow modules to adjust the rendering array of the panels dashboard.
91
 *
92
 * @param array $vars
93
 *   The output variables.
94
 */
95
function hook_panels_dashboard_blocks(&$vars) {
96
  $vars['links']['panels_node'] = array(
97
    'title' => l(t('Panel node'), 'node/add/panel'),
98
    'description' => t('Panel nodes are node content and appear in your searches, but are more limited than panel pages.'),
99
    'weight' => -1,
100
  );
101
}
102

  
103
/**
104
 * Allow to alter the pane content to render.
105
 *
106
 * This happens after the keyword substitution.
107
 *
108
 * @param stdClass $content
109
 *   The content block to render.
110
 * @param stdClass $pane
111
 *   The pane object.
112
 * @param array $args
113
 *   The display arguments.
114
 * @param array $contexts
115
 *   Array with the used contexts.
116
 */
117
function hook_panels_pane_content_alter($content, $pane, $args, $contexts) {
118
  // Don't display titles.
119
  unset($content->title);
120
}
121

  
122
/**
123
 * Allow modules to provide a mechanism to break locks.
124
 *
125
 * @param string $argument
126
 *   The second half of the cache key. Full key module:TASK_NAME:HANDLER_NAME
127
 *   passed part: TASK_NAME:HANDLER_NAME
128
 * @param stdClass $cache
129
 *   The cached display.
130
 */
131
function hook_panels_edit_cache_break_lock($argument, $cache) {
132
  $cache->locked = FALSE;
133
}
134

  
135
/**
136
 * Fired before a panels display is rendered.
137
 *
138
 * Last chance to modify the panels display or add output before the keyword
139
 * substitution runs and the panels display is rendered.
140
 *
141
 * @param panels_display $panels_display
142
 *   The panels display that will be rendered.
143
 * @param stdClass $renderer
144
 *   The renderer object that will be used to render.
145
 *
146
 * @return string
147
 *   Additional output to add before the panels display.
148
 */
149
function hook_panels_pre_render($panels_display, $renderer) {
150
  $translation = i18n_string_object_translate('panels_display_configuration', $panels_display);
151
  $panels_display->title = $translation->title;
152
}
153

  
154
/**
155
 * Fired after a panels display is rendered.
156
 *
157
 * Allow to add additional output after the output of the panels display.
158
 *
159
 * @param panels_display $panels_display
160
 *   The rendered panels display.
161
 * @param stdClass $renderer
162
 *   The used renderer object.
163
 *
164
 * @return string
165
 *   Additional output to add after the panels display.
166
 */
167
function hook_panels_post_render($panels_display, $renderer) {
168
  return t('Output proudly sponsored by panels.');
169
}
170

  
171
/**
172
 * Fired before a new pane is inserted in the storage.
173
 *
174
 * @param stdClass $pane
175
 *   Pane that will be rendered.
176
 */
177
function hook_panels_pane_insert($pane) {
178
  // Check if this pane has a custom title enabled.
179
  if (!empty($pane->configuration['override_title'])) {
180
    $translation_object = (object) array(
181
      'pid' => $pane->pid,
182
      'title' => $pane->configuration['override_title_text'],
183
    );
184
    $status = i18n_string_object_update('panels_pane_configuration', $translation_object);
185
  }
186
}
187

  
188
/**
189
 * Fired before a changed pane is updated in the storage.
190
 *
191
 * @param stdClass $pane
192
 *   Pane that will be rendered.
193
 */
194
function hook_panels_pane_update($pane) {
195
  // Check if this pane has a custom title enabled.
196
  if (!empty($pane->configuration['override_title'])) {
197
    $translation_object = (object) array(
198
      'pid' => $pane->pid,
199
      'title' => $pane->configuration['override_title_text'],
200
    );
201
    $status = i18n_string_object_update('panels_pane_configuration', $translation_object);
202
  }
203
}
204

  
205
/**
206
 * Fired before a panel is rendered.
207
 *
208
 * Last chance to modify the pane before the keyword substitution runs and the
209
 * pane is rendered.
210
 *
211
 * @param stdClass $pane
212
 *   Pane that will be rendered.
213
 */
214
function hook_panels_pane_prerender($pane) {
215
  // Check if this pane has a custom title enabled.
216
  if (!empty($pane->configuration['override_title'])) {
217
    $translation_object = (object) array(
218
      'pid' => $pane->pid,
219
      'title' => $pane->configuration['override_title_text'],
220
    );
221
    $translation_object = i18n_string_object_translate('panels_pane_configuration', $translation_object);
222
    $pane->configuration['override_title_text'] = $translation_object->title;
223
  }
224
}
225

  
226
/**
227
 * Fired before panes are deleted.
228
 *
229
 * @param array $pids
230
 *   Array with the panel id's to delete.
231
 */
232
function hook_panels_pane_delete($pids) {
233
  foreach ($pids as $pid) {
234
    // Create dummy pane with pid as property.
235
    $pane = (object) array('pid' => $pid);
236
    i18n_string_object_remove('panels_pane_configuration', $pane);
237
  }
238
}
239

  
240
/**
241
 * Fired after a display is saved.
242
 *
243
 * @param panels_display $display
244
 *   The display to save.
245
 */
246
function hook_panels_display_save($display) {
247
  i18n_string_object_update('display_configuration', $display);
248
}
249

  
250
/**
251
 * Fired before a display is deleted.
252
 *
253
 * @param integer $did
254
 *   Id of the display to delete.
255
 */
256
function hook_panels_delete_display($did) {
257
  $uuid = db_select('panels_display')
258
    ->fields('panels_display', array('uuid'))
259
    ->condition('did', $did)
260
    ->execute()
261
    ->fetchColumn();
262
  $display = (object) array('uuid' => $uuid);
263
  i18n_string_object_remove('display_configuration', $display);
264
}
drupal7/sites/all/modules/panels/panels.info
3 3
core = 7.x
4 4
package = "Panels"
5 5
configure = admin/structure/panels
6
dependencies[] = ctools
6
dependencies[] = ctools (>=1.4)
7 7
files[] = panels.module
8 8
files[] = includes/common.inc
9 9
files[] = includes/legacy.inc
10 10
files[] = includes/plugins.inc
11 11
files[] = plugins/views/panels_views_plugin_row_fields.inc
12 12

  
13
; Information added by drupal.org packaging script on 2012-08-18
14
version = "7.x-3.3"
13
; Information added by Drupal.org packaging script on 2014-02-12
14
version = "7.x-3.4"
15 15
core = "7.x"
16 16
project = "panels"
17
datestamp = "1345319572"
17
datestamp = "1392221614"
18 18

  
drupal7/sites/all/modules/panels/panels.install
47 47
function panels_schema() {
48 48
  // This should always point to our 'current' schema. This makes it relatively easy
49 49
  // to keep a record of schema as we make changes to it.
50
  return panels_schema_4();
50
  return panels_schema_5();
51
}
52

  
53
function panels_schema_5() {
54
  $schema = panels_schema_4();
55

  
56
  $schema['panels_display']['fields']['uuid'] = array(
57
    'type' => 'char',
58
    'length' => '36',
59
  );
60
  $schema['panels_display']['export']['key'] = 'uuid';
61
  $schema['panels_display']['export']['key name'] = 'UUID';
62

  
63
  $schema['panels_pane']['fields']['uuid'] = array(
64
    'type' => 'char',
65
    'length' => '36',
66
  );
67
  $schema['panels_pane']['export']['key'] = 'uuid';
68
  $schema['panels_pane']['export']['key name'] = 'UUID';
69

  
70
  return $schema;
51 71
}
52 72

  
53 73
function panels_schema_4() {
......
331 351
    'primary key' => array('lid'),
332 352
  );
333 353

  
354
  $schema['cache_panels'] = drupal_get_schema_unprocessed('system', 'cache');
355

  
334 356
  return $schema;
335 357
}
336 358

  
......
375 397

  
376 398
  return t('panels_pane.lock field already existed, update skipped.');
377 399
}
400

  
401
/**
402
 * Adding universally unique identifiers to panels.
403
 */
404
function panels_update_7302() {
405
  // Load the schema.
406
  $schema = panels_schema_5();
407
  $msg = array();
408

  
409
  // Add the uuid column to the pane table.
410
  $table = 'panels_pane';
411
  $field = 'uuid';
412
  // Due to a previous failure, the column may already exist:
413
  if (!db_field_exists($table, $field)) {
414
    $spec = $schema[$table]['fields'][$field];
415
    db_add_field($table, $field, $spec);
416
    $msg[] = t('Added panels_pane.uuid column.');
417
  }
418

  
419
  // Add the uuid column to the display table.
420
  $table = 'panels_display';
421
  $field = 'uuid';
422
  // Due to a previous failure, the column may already exist:
423
  if (!db_field_exists($table, $field)) {
424
    $spec = $schema[$table]['fields'][$field];
425
    db_add_field($table, $field, $spec);
426
    $msg[] = t('Added panels_display.uuid column.');
427
  }
428

  
429
  if (empty($msg)) {
430
    $msg[] = t('UUID column already present in the panels_display & panels_pane tables.');
431
  }
432

  
433
  // Update all DB-based panes & displays to ensure that they all contain a UUID.
434
  $display_dids = db_select('panels_display')
435
    ->fields('panels_display', array('did'))
436
    ->condition(db_or()
437
      ->condition('uuid', '')
438
      ->isNull('uuid')
439
    )
440
    ->execute()
441
    ->fetchCol();
442

  
443
  // Check the panes as well, for paranoia.
444
  $pane_dids = db_select('panels_pane')
445
    ->distinct()
446
    ->fields('panels_pane', array('did'))
447
    ->condition(db_or()
448
      ->condition('uuid', '')
449
      ->isNull('uuid')
450
    )
451
    ->execute()
452
    ->fetchCol();
453

  
454
  $dids = array_unique(array_merge($display_dids, $pane_dids));
455

  
456
  if ($displays = panels_load_displays($dids)) {
457
    foreach ($displays as $display) {
458
      // A display save also triggers pane saves.
459
      panels_save_display($display);
460
    }
461
    $msg[] = t('Generated UUIDs for database-based panel displays and panes.');
462
  }
463
  else {
464
    $msg[] = t('No database-based panel displays or panes for which to generate UUIDs.');
465
  }
466

  
467
  return implode("\n", $msg);
468
}
469

  
470
/**
471
 * Add a custom cache table for Panels.
472
 */
473
function panels_update_7303() {
474
  $table_name = 'cache_panels';
475
  if (!db_table_exists($table_name)) {
476
    $schema = drupal_get_schema_unprocessed('system', 'cache');
477
    db_create_table($table_name, $schema);
478
  }
479
}
drupal7/sites/all/modules/panels/panels.module
258 258
  }
259 259

  
260 260
  ctools_add_css('panels', 'panels');
261
  ctools_add_js('panels', 'panels');
262 261
}
263 262

  
264 263
/**
......
308 307
      'title' => t('Use panel locks'),
309 308
      'description' => t('Allows a user to lock and unlock panes in a panel display.'),
310 309
    ),
310
    'use ipe with page manager' => array(
311
      'title' => t("Use the Panels In-Place Editor with Page Manager"),
312
      'description' => t('Allows users with access to the In-Place editor to administer page manager pages. This permission is only needed for users without "use page manager" access.'),
313
    ),
311 314
  );
312 315
}
313 316

  
......
322 325
//  $legacy->determineStatus();
323 326
//}
324 327

  
328
/**
329
 * Implements hook_flush_caches().
330
 */
331
function panels_flush_caches() {
332
  return array('cache_panels');
333
}
334

  
325 335
// ---------------------------------------------------------------------------
326 336
// CTools hook implementations
327 337
//
......
652 662
      $pane->panel = $location;
653 663
    }
654 664

  
655
    // Get a temporary pid for this pane.
656
    $pane->pid = "new-" . $this->next_new_pid();
665
    // Generate a permanent uuid for this pane, and use
666
    // it as a temporary pid.
667
    $pane->uuid = ctools_uuid_generate();
668
    $pane->pid = 'new-' . $pane->uuid;
657 669

  
658 670
    // Add the pane to the approprate spots.
659 671
    $this->content[$pane->pid] = &$pane;
......
667 679

  
668 680
  function clone_pane($pid) {
669 681
    $pane = clone $this->content[$pid];
682
    $pane->uuid = ctools_uuid_generate();
670 683
    return $pane;
671 684
  }
672 685

  
673
  function next_new_pid() {
674
    // We don't use static vars to record the next new pid because
675
    // temporary pids can last for years in exports and in caching
676
    // during editing.
677
    $id = array(0);
678
    foreach (array_keys($this->content) as $pid) {
679
      if (!is_numeric($pid)) {
680
        $id[] = substr($pid, 4);
681
      }
682
    }
683
    $next_id = max($id);
684
    return ++$next_id;
685
  }
686

  
687 686
  /**
688 687
   * Get the title from a display.
689 688
   *
......
867 866
 *
868 867
 * @ingroup mainapi
869 868
 *
870
 * Note a new $display only receives a real did once it is run through this function.
871
 * Until then, it uses a string placeholder, 'new', in place of a real did. The same
872
 * applies to all new panes (whether on a new $display or not); in addition,
873
 * panes have sequential numbers appended, of the form 'new-1', 'new-2', etc.
869
 * Note that a new $display only receives a real did once it is run through
870
 * this function, and likewise for the pid of any new pane.
871
 *
872
 * Until then, a new display uses a string placeholder, 'new', in place of
873
 * a real did, and a new pane (whether on a new $display or not) appends a
874
 * universally-unique identifier (which is stored permanently in the 'uuid'
875
 * field). This format is also used in place of the real pid for exports.
874 876
 *
875 877
 * @param object $display instanceof panels_display \n
876 878
 *  The display object to be saved. Passed by reference so the caller need not use
......
880 882
 */
881 883
function panels_save_display(&$display) {
882 884
  $update = (isset($display->did) && is_numeric($display->did)) ? array('did') : array();
885
  if (empty($display->uuid) || !ctools_uuid_is_valid($display->uuid)) {
886
    $display->uuid = ctools_uuid_generate();
887
  }
883 888
  drupal_write_record('panels_display', $display, $update);
884 889

  
885 890
  $pids = array();
......
910 915
      $pane->did = $display->did;
911 916

  
912 917
      $old_pid = $pane->pid;
918

  
919
      if (empty($pane->uuid) || !ctools_uuid_is_valid($pane->uuid)) {
920
        $pane->uuid = ctools_uuid_generate();
921
      }
922

  
913 923
      drupal_write_record('panels_pane', $pane, is_numeric($pid) ? array('pid') : array());
914 924

  
925
      // Allow other modules to take action after a pane is saved.
926
      if ($pane->pid == $old_pid) {
927
        module_invoke_all('panels_pane_update', $pane);
928
      }
929
      else {
930
        module_invoke_all('panels_pane_insert', $pane);
931
      }
932

  
915 933
      if ($pane->pid != $old_pid) {
916
        // and put it back so our pids and positions can be used
917
        unset($display->content[$id]);
934
        // Remove the old new-* entry from the displays content.
935
        unset($display->content[$pid]);
936

  
937
        // and put it back so our pids and positions can be used.
918 938
        $display->content[$pane->pid] = $pane;
919 939

  
920 940
        // If the title pane was one of our panes that just got its ID changed,
......
945 965
    $display->panels[$id] = $new_panes;
946 966
  }
947 967
  if (!empty($pids)) {
968
    // Allow other modules to take action before a panes are deleted.
969
    module_invoke_all('panels_pane_delete', $pids);
948 970
    db_delete('panels_pane')->condition('pid', $pids)->execute();
949 971
  }
950 972

  
......
978 1000
  else {
979 1001
    $did = $display;
980 1002
  }
1003
  module_invoke_all('panels_delete_display', $did);
981 1004
  db_delete('panels_display')->condition('did', $did)->execute();
982 1005
  db_delete('panels_pane')->condition('did', $did)->execute();
983 1006
}
......
987 1010
 *
988 1011
 * This function is primarily intended as a mechanism for cloning displays.
989 1012
 * It generates an exact replica (in code) of the provided $display, with
990
 * the exception that it replaces all ids (dids and pids) with 'new-*' values.
991
 * Only once panels_save_display() is called on the code version of $display will
992
 * the exported display written to the database and permanently saved.
1013
 * the exception that it replaces all ids (dids and pids) with place-holder
1014
 * values (consisting of the display or pane's uuid, with a 'new-' prefix).
1015
 *
1016
 * Only once panels_save_display() is called on the code version of $display
1017
 * will the exported display be written to the database and permanently saved.
993 1018
 *
994 1019
 * @see panels_page_export() or _panels_page_fetch_display() for sample implementations.
995 1020
 *
......
1011 1036
 */
1012 1037
function panels_export_display($display, $prefix = '') {
1013 1038
  ctools_include('export');
1039
  if (empty($display->uuid) || !ctools_uuid_is_valid($display->uuid)) {
1040
    $display->uuid = ctools_uuid_generate();
1041
  }
1042
  $display->did = 'new-' . $display->uuid;
1014 1043
  $output = ctools_export_object('panels_display', $display, $prefix);
1015 1044

  
1016
  $pid_counter = &drupal_static(__FUNCTION__, 0);
1017

  
1018 1045
  // Initialize empty properties.
1019 1046
  $output .= $prefix . '$display->content = array()' . ";\n";
1020 1047
  $output .= $prefix . '$display->panels = array()' . ";\n";
......
1024 1051
  if (!empty($display->content)) {
1025 1052
    $region_counters = array();
1026 1053
    foreach ($display->content as $pane) {
1027
      $pid = 'new-' . ++$pid_counter;
1054

  
1055
      if (!isset($pane->uuid) || !ctools_uuid_is_valid($pane->uuid)) {
1056
        $pane->uuid = ctools_uuid_generate();
1057
      }
1058
      $pid = 'new-' . $pane->uuid;
1059

  
1028 1060
      if ($pane->pid == $display->title_pane) {
1029 1061
        $title_pid = $pid;
1030 1062
      }
......
1070 1102
  if (!empty($display->context)) {
1071 1103
    if ($form_context = ctools_context_get_form($display->context)) {
1072 1104
      $form_context->form['#theme'] = 'panels_render_display_form';
1105
      if (empty($form_context->form['#theme_wrappers']) || !in_array('form', $form_context->form['#theme_wrappers'])) {
1106
        $form_context['#theme_wrappers'][] = 'form';
1107
      }
1073 1108
      $form_context->form['#display'] = &$display;
1074 1109
      return $form_context->form;
1075 1110
    }
......
1086 1121
 * then operate as a theme function of the form.
1087 1122
 */
1088 1123
function theme_panels_render_display_form($vars) {
1089
  // @todo this is probably broken in D7
1090
  $render = $vars['element']['#display']->render();
1091
  $vars['element']['#children'] = $render;
1092
  return theme('form', $vars);
1124
  return $vars['element']['#display']->render();
1093 1125
}
1094 1126

  
1095 1127
// @layout
......
1226 1258
      }
1227 1259

  
1228 1260
      $element = contextual_pre_render_links($element);
1229
      $links += $element['#links'];
1261
      if(!empty($element['#links'])) {
1262
        $links += $element['#links'];
1263
      }
1230 1264
    }
1231 1265

  
1232 1266
    if ($links) {
......
1276 1310

  
1277 1311
  // Add template file suggestion for content type and sub-type.
1278 1312
  $vars['theme_hook_suggestions'][] = $base . $delimiter . $content->type;
1279
  $vars['theme_hook_suggestions'][] = $base . $delimiter . strtr($content->type, '-', '_') . $delimiter . strtr($content->subtype, '-', '_');
1313
  $vars['theme_hook_suggestions'][] = $base . $delimiter . strtr(ctools_cleanstring($content->type, array('lower case' => TRUE)), '-', '_') . $delimiter . strtr(ctools_cleanstring($content->subtype, array('lower case' => TRUE)), '-', '_');
1280 1314

  
1281 1315
  $vars['pane_prefix'] = !empty($content->pane_prefix) ? $content->pane_prefix : '';
1282 1316
  $vars['pane_suffix'] = !empty($content->pane_suffix) ? $content->pane_suffix : '';
......
1526 1560
 * Get display edit cache on behalf of panel context.
1527 1561
 *
1528 1562
 * The key is the second half of the key in this form:
1529
 * panel_context:TASK_NAME:HANDLER_NAME;
1563
 * panel_context:TASK_NAME::HANDLER_NAME::args::url;
1530 1564
 */
1531 1565
function panel_context_panels_cache_get($key) {
1532 1566
  ctools_include('common', 'panels');
......
1535 1569
  // this loads the panel context inc even if we don't use the plugin.
1536 1570
  $plugin = page_manager_get_task_handler('panel_context');
1537 1571

  
1538
  list($task_name, $handler_name) = explode(':', $key, 2);
1572
  list($task_name, $handler_name, $args, $q) = explode('::', $key, 4);
1539 1573
  $page = page_manager_get_page_cache($task_name);
1540 1574
  if (isset($page->display_cache[$handler_name])) {
1541 1575
    return $page->display_cache[$handler_name];
......
1549 1583
  }
1550 1584
  $cache = new stdClass();
1551 1585

  
1586
  $task = page_manager_get_task($page->task_id);
1587
  //ctools_context_handler_get_all_contexts($page->task, $page->subtask, $handler);
1588
  $arguments = array();
1589
  if ($args) {
1590
    $arguments = explode('\\', $args);
1591
    $contexts = ctools_context_handler_get_task_contexts($task, $page->subtask, $arguments);
1592
    $contexts = ctools_context_handler_get_handler_contexts($contexts, $handler);
1593
  }
1594
  else {
1595
    $contexts = ctools_context_handler_get_all_contexts($page->task, $page->subtask, $handler);
1596
  }
1597

  
... Ce différentiel a été tronqué car il excède la taille maximale pouvant être affichée.

Formats disponibles : Unified diff