annotate modules/node/node.admin.inc @ 1:c1f4ac30525a 6.0

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