Révision 5a7e6170
Ajouté par Florent Torregrosa il y a environ 10 ans
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 |
|
Formats disponibles : Unified diff
Update :