webmaster@1
|
1 <?php |
webmaster@5
|
2 // $Id: node.admin.inc,v 1.19.2.1 2008/03/21 22:01:05 goba Exp $ |
webmaster@1
|
3 |
webmaster@1
|
4 /** |
webmaster@1
|
5 * @file |
webmaster@1
|
6 * Content administration and module settings UI. |
webmaster@1
|
7 */ |
webmaster@1
|
8 |
webmaster@1
|
9 /** |
webmaster@1
|
10 * Menu callback; presents general node configuration options. |
webmaster@1
|
11 */ |
webmaster@1
|
12 function node_configure() { |
webmaster@5
|
13 // Only show rebuild button if there are either 0, or 2 or more, rows |
webmaster@5
|
14 // in the {node_access} table, or if there are modules that |
webmaster@5
|
15 // implement hook_node_grants(). |
webmaster@1
|
16 if (db_result(db_query('SELECT COUNT(*) FROM {node_access}')) != 1 || count(module_implements('node_grants')) > 0) { |
webmaster@1
|
17 $status = '<p>'. t('If the site is experiencing problems with permissions to content, you may have to rebuild the permissions cache. Possible causes for permission problems are disabling modules or configuration changes to permissions. Rebuilding will remove all privileges to posts, and replace them with permissions based on the current modules and settings.') .'</p>'; |
webmaster@1
|
18 $status .= '<p>'. t('Rebuilding may take some time if there is a lot of content or complex permission settings. After rebuilding has completed posts will automatically use the new permissions.') .'</p>'; |
webmaster@1
|
19 |
webmaster@1
|
20 $form['access'] = array( |
webmaster@1
|
21 '#type' => 'fieldset', |
webmaster@1
|
22 '#title' => t('Node access status'), |
webmaster@1
|
23 ); |
webmaster@1
|
24 $form['access']['status'] = array('#value' => $status); |
webmaster@1
|
25 $form['access']['rebuild'] = array( |
webmaster@1
|
26 '#type' => 'submit', |
webmaster@1
|
27 '#value' => t('Rebuild permissions'), |
webmaster@1
|
28 ); |
webmaster@1
|
29 } |
webmaster@1
|
30 |
webmaster@1
|
31 $form['default_nodes_main'] = array( |
webmaster@1
|
32 '#type' => 'select', '#title' => t('Number of posts on main page'), '#default_value' => variable_get('default_nodes_main', 10), |
webmaster@1
|
33 '#options' => drupal_map_assoc(array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20, 25, 30)), |
webmaster@1
|
34 '#description' => t('The default maximum number of posts to display per page on overview pages such as the main page.') |
webmaster@1
|
35 ); |
webmaster@1
|
36 $form['teaser_length'] = array( |
webmaster@1
|
37 '#type' => 'select', '#title' => t('Length of trimmed posts'), '#default_value' => variable_get('teaser_length', 600), |
webmaster@1
|
38 '#options' => array( |
webmaster@1
|
39 0 => t('Unlimited'), |
webmaster@1
|
40 200 => t('200 characters'), |
webmaster@1
|
41 400 => t('400 characters'), |
webmaster@1
|
42 600 => t('600 characters'), |
webmaster@1
|
43 800 => t('800 characters'), |
webmaster@1
|
44 1000 => t('1000 characters'), |
webmaster@1
|
45 1200 => t('1200 characters'), |
webmaster@1
|
46 1400 => t('1400 characters'), |
webmaster@1
|
47 1600 => t('1600 characters'), |
webmaster@1
|
48 1800 => t('1800 characters'), |
webmaster@1
|
49 2000 => t('2000 characters'), |
webmaster@1
|
50 ), |
webmaster@1
|
51 '#description' => t("The maximum number of characters used in the trimmed version of a post. Drupal will use this setting to determine at which offset long posts should be trimmed. The trimmed version of a post is typically used as a teaser when displaying the post on the main page, in XML feeds, etc. To disable teasers, set to 'Unlimited'. Note that this setting will only affect new or updated content and will not affect existing teasers.") |
webmaster@1
|
52 ); |
webmaster@1
|
53 |
webmaster@1
|
54 $form['node_preview'] = array( |
webmaster@1
|
55 '#type' => 'radios', |
webmaster@1
|
56 '#title' => t('Preview post'), |
webmaster@1
|
57 '#default_value' => variable_get('node_preview', 0), |
webmaster@1
|
58 '#options' => array(t('Optional'), t('Required')), |
webmaster@1
|
59 '#description' => t('Must users preview posts before submitting?'), |
webmaster@1
|
60 ); |
webmaster@1
|
61 |
webmaster@1
|
62 $form['#validate'] = array('node_configure_validate'); |
webmaster@1
|
63 |
webmaster@1
|
64 return system_settings_form($form); |
webmaster@1
|
65 } |
webmaster@1
|
66 |
webmaster@1
|
67 /** |
webmaster@1
|
68 * Form validate callback. |
webmaster@1
|
69 */ |
webmaster@1
|
70 function node_configure_validate($form, &$form_state) { |
webmaster@1
|
71 if ($form_state['values']['op'] == t('Rebuild permissions')) { |
webmaster@1
|
72 drupal_goto('admin/content/node-settings/rebuild'); |
webmaster@1
|
73 } |
webmaster@1
|
74 } |
webmaster@1
|
75 |
webmaster@1
|
76 /** |
webmaster@1
|
77 * Menu callback: confirm rebuilding of permissions. |
webmaster@1
|
78 */ |
webmaster@1
|
79 function node_configure_rebuild_confirm() { |
webmaster@1
|
80 return confirm_form(array(), t('Are you sure you want to rebuild the permissions on site content?'), |
webmaster@1
|
81 'admin/content/node-settings', t('This action rebuilds all permissions on site content, and may be a lengthy process. This action cannot be undone.'), t('Rebuild permissions'), t('Cancel')); |
webmaster@1
|
82 } |
webmaster@1
|
83 |
webmaster@1
|
84 /** |
webmaster@1
|
85 * Handler for wipe confirmation |
webmaster@1
|
86 */ |
webmaster@1
|
87 function node_configure_rebuild_confirm_submit($form, &$form_state) { |
webmaster@1
|
88 node_access_rebuild(TRUE); |
webmaster@1
|
89 $form_state['redirect'] = 'admin/content/node-settings'; |
webmaster@1
|
90 return; |
webmaster@1
|
91 } |
webmaster@1
|
92 |
webmaster@1
|
93 /** |
webmaster@1
|
94 * Implementation of hook_node_operations(). |
webmaster@1
|
95 */ |
webmaster@1
|
96 function node_node_operations() { |
webmaster@1
|
97 $operations = array( |
webmaster@1
|
98 'publish' => array( |
webmaster@1
|
99 'label' => t('Publish'), |
webmaster@1
|
100 'callback' => 'node_mass_update', |
webmaster@1
|
101 'callback arguments' => array('updates' => array('status' => 1)), |
webmaster@1
|
102 ), |
webmaster@1
|
103 'unpublish' => array( |
webmaster@1
|
104 'label' => t('Unpublish'), |
webmaster@1
|
105 'callback' => 'node_mass_update', |
webmaster@1
|
106 'callback arguments' => array('updates' => array('status' => 0)), |
webmaster@1
|
107 ), |
webmaster@1
|
108 'promote' => array( |
webmaster@1
|
109 'label' => t('Promote to front page'), |
webmaster@1
|
110 'callback' => 'node_mass_update', |
webmaster@1
|
111 'callback arguments' => array('updates' => array('status' => 1, 'promote' => 1)), |
webmaster@1
|
112 ), |
webmaster@1
|
113 'demote' => array( |
webmaster@1
|
114 'label' => t('Demote from front page'), |
webmaster@1
|
115 'callback' => 'node_mass_update', |
webmaster@1
|
116 'callback arguments' => array('updates' => array('promote' => 0)), |
webmaster@1
|
117 ), |
webmaster@1
|
118 'sticky' => array( |
webmaster@1
|
119 'label' => t('Make sticky'), |
webmaster@1
|
120 'callback' => 'node_mass_update', |
webmaster@1
|
121 'callback arguments' => array('updates' => array('status' => 1, 'sticky' => 1)), |
webmaster@1
|
122 ), |
webmaster@1
|
123 'unsticky' => array( |
webmaster@1
|
124 'label' => t('Remove stickiness'), |
webmaster@1
|
125 'callback' => 'node_mass_update', |
webmaster@1
|
126 'callback arguments' => array('updates' => array('sticky' => 0)), |
webmaster@1
|
127 ), |
webmaster@1
|
128 'delete' => array( |
webmaster@1
|
129 'label' => t('Delete'), |
webmaster@1
|
130 'callback' => NULL, |
webmaster@1
|
131 ), |
webmaster@1
|
132 ); |
webmaster@1
|
133 return $operations; |
webmaster@1
|
134 } |
webmaster@1
|
135 |
webmaster@1
|
136 /** |
webmaster@1
|
137 * List node administration filters that can be applied. |
webmaster@1
|
138 */ |
webmaster@1
|
139 function node_filters() { |
webmaster@1
|
140 // Regular filters |
webmaster@1
|
141 $filters['status'] = array( |
webmaster@1
|
142 'title' => t('status'), |
webmaster@1
|
143 'options' => array( |
webmaster@1
|
144 'status-1' => t('published'), |
webmaster@1
|
145 'status-0' => t('not published'), |
webmaster@1
|
146 'promote-1' => t('promoted'), |
webmaster@1
|
147 'promote-0' => t('not promoted'), |
webmaster@1
|
148 'sticky-1' => t('sticky'), |
webmaster@1
|
149 'sticky-0' => t('not sticky'), |
webmaster@1
|
150 ), |
webmaster@1
|
151 ); |
webmaster@1
|
152 // Include translation states if we have this module enabled |
webmaster@1
|
153 if (module_exists('translation')) { |
webmaster@1
|
154 $filters['status']['options'] += array( |
webmaster@1
|
155 'translate-0' => t('Up to date translation'), |
webmaster@1
|
156 'translate-1' => t('Outdated translation'), |
webmaster@1
|
157 ); |
webmaster@1
|
158 } |
webmaster@1
|
159 |
webmaster@1
|
160 $filters['type'] = array('title' => t('type'), 'options' => node_get_types('names')); |
webmaster@1
|
161 |
webmaster@1
|
162 // The taxonomy filter |
webmaster@1
|
163 if ($taxonomy = module_invoke('taxonomy', 'form_all', 1)) { |
webmaster@1
|
164 $filters['category'] = array('title' => t('category'), 'options' => $taxonomy); |
webmaster@1
|
165 } |
webmaster@1
|
166 // Language filter if there is a list of languages |
webmaster@1
|
167 if ($languages = module_invoke('locale', 'language_list')) { |
webmaster@1
|
168 $languages = array('' => t('Language neutral')) + $languages; |
webmaster@1
|
169 $filters['language'] = array('title' => t('language'), 'options' => $languages); |
webmaster@1
|
170 } |
webmaster@1
|
171 return $filters; |
webmaster@1
|
172 } |
webmaster@1
|
173 |
webmaster@1
|
174 /** |
webmaster@1
|
175 * Build query for node administration filters based on session. |
webmaster@1
|
176 */ |
webmaster@1
|
177 function node_build_filter_query() { |
webmaster@1
|
178 $filters = node_filters(); |
webmaster@1
|
179 |
webmaster@1
|
180 // Build query |
webmaster@1
|
181 $where = $args = array(); |
webmaster@1
|
182 $join = ''; |
webmaster@1
|
183 foreach ($_SESSION['node_overview_filter'] as $index => $filter) { |
webmaster@1
|
184 list($key, $value) = $filter; |
webmaster@1
|
185 switch ($key) { |
webmaster@1
|
186 case 'status': |
webmaster@1
|
187 // Note: no exploitable hole as $key/$value have already been checked when submitted |
webmaster@1
|
188 list($key, $value) = explode('-', $value, 2); |
webmaster@1
|
189 $where[] = 'n.'. $key .' = %d'; |
webmaster@1
|
190 break; |
webmaster@1
|
191 case 'category': |
webmaster@1
|
192 $table = "tn$index"; |
webmaster@1
|
193 $where[] = "$table.tid = %d"; |
webmaster@1
|
194 $join .= "INNER JOIN {term_node} $table ON n.nid = $table.nid "; |
webmaster@1
|
195 break; |
webmaster@1
|
196 case 'type': |
webmaster@1
|
197 $where[] = "n.type = '%s'"; |
webmaster@1
|
198 break; |
webmaster@1
|
199 case 'language': |
webmaster@1
|
200 $where[] = "n.language = '%s'"; |
webmaster@1
|
201 break; |
webmaster@1
|
202 } |
webmaster@1
|
203 $args[] = $value; |
webmaster@1
|
204 } |
webmaster@1
|
205 $where = count($where) ? 'WHERE '. implode(' AND ', $where) : ''; |
webmaster@1
|
206 |
webmaster@1
|
207 return array('where' => $where, 'join' => $join, 'args' => $args); |
webmaster@1
|
208 } |
webmaster@1
|
209 |
webmaster@1
|
210 /** |
webmaster@1
|
211 * Return form for node administration filters. |
webmaster@1
|
212 */ |
webmaster@1
|
213 function node_filter_form() { |
webmaster@1
|
214 $session = &$_SESSION['node_overview_filter']; |
webmaster@1
|
215 $session = is_array($session) ? $session : array(); |
webmaster@1
|
216 $filters = node_filters(); |
webmaster@1
|
217 |
webmaster@1
|
218 $i = 0; |
webmaster@1
|
219 $form['filters'] = array( |
webmaster@1
|
220 '#type' => 'fieldset', |
webmaster@1
|
221 '#title' => t('Show only items where'), |
webmaster@1
|
222 '#theme' => 'node_filters', |
webmaster@1
|
223 ); |
webmaster@1
|
224 $form['#submit'][] = 'node_filter_form_submit'; |
webmaster@1
|
225 foreach ($session as $filter) { |
webmaster@1
|
226 list($type, $value) = $filter; |
webmaster@1
|
227 if ($type == 'category') { |
webmaster@1
|
228 // Load term name from DB rather than search and parse options array. |
webmaster@1
|
229 $value = module_invoke('taxonomy', 'get_term', $value); |
webmaster@1
|
230 $value = $value->name; |
webmaster@1
|
231 } |
webmaster@1
|
232 else if ($type == 'language') { |
webmaster@1
|
233 $value = empty($value) ? t('Language neutral') : module_invoke('locale', 'language_name', $value); |
webmaster@1
|
234 } |
webmaster@1
|
235 else { |
webmaster@1
|
236 $value = $filters[$type]['options'][$value]; |
webmaster@1
|
237 } |
webmaster@1
|
238 if ($i++) { |
webmaster@1
|
239 $form['filters']['current'][] = array('#value' => t('<em>and</em> where <strong>%a</strong> is <strong>%b</strong>', array('%a' => $filters[$type]['title'], '%b' => $value))); |
webmaster@1
|
240 } |
webmaster@1
|
241 else { |
webmaster@1
|
242 $form['filters']['current'][] = array('#value' => t('<strong>%a</strong> is <strong>%b</strong>', array('%a' => $filters[$type]['title'], '%b' => $value))); |
webmaster@1
|
243 } |
webmaster@1
|
244 if (in_array($type, array('type', 'language'))) { |
webmaster@1
|
245 // Remove the option if it is already being filtered on. |
webmaster@1
|
246 unset($filters[$type]); |
webmaster@1
|
247 } |
webmaster@1
|
248 } |
webmaster@1
|
249 |
webmaster@1
|
250 foreach ($filters as $key => $filter) { |
webmaster@1
|
251 $names[$key] = $filter['title']; |
webmaster@1
|
252 $form['filters']['status'][$key] = array('#type' => 'select', '#options' => $filter['options']); |
webmaster@1
|
253 } |
webmaster@1
|
254 |
webmaster@1
|
255 $form['filters']['filter'] = array('#type' => 'radios', '#options' => $names, '#default_value' => 'status'); |
webmaster@1
|
256 $form['filters']['buttons']['submit'] = array('#type' => 'submit', '#value' => (count($session) ? t('Refine') : t('Filter'))); |
webmaster@1
|
257 if (count($session)) { |
webmaster@1
|
258 $form['filters']['buttons']['undo'] = array('#type' => 'submit', '#value' => t('Undo')); |
webmaster@1
|
259 $form['filters']['buttons']['reset'] = array('#type' => 'submit', '#value' => t('Reset')); |
webmaster@1
|
260 } |
webmaster@1
|
261 |
webmaster@1
|
262 drupal_add_js('misc/form.js', 'core'); |
webmaster@1
|
263 |
webmaster@1
|
264 return $form; |
webmaster@1
|
265 } |
webmaster@1
|
266 |
webmaster@1
|
267 /** |
webmaster@1
|
268 * Theme node administration filter form. |
webmaster@1
|
269 * |
webmaster@1
|
270 * @ingroup themeable |
webmaster@1
|
271 */ |
webmaster@1
|
272 function theme_node_filter_form($form) { |
webmaster@1
|
273 $output = ''; |
webmaster@1
|
274 $output .= '<div id="node-admin-filter">'; |
webmaster@1
|
275 $output .= drupal_render($form['filters']); |
webmaster@1
|
276 $output .= '</div>'; |
webmaster@1
|
277 $output .= drupal_render($form); |
webmaster@1
|
278 return $output; |
webmaster@1
|
279 } |
webmaster@1
|
280 |
webmaster@1
|
281 /** |
webmaster@1
|
282 * Theme node administration filter selector. |
webmaster@1
|
283 * |
webmaster@1
|
284 * @ingroup themeable |
webmaster@1
|
285 */ |
webmaster@1
|
286 function theme_node_filters($form) { |
webmaster@1
|
287 $output = ''; |
webmaster@1
|
288 $output .= '<ul class="clear-block">'; |
webmaster@1
|
289 if (!empty($form['current'])) { |
webmaster@1
|
290 foreach (element_children($form['current']) as $key) { |
webmaster@1
|
291 $output .= '<li>'. drupal_render($form['current'][$key]) .'</li>'; |
webmaster@1
|
292 } |
webmaster@1
|
293 } |
webmaster@1
|
294 |
webmaster@1
|
295 $output .= '<li><dl class="multiselect">'. (!empty($form['current']) ? '<dt><em>'. t('and') .'</em> '. t('where') .'</dt>' : '') .'<dd class="a">'; |
webmaster@1
|
296 foreach (element_children($form['filter']) as $key) { |
webmaster@1
|
297 $output .= drupal_render($form['filter'][$key]); |
webmaster@1
|
298 } |
webmaster@1
|
299 $output .= '</dd>'; |
webmaster@1
|
300 |
webmaster@1
|
301 $output .= '<dt>'. t('is') .'</dt><dd class="b">'; |
webmaster@1
|
302 |
webmaster@1
|
303 foreach (element_children($form['status']) as $key) { |
webmaster@1
|
304 $output .= drupal_render($form['status'][$key]); |
webmaster@1
|
305 } |
webmaster@1
|
306 $output .= '</dd>'; |
webmaster@1
|
307 |
webmaster@1
|
308 $output .= '</dl>'; |
webmaster@1
|
309 $output .= '<div class="container-inline" id="node-admin-buttons">'. drupal_render($form['buttons']) .'</div>'; |
webmaster@1
|
310 $output .= '</li></ul>'; |
webmaster@1
|
311 |
webmaster@1
|
312 return $output; |
webmaster@1
|
313 } |
webmaster@1
|
314 |
webmaster@1
|
315 /** |
webmaster@1
|
316 * Process result from node administration filter form. |
webmaster@1
|
317 */ |
webmaster@1
|
318 function node_filter_form_submit($form, &$form_state) { |
webmaster@1
|
319 $filters = node_filters(); |
webmaster@1
|
320 switch ($form_state['values']['op']) { |
webmaster@1
|
321 case t('Filter'): |
webmaster@1
|
322 case t('Refine'): |
webmaster@1
|
323 if (isset($form_state['values']['filter'])) { |
webmaster@1
|
324 $filter = $form_state['values']['filter']; |
webmaster@1
|
325 |
webmaster@1
|
326 // Flatten the options array to accommodate hierarchical/nested options. |
webmaster@1
|
327 $flat_options = form_options_flatten($filters[$filter]['options']); |
webmaster@1
|
328 |
webmaster@1
|
329 if (isset($flat_options[$form_state['values'][$filter]])) { |
webmaster@1
|
330 $_SESSION['node_overview_filter'][] = array($filter, $form_state['values'][$filter]); |
webmaster@1
|
331 } |
webmaster@1
|
332 } |
webmaster@1
|
333 break; |
webmaster@1
|
334 case t('Undo'): |
webmaster@1
|
335 array_pop($_SESSION['node_overview_filter']); |
webmaster@1
|
336 break; |
webmaster@1
|
337 case t('Reset'): |
webmaster@1
|
338 $_SESSION['node_overview_filter'] = array(); |
webmaster@1
|
339 break; |
webmaster@1
|
340 } |
webmaster@1
|
341 } |
webmaster@1
|
342 |
webmaster@1
|
343 /** |
webmaster@1
|
344 * Make mass update of nodes, changing all nodes in the $nodes array |
webmaster@1
|
345 * to update them with the field values in $updates. |
webmaster@1
|
346 * |
webmaster@1
|
347 * IMPORTANT NOTE: This function is intended to work when called |
webmaster@1
|
348 * from a form submit handler. Calling it outside of the form submission |
webmaster@1
|
349 * process may not work correctly. |
webmaster@1
|
350 * |
webmaster@1
|
351 * @param array $nodes |
webmaster@1
|
352 * Array of node nids to update. |
webmaster@1
|
353 * @param array $updates |
webmaster@1
|
354 * Array of key/value pairs with node field names and the |
webmaster@1
|
355 * value to update that field to. |
webmaster@1
|
356 */ |
webmaster@1
|
357 function node_mass_update($nodes, $updates) { |
webmaster@1
|
358 // We use batch processing to prevent timeout when updating a large number |
webmaster@1
|
359 // of nodes. |
webmaster@1
|
360 if (count($nodes) > 10) { |
webmaster@1
|
361 $batch = array( |
webmaster@1
|
362 'operations' => array( |
webmaster@1
|
363 array('_node_mass_update_batch_process', array($nodes, $updates)) |
webmaster@1
|
364 ), |
webmaster@1
|
365 'finished' => '_node_mass_update_batch_finished', |
webmaster@1
|
366 'title' => t('Processing'), |
webmaster@1
|
367 // We use a single multi-pass operation, so the default |
webmaster@1
|
368 // 'Remaining x of y operations' message will be confusing here. |
webmaster@1
|
369 'progress_message' => '', |
webmaster@1
|
370 'error_message' => t('The update has encountered an error.'), |
webmaster@1
|
371 // The operations do not live in the .module file, so we need to |
webmaster@1
|
372 // tell the batch engine which file to load before calling them. |
webmaster@1
|
373 'file' => drupal_get_path('module', 'node') .'/node.admin.inc', |
webmaster@1
|
374 ); |
webmaster@1
|
375 batch_set($batch); |
webmaster@1
|
376 } |
webmaster@1
|
377 else { |
webmaster@1
|
378 foreach ($nodes as $nid) { |
webmaster@1
|
379 _node_mass_update_helper($nid, $updates); |
webmaster@1
|
380 } |
webmaster@1
|
381 drupal_set_message(t('The update has been performed.')); |
webmaster@1
|
382 } |
webmaster@1
|
383 } |
webmaster@1
|
384 |
webmaster@1
|
385 /** |
webmaster@1
|
386 * Node Mass Update - helper function. |
webmaster@1
|
387 */ |
webmaster@1
|
388 function _node_mass_update_helper($nid, $updates) { |
webmaster@1
|
389 $node = node_load($nid, NULL, TRUE); |
webmaster@1
|
390 foreach ($updates as $name => $value) { |
webmaster@1
|
391 $node->$name = $value; |
webmaster@1
|
392 } |
webmaster@1
|
393 node_save($node); |
webmaster@1
|
394 return $node; |
webmaster@1
|
395 } |
webmaster@1
|
396 |
webmaster@1
|
397 /** |
webmaster@1
|
398 * Node Mass Update Batch operation |
webmaster@1
|
399 */ |
webmaster@1
|
400 function _node_mass_update_batch_process($nodes, $updates, &$context) { |
webmaster@1
|
401 if (!isset($context['sandbox']['progress'])) { |
webmaster@1
|
402 $context['sandbox']['progress'] = 0; |
webmaster@1
|
403 $context['sandbox']['max'] = count($nodes); |
webmaster@1
|
404 $context['sandbox']['nodes'] = $nodes; |
webmaster@1
|
405 } |
webmaster@1
|
406 |
webmaster@1
|
407 // Process nodes by groups of 5. |
webmaster@1
|
408 $count = min(5, count($context['sandbox']['nodes'])); |
webmaster@1
|
409 for ($i = 1; $i <= $count; $i++) { |
webmaster@1
|
410 // For each nid, load the node, reset the values, and save it. |
webmaster@1
|
411 $nid = array_shift($context['sandbox']['nodes']); |
webmaster@1
|
412 $node = _node_mass_update_helper($nid, $updates); |
webmaster@1
|
413 |
webmaster@1
|
414 // Store result for post-processing in the finished callback. |
webmaster@1
|
415 $context['results'][] = l($node->title, 'node/'. $node->nid); |
webmaster@1
|
416 |
webmaster@1
|
417 // Update our progress information. |
webmaster@1
|
418 $context['sandbox']['progress']++; |
webmaster@1
|
419 } |
webmaster@1
|
420 |
webmaster@1
|
421 // Inform the batch engine that we are not finished, |
webmaster@1
|
422 // and provide an estimation of the completion level we reached. |
webmaster@1
|
423 if ($context['sandbox']['progress'] != $context['sandbox']['max']) { |
webmaster@1
|
424 $context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max']; |
webmaster@1
|
425 } |
webmaster@1
|
426 } |
webmaster@1
|
427 |
webmaster@1
|
428 /** |
webmaster@1
|
429 * Node Mass Update Batch 'finished' callback. |
webmaster@1
|
430 */ |
webmaster@1
|
431 function _node_mass_update_batch_finished($success, $results, $operations) { |
webmaster@1
|
432 if ($success) { |
webmaster@1
|
433 drupal_set_message(t('The update has been performed.')); |
webmaster@1
|
434 } |
webmaster@1
|
435 else { |
webmaster@1
|
436 drupal_set_message(t('An error occurred and processing did not complete.'), 'error'); |
webmaster@1
|
437 $message = format_plural(count($results), '1 item successfully processed:', '@count items successfully processed:'); |
webmaster@1
|
438 $message .= theme('item_list', $results); |
webmaster@1
|
439 drupal_set_message($message); |
webmaster@1
|
440 } |
webmaster@1
|
441 } |
webmaster@1
|
442 |
webmaster@1
|
443 /** |
webmaster@1
|
444 * Menu callback: content administration. |
webmaster@1
|
445 */ |
webmaster@1
|
446 function node_admin_content($form_state) { |
webmaster@1
|
447 if (isset($form_state['values']['operation']) && $form_state['values']['operation'] == 'delete') { |
webmaster@1
|
448 return node_multiple_delete_confirm($form_state, array_filter($form_state['values']['nodes'])); |
webmaster@1
|
449 } |
webmaster@1
|
450 $form = node_filter_form(); |
webmaster@1
|
451 |
webmaster@1
|
452 $form['#theme'] = 'node_filter_form'; |
webmaster@1
|
453 $form['admin'] = node_admin_nodes(); |
webmaster@1
|
454 |
webmaster@1
|
455 return $form; |
webmaster@1
|
456 } |
webmaster@1
|
457 |
webmaster@1
|
458 /** |
webmaster@1
|
459 * Form builder: Builds the node administration overview. |
webmaster@1
|
460 */ |
webmaster@1
|
461 function node_admin_nodes() { |
webmaster@1
|
462 |
webmaster@1
|
463 $filter = node_build_filter_query(); |
webmaster@1
|
464 |
webmaster@1
|
465 $result = pager_query(db_rewrite_sql('SELECT n.*, u.name FROM {node} n '. $filter['join'] .' INNER JOIN {users} u ON n.uid = u.uid '. $filter['where'] .' ORDER BY n.changed DESC'), 50, 0, NULL, $filter['args']); |
webmaster@1
|
466 |
webmaster@1
|
467 // Enable language column if locale is enabled or if we have any node with language |
webmaster@1
|
468 $count = db_result(db_query("SELECT COUNT(*) FROM {node} n WHERE language != ''")); |
webmaster@1
|
469 $multilanguage = (module_exists('locale') || $count); |
webmaster@1
|
470 |
webmaster@1
|
471 $form['options'] = array( |
webmaster@1
|
472 '#type' => 'fieldset', |
webmaster@1
|
473 '#title' => t('Update options'), |
webmaster@1
|
474 '#prefix' => '<div class="container-inline">', |
webmaster@1
|
475 '#suffix' => '</div>', |
webmaster@1
|
476 ); |
webmaster@1
|
477 $options = array(); |
webmaster@1
|
478 foreach (module_invoke_all('node_operations') as $operation => $array) { |
webmaster@1
|
479 $options[$operation] = $array['label']; |
webmaster@1
|
480 } |
webmaster@1
|
481 $form['options']['operation'] = array( |
webmaster@1
|
482 '#type' => 'select', |
webmaster@1
|
483 '#options' => $options, |
webmaster@1
|
484 '#default_value' => 'approve', |
webmaster@1
|
485 ); |
webmaster@1
|
486 $form['options']['submit'] = array( |
webmaster@1
|
487 '#type' => 'submit', |
webmaster@1
|
488 '#value' => t('Update'), |
webmaster@1
|
489 '#submit' => array('node_admin_nodes_submit'), |
webmaster@1
|
490 ); |
webmaster@1
|
491 |
webmaster@1
|
492 $languages = language_list(); |
webmaster@1
|
493 $destination = drupal_get_destination(); |
webmaster@1
|
494 $nodes = array(); |
webmaster@1
|
495 while ($node = db_fetch_object($result)) { |
webmaster@1
|
496 $nodes[$node->nid] = ''; |
webmaster@1
|
497 $options = empty($node->language) ? array() : array('language' => $languages[$node->language]); |
webmaster@1
|
498 $form['title'][$node->nid] = array('#value' => l($node->title, 'node/'. $node->nid, $options) .' '. theme('mark', node_mark($node->nid, $node->changed))); |
webmaster@1
|
499 $form['name'][$node->nid] = array('#value' => check_plain(node_get_types('name', $node))); |
webmaster@1
|
500 $form['username'][$node->nid] = array('#value' => theme('username', $node)); |
webmaster@1
|
501 $form['status'][$node->nid] = array('#value' => ($node->status ? t('published') : t('not published'))); |
webmaster@1
|
502 if ($multilanguage) { |
webmaster@1
|
503 $form['language'][$node->nid] = array('#value' => empty($node->language) ? t('Language neutral') : t($languages[$node->language]->name)); |
webmaster@1
|
504 } |
webmaster@1
|
505 $form['operations'][$node->nid] = array('#value' => l(t('edit'), 'node/'. $node->nid .'/edit', array('query' => $destination))); |
webmaster@1
|
506 } |
webmaster@1
|
507 $form['nodes'] = array('#type' => 'checkboxes', '#options' => $nodes); |
webmaster@1
|
508 $form['pager'] = array('#value' => theme('pager', NULL, 50, 0)); |
webmaster@1
|
509 $form['#theme'] = 'node_admin_nodes'; |
webmaster@1
|
510 return $form; |
webmaster@1
|
511 } |
webmaster@1
|
512 |
webmaster@1
|
513 /** |
webmaster@1
|
514 * Validate node_admin_nodes form submissions. |
webmaster@1
|
515 * |
webmaster@1
|
516 * Check if any nodes have been selected to perform the chosen |
webmaster@1
|
517 * 'Update option' on. |
webmaster@1
|
518 */ |
webmaster@1
|
519 function node_admin_nodes_validate($form, &$form_state) { |
webmaster@1
|
520 $nodes = array_filter($form_state['values']['nodes']); |
webmaster@1
|
521 if (count($nodes) == 0) { |
webmaster@1
|
522 form_set_error('', t('No items selected.')); |
webmaster@1
|
523 } |
webmaster@1
|
524 } |
webmaster@1
|
525 |
webmaster@1
|
526 /** |
webmaster@1
|
527 * Process node_admin_nodes form submissions. |
webmaster@1
|
528 * |
webmaster@1
|
529 * Execute the chosen 'Update option' on the selected nodes. |
webmaster@1
|
530 */ |
webmaster@1
|
531 function node_admin_nodes_submit($form, &$form_state) { |
webmaster@1
|
532 $operations = module_invoke_all('node_operations'); |
webmaster@1
|
533 $operation = $operations[$form_state['values']['operation']]; |
webmaster@1
|
534 // Filter out unchecked nodes |
webmaster@1
|
535 $nodes = array_filter($form_state['values']['nodes']); |
webmaster@1
|
536 if ($function = $operation['callback']) { |
webmaster@1
|
537 // Add in callback arguments if present. |
webmaster@1
|
538 if (isset($operation['callback arguments'])) { |
webmaster@1
|
539 $args = array_merge(array($nodes), $operation['callback arguments']); |
webmaster@1
|
540 } |
webmaster@1
|
541 else { |
webmaster@1
|
542 $args = array($nodes); |
webmaster@1
|
543 } |
webmaster@1
|
544 call_user_func_array($function, $args); |
webmaster@1
|
545 |
webmaster@1
|
546 cache_clear_all(); |
webmaster@1
|
547 } |
webmaster@1
|
548 else { |
webmaster@1
|
549 // We need to rebuild the form to go to a second step. For example, to |
webmaster@1
|
550 // show the confirmation form for the deletion of nodes. |
webmaster@1
|
551 $form_state['rebuild'] = TRUE; |
webmaster@1
|
552 } |
webmaster@1
|
553 } |
webmaster@1
|
554 |
webmaster@1
|
555 |
webmaster@1
|
556 /** |
webmaster@1
|
557 * Theme node administration overview. |
webmaster@1
|
558 * |
webmaster@1
|
559 * @ingroup themeable |
webmaster@1
|
560 */ |
webmaster@1
|
561 function theme_node_admin_nodes($form) { |
webmaster@1
|
562 // If there are rows in this form, then $form['title'] contains a list of |
webmaster@1
|
563 // the title form elements. |
webmaster@1
|
564 $has_posts = isset($form['title']) && is_array($form['title']); |
webmaster@1
|
565 $select_header = $has_posts ? theme('table_select_header_cell') : ''; |
webmaster@1
|
566 $header = array($select_header, t('Title'), t('Type'), t('Author'), t('Status')); |
webmaster@1
|
567 if (isset($form['language'])) { |
webmaster@1
|
568 $header[] = t('Language'); |
webmaster@1
|
569 } |
webmaster@1
|
570 $header[] = t('Operations'); |
webmaster@1
|
571 $output = ''; |
webmaster@1
|
572 |
webmaster@1
|
573 $output .= drupal_render($form['options']); |
webmaster@1
|
574 if ($has_posts) { |
webmaster@1
|
575 foreach (element_children($form['title']) as $key) { |
webmaster@1
|
576 $row = array(); |
webmaster@1
|
577 $row[] = drupal_render($form['nodes'][$key]); |
webmaster@1
|
578 $row[] = drupal_render($form['title'][$key]); |
webmaster@1
|
579 $row[] = drupal_render($form['name'][$key]); |
webmaster@1
|
580 $row[] = drupal_render($form['username'][$key]); |
webmaster@1
|
581 $row[] = drupal_render($form['status'][$key]); |
webmaster@1
|
582 if (isset($form['language'])) { |
webmaster@1
|
583 $row[] = drupal_render($form['language'][$key]); |
webmaster@1
|
584 } |
webmaster@1
|
585 $row[] = drupal_render($form['operations'][$key]); |
webmaster@1
|
586 $rows[] = $row; |
webmaster@1
|
587 } |
webmaster@1
|
588 |
webmaster@1
|
589 } |
webmaster@1
|
590 else { |
webmaster@1
|
591 $rows[] = array(array('data' => t('No posts available.'), 'colspan' => '6')); |
webmaster@1
|
592 } |
webmaster@1
|
593 |
webmaster@1
|
594 $output .= theme('table', $header, $rows); |
webmaster@1
|
595 if ($form['pager']['#value']) { |
webmaster@1
|
596 $output .= drupal_render($form['pager']); |
webmaster@1
|
597 } |
webmaster@1
|
598 |
webmaster@1
|
599 $output .= drupal_render($form); |
webmaster@1
|
600 |
webmaster@1
|
601 return $output; |
webmaster@1
|
602 } |
webmaster@1
|
603 |
webmaster@1
|
604 function node_multiple_delete_confirm(&$form_state, $nodes) { |
webmaster@1
|
605 |
webmaster@1
|
606 $form['nodes'] = array('#prefix' => '<ul>', '#suffix' => '</ul>', '#tree' => TRUE); |
webmaster@1
|
607 // array_filter returns only elements with TRUE values |
webmaster@1
|
608 foreach ($nodes as $nid => $value) { |
webmaster@1
|
609 $title = db_result(db_query('SELECT title FROM {node} WHERE nid = %d', $nid)); |
webmaster@1
|
610 $form['nodes'][$nid] = array( |
webmaster@1
|
611 '#type' => 'hidden', |
webmaster@1
|
612 '#value' => $nid, |
webmaster@1
|
613 '#prefix' => '<li>', |
webmaster@1
|
614 '#suffix' => check_plain($title) ."</li>\n", |
webmaster@1
|
615 ); |
webmaster@1
|
616 } |
webmaster@1
|
617 $form['operation'] = array('#type' => 'hidden', '#value' => 'delete'); |
webmaster@1
|
618 $form['#submit'][] = 'node_multiple_delete_confirm_submit'; |
webmaster@1
|
619 return confirm_form($form, |
webmaster@1
|
620 t('Are you sure you want to delete these items?'), |
webmaster@1
|
621 'admin/content/node', t('This action cannot be undone.'), |
webmaster@1
|
622 t('Delete all'), t('Cancel')); |
webmaster@1
|
623 } |
webmaster@1
|
624 |
webmaster@1
|
625 function node_multiple_delete_confirm_submit($form, &$form_state) { |
webmaster@1
|
626 if ($form_state['values']['confirm']) { |
webmaster@1
|
627 foreach ($form_state['values']['nodes'] as $nid => $value) { |
webmaster@1
|
628 node_delete($nid); |
webmaster@1
|
629 } |
webmaster@1
|
630 drupal_set_message(t('The items have been deleted.')); |
webmaster@1
|
631 } |
webmaster@1
|
632 $form_state['redirect'] = 'admin/content/node'; |
webmaster@1
|
633 return; |
webmaster@1
|
634 } |
webmaster@1
|
635 |