annotate modules/node/node.admin.inc @ 20:e3d20ebd63d1 tip

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