Index: pathauto.admin.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/pathauto/pathauto.admin.inc,v retrieving revision 1.20.2.5 diff -u -p -r1.20.2.5 pathauto.admin.inc --- pathauto.admin.inc 2 Mar 2010 20:38:16 -0000 1.20.2.5 +++ pathauto.admin.inc 3 Mar 2010 00:23:13 -0000 @@ -79,15 +79,6 @@ function pathauto_admin_settings() { '#description' => t('Maximum text length of any component in the alias (e.g., [title]). 100 is the recommended length. @max is the maximum possible length. See Pathauto help for details.', array('@pathauto-help' => url('admin/help/pathauto'), '@max' => _pathauto_get_schema_alias_maxlength())), ); - $form['general']['pathauto_max_bulk_update'] = array( - '#type' => 'textfield', - '#title' => t('Maximum number of objects to alias in a bulk update'), - '#size' => 4, - '#maxlength' => 4, - '#default_value' => variable_get('pathauto_max_bulk_update', 50), - '#description' => t('Maximum number of objects of a given type which should be aliased during a bulk update. The default is 50 and the recommended number depends on the speed of your server. If bulk updates "time out" or result in a "white screen" then reduce the number.'), - ); - $actions = array( t('Do nothing. Leave the old alias intact.'), t('Create a new alias. Leave the existing alias functioning.'), @@ -172,10 +163,8 @@ function pathauto_admin_settings() { // Call the hook on all modules - an array of 'settings' objects is returned $all_settings = module_invoke_all('pathauto', 'settings'); - $modulelist = ''; - $indexcount = 0; + $modulelist = array(); foreach ($all_settings as $settings) { - $items = ''; $module = $settings->module; $modulelist[] = $module; $patterndescr = $settings->patterndescr; @@ -254,22 +243,6 @@ function pathauto_admin_settings() { '#value' => $doc, ); - // If the module supports bulk updates, offer the update action here - if ($settings->bulkname) { - $variable = 'pathauto_' . $module . '_bulkupdate'; - if (variable_get($variable, FALSE)) { - variable_set($variable, FALSE); - $function = $module . '_pathauto_bulkupdate'; - call_user_func($function); - } - $form[$module][$variable] = array( - '#type' => 'checkbox', - '#title' => $settings->bulkname, - '#default_value' => FALSE, - '#description' => $settings->bulkdescr, - ); - } - // If the module supports feeds, offer to generate aliases for them if ($supportsfeeds) { $variable = 'pathauto_' . $module . '_applytofeeds'; @@ -288,13 +261,6 @@ function pathauto_admin_settings() { '#description' => t('The text to use for aliases for RSS feeds. Examples are "0/feed" (used throughout Drupal core) and "feed" (used by some contributed Drupal modules, like Views).'), ); } - - } - - if (isset($do_index_bulkupdate) && $do_index_bulkupdate) { - drupal_set_message(format_plural($indexcount, - 'Bulk generation of index aliases completed, one alias generated.', - 'Bulk generation of index aliases completed, @count aliases generated.')); } // Keep track of which modules currently support pathauto @@ -388,6 +354,105 @@ function pathauto_admin_settings_validat } /** + * Form contructor for path alias bulk update form. + */ +function pathauto_admin_update() { + _pathauto_include(); + + $form['#tree'] = TRUE; + + $modules = variable_get('pathauto_modulelist', array()); + foreach ($modules as $module) { + $settings = module_invoke($module, 'pathauto', 'settings'); + if (empty($settings) || empty($settings->bulkname)) { + continue; + } + $form['bulk_update'][$module] = array( + '#type' => 'checkbox', + '#title' => $settings->bulkname, + '#default_value' => FALSE, + ); + if (!empty($settings->bulkdescr)) { + $form['bulk_update'][$module]['#description'] = $settings->bulkdescr; + } + } + + $form['actions']['submit'] = array('#type' => 'submit', '#value' => t('Update')); + + return $form; +} + +/** + * Form submit handler for path alias bulk update form. + */ +function pathauto_admin_update_submit($form, &$form_state) { + // Disable pathauto verbose mode; backup current value to restore it later. + // In case a previous bulk update failed for any reason, the temporary + // variable will be set already. + $mode = variable_get('pathauto_batch_verbose', NULL); + if (!isset($mode)) { + variable_set('pathauto_batch_verbose', variable_get('pathauto_verbose', FALSE)); + variable_set('pathauto_verbose', FALSE); + } + + $path = drupal_get_path('module', 'pathauto'); + + $batch = array( + 'title' => t('Bulk updating path aliases'), + 'operations' => array(), + 'finished' => 'pathauto_admin_update_batch_finished', + 'file' => $path . '/pathauto.admin.inc', + ); + foreach ($form_state['values']['bulk_update'] as $module => $value) { + if (!empty($value)) { + $batch['operations'][] = array('pathauto_admin_update_batch_process', array($module)); + } + } + batch_set($batch); +} + +/** + * Common batch processing callback for all operations. + * + * Required to load our include files. + * + * @todo Allow other modules to also load an include file? + */ +function pathauto_admin_update_batch_process($module, &$context) { + _pathauto_include(); + + if (!isset($context['results']['count'])) { + $context['results']['count'] = 0; + } + + $function = $module . '_pathauto_batch_update'; + $function($context); +} + +/** + * Batch finished callback. + */ +function pathauto_admin_update_batch_finished($success, $results, $operations) { + // This finished callback also needs to be invoked in case nothing happened, + // so we can restore the verbose mode below. + if (isset($results['count'])) { + if ($success) { + $message = format_plural($results['count'], 'One alias generated.', '@count aliases generated.'); + $type = 'success'; + } + else { + $message = t('Finished with errors.'); + $type = 'error'; + } + drupal_set_message($message, $type); + } + + // Restore verbose mode setting. + variable_set('pathauto_verbose', variable_get('pathauto_batch_verbose', FALSE)); + variable_del('pathauto_batch_verbose'); +} + +/** * Menu callback; select certain alias types to delete. */ function pathauto_admin_delete() { @@ -472,8 +537,8 @@ function pathauto_admin_delete_submit($f */ function _pathauto_warn_wysiwygs() { $wysiwygs = array( - 'bueditor', 'fckeditor', 'htmlarea', 'htmlbox', 'tinymce', 'whizzywig', - 'widgeditor', 'wymeditor', 'wysiwyg', 'xstandard', 'yui_editor', + 'bueditor', 'ckeditor', 'fckeditor', 'htmlarea', 'htmlbox', 'tinymce', 'whizzywig', + 'widgeditor', 'wymeditor', 'xstandard', 'yui_editor', ); $wysiwyg_problem = FALSE; Index: pathauto.install =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/pathauto/pathauto.install,v retrieving revision 1.14 diff -u -p -r1.14 pathauto.install --- pathauto.install 17 Oct 2009 17:36:58 -0000 1.14 +++ pathauto.install 3 Mar 2010 00:05:15 -0000 @@ -108,3 +108,12 @@ function pathauto_update_7() { } return $ret; } + +/** + * Remove the maximum aliases for bulk updates variable (processing via batch now). + */ +function pathauto_update_6201() { + $ret = array(); + variable_del('pathauto_max_bulk_update'); + return $ret; +} Index: pathauto.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/pathauto/pathauto.module,v retrieving revision 1.126.2.19 diff -u -p -r1.126.2.19 pathauto.module --- pathauto.module 2 Mar 2010 23:04:09 -0000 1.126.2.19 +++ pathauto.module 3 Mar 2010 00:07:50 -0000 @@ -69,7 +69,14 @@ function pathauto_menu() { 'page arguments' => array('pathauto_admin_delete'), 'access arguments' => array('administer url aliases'), 'type' => MENU_LOCAL_TASK, - 'weight' => 11, + 'file' => 'pathauto.admin.inc', + ); + $items['admin/build/path/update_bulk'] = array( + 'title' => 'Bulk update', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('pathauto_admin_update'), + 'access arguments' => array('administer url aliases'), + 'type' => MENU_LOCAL_TASK, 'file' => 'pathauto.admin.inc', ); @@ -112,14 +119,17 @@ function pathauto_path_alias_types() { if (module_exists('blog')) { $objects['blog/'] = t('User blogs'); } + if (module_exists('contact')) { + $objects['user/%/contact'] = t('User contact forms'); + } if (module_exists('taxonomy')) { - $objects['taxonomy/'] = t('Vocabularies and terms'); + $objects['taxonomy/term/'] = t('Vocabularies and terms'); } if (module_exists('tracker')) { $objects['user/%/track'] = t('User trackers'); } if (module_exists('forum')) { - $objects['forum/%'] = t('Forums'); + $objects['forum/'] = t('Forums'); } return $objects; } Index: pathauto.test =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/pathauto/pathauto.test,v retrieving revision 1.1.4.4 diff -u -p -r1.1.4.4 pathauto.test --- pathauto.test 2 Mar 2010 23:04:09 -0000 1.1.4.4 +++ pathauto.test 3 Mar 2010 01:35:54 -0000 @@ -193,3 +193,48 @@ class PathautoBookTokenTestCase extends $this->assertNodeAlias($sub_child_node1, 'root/sub-page1/sub-sub-page1'); } } + +/** + * Bulk update functionality tests. + */ +class PathautoBulkUpdateTestCase extends PathautoTestHelper { + public static function getInfo() { + return array( + 'name' => 'Bulk updates', + 'description' => 'Tests bulk updating of URL aliases.', + 'group' => 'Pathauto', + ); + } + + function setUp() { + parent::setUp(); + } + + function testBulkCreate() { + // Remove node page pattern. + variable_del('pathauto_node_page_pattern'); + variable_del('pathauto_node_pattern'); + + // Create some nodes. + $this->nodes = array(); + foreach (range(0, 9) as $num) { + $this->nodes[$num] = $this->drupalCreateNode(array('type' => 'page')); + // Verify that there is no alias after creation. + $path = 'node/' . $this->nodes[$num]->nid; + $alias = drupal_lookup_path('alias', $path); + $this->assertFalse($alias); + } + + // Setup node page pattern. + variable_set('pathauto_node_page_pattern', 'content/[title-raw]'); + + // Bulk create aliases. + $edit = array( + 'bulk_update[node]' => TRUE, + ); + $this->drupalPost('admin/build/path/update_bulk', $edit, t('Update')); + $message = format_plural(count($this->nodes), 'One alias generated.', '@count aliases generated.'); + $this->assertText($message); + } +} + Index: pathauto_node.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/pathauto/pathauto_node.inc,v retrieving revision 1.48 diff -u -p -r1.48 pathauto_node.inc --- pathauto_node.inc 28 Jun 2008 15:41:15 -0000 1.48 +++ pathauto_node.inc 3 Mar 2010 00:24:08 -0000 @@ -20,8 +20,7 @@ function node_pathauto($op) { $settings['groupheader'] = t('Node path settings'); $settings['patterndescr'] = t('Default path pattern (applies to all node types with blank patterns below)'); $settings['patterndefault'] = t('content/[title-raw]'); - $settings['bulkname'] = t('Bulk generate aliases for nodes that are not aliased'); - $settings['bulkdescr'] = t('Generate aliases for all existing nodes which do not already have aliases.'); + $settings['bulkname'] = t('Content'); $patterns = token_get_list('node'); foreach ($patterns as $type => $pattern_set) { @@ -62,63 +61,86 @@ function node_pathauto($op) { } /** - * Generate aliases for all nodes without aliases. + * Batch processing callback; Generate aliases for nodes. */ -function node_pathauto_bulkupdate() { - // From all node types, only attempt to update those with patterns - $pattern_types = array(); - - // If there's a default pattern we assume all types might be updated. - if (trim(variable_get('pathauto_node_pattern', ''))) { - $pattern_types = array_keys(node_get_types('names')); - } - else { - // Check first for a node specific pattern... - $languages = array(); - if (module_exists('locale')) { - $languages = array('' => t('Language neutral')) + locale_language_list('name'); - } - foreach (array_keys(node_get_types('names')) as $type) { - if (trim(variable_get('pathauto_node_'. $type .'_pattern', ''))) { - $pattern_types[$type] = $type; - continue; - } - // ...then for a node-language pattern. - if (variable_get('language_content_type_'. $type, 0) && $languages) { - foreach ($languages as $lang_code => $lang_name) { - if (trim(variable_get('pathauto_node_'. $type .'_'. $lang_code .'_pattern', ''))) { - $pattern_types[$type] = $type; - continue 2; +function node_pathauto_batch_update(&$context) { + // Prepare query. + if (!isset($context['sandbox']['query'])) { + // From all node types, only attempt to update those with patterns + $pattern_types = array(); + // If there's a default pattern we assume all types might be updated. + if (trim(variable_get('pathauto_node_pattern', ''))) { + $pattern_types = array_keys(node_get_types('names')); + } + else { + // Check first for a node specific pattern... + $languages = array(); + if (module_exists('locale')) { + $languages = array('' => t('Language neutral')) + locale_language_list('name'); + } + foreach (array_keys(node_get_types('names')) as $type) { + if (trim(variable_get('pathauto_node_'. $type .'_pattern', ''))) { + $pattern_types[$type] = $type; + continue; + } + // ...then for a node-language pattern. + if (variable_get('language_content_type_'. $type, 0) && $languages) { + foreach ($languages as $lang_code => $lang_name) { + if (trim(variable_get('pathauto_node_'. $type .'_'. $lang_code .'_pattern', ''))) { + $pattern_types[$type] = $type; + continue 2; + } } } } } + if (!$pattern_types) { + $context['finished'] = 1; + return; + } + + $context['sandbox']['query'] = "FROM {node} n LEFT JOIN {url_alias} alias ON CONCAT('node/', CAST(n.nid AS CHAR)) = alias.src WHERE alias.src IS NULL AND n.type IN (" . db_placeholders($pattern_types, 'varchar') . ')'; + $context['sandbox']['query_args'] = $pattern_types; } - $count = 0; - if (count($pattern_types)) { - $query = "SELECT n.nid, n.vid, n.type, n.title, n.uid, n.created, n.language, alias.src, alias.dst FROM {node} n LEFT JOIN {url_alias} alias ON CONCAT('node/', CAST(n.nid AS CHAR)) = alias.src WHERE alias.src IS NULL AND n.type IN (". db_placeholders($pattern_types, 'varchar') .')'; - $result = db_query_range($query, $pattern_types, 0, variable_get('pathauto_max_bulk_update', 50)); - - $placeholders = array(); - while ($node_ref = db_fetch_object($result)) { - $node = node_load($node_ref->nid, NULL, TRUE); - $node->src = $node_ref->src; - $node->dst = $node_ref->dst; - if (module_exists('taxonomy')) { - // Must populate the terms for the node here for the category - // placeholders to work - $node->taxonomy = array_keys(taxonomy_node_get_terms($node)); - } - $placeholders = pathauto_get_placeholders('node', $node); - $src = "node/$node->nid"; - if (pathauto_create_alias('node', 'bulkupdate', $placeholders, $src, $node->nid, $node->type, $node->language)) { - $count++; - } + // Get the total amount of items to process. + if (!isset($context['sandbox']['total'])) { + $context['sandbox']['total'] = db_result(db_query("SELECT COUNT(nid) " . $context['sandbox']['query'], $context['sandbox']['query_args'])); + $context['sandbox']['count'] = 0; + $context['sandbox']['items'] = array(); + } + + // Get the next stack of items to process. + if (empty($context['sandbox']['items'])) { + $query = "SELECT n.nid, alias.src, alias.dst " . $context['sandbox']['query']; + $result = db_query_range($query, $context['sandbox']['query_args'], $context['sandbox']['count'], 1000); + while ($row = db_fetch_object($result)) { + $context['sandbox']['items'][] = $row; + } + } + + // Process the next item in the stack. + if ($row = array_shift($context['sandbox']['items'])) { + $context['sandbox']['count']++; + + $node = node_load($row->nid, NULL, TRUE); + $node->src = $row->src; + $node->dst = $row->dst; + // Must populate the terms for the node here for category placeholders. + if (module_exists('taxonomy')) { + $node->taxonomy = array_keys(taxonomy_node_get_terms($node)); + } + $placeholders = pathauto_get_placeholders('node', $node); + $src = "node/$node->nid"; + if (pathauto_create_alias('node', 'bulkupdate', $placeholders, $src, $node->nid, $node->type, $node->language)) { + $type = node_get_types('name', $node); + $context['message'] = t('Updated alias for @type %title', array('@type' => $type, '%title' => $node->title)); + // Update total counter. + $context['results']['count']++; } } - drupal_set_message(format_plural($count, - 'Bulk generation of nodes completed, one alias generated.', - 'Bulk generation of nodes completed, @count aliases generated.')); + if ($context['sandbox']['total'] > 0) { + $context['finished'] = $context['sandbox']['count'] / $context['sandbox']['total']; + } } Index: pathauto_taxonomy.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/pathauto/pathauto_taxonomy.inc,v retrieving revision 1.41.2.1 diff -u -p -r1.41.2.1 pathauto_taxonomy.inc --- pathauto_taxonomy.inc 2 Mar 2010 23:04:09 -0000 1.41.2.1 +++ pathauto_taxonomy.inc 3 Mar 2010 00:28:47 -0000 @@ -29,8 +29,7 @@ function taxonomy_pathauto($op) { } } $settings['supportsfeeds'] = '0/feed'; - $settings['bulkname'] = t('Bulk generate aliases for terms that are not aliased'); - $settings['bulkdescr'] = t('Generate aliases for all existing terms which do not already have aliases.'); + $settings['bulkname'] = t('Taxonomy terms'); $vocabularies = taxonomy_get_vocabularies(); if (sizeof($vocabularies) > 0) { @@ -51,41 +50,73 @@ function taxonomy_pathauto($op) { } /** - * Generate aliases for all categories without aliases. + * Batch processing callback; Generate aliases for taxonomy terms. */ -function taxonomy_pathauto_bulkupdate() { - // From all node types, only attempt to update those with patterns - $pattern_vids = array(); - foreach (taxonomy_get_vocabularies() as $vid => $info) { - // TODO - If there's a default we shouldn't do this crazy where statement because all vocabularies get aliases. - // TODO - Special casing to exclude the forum vid (and the images vid and...?). - if (pathauto_pattern_load_by_entity('taxonomy', $vid)) { - $pattern_vids[] = $vid; - if (empty($vid_where)) { - $vid_where = " AND (vid = '%s' "; +function taxonomy_pathauto_batch_update(&$context) { + // Prepare query. + if (!isset($context['sandbox']['query'])) { + // From all node types, only attempt to update those with patterns + $pattern_vids = array(); + foreach (taxonomy_get_vocabularies() as $vid => $info) { + $pattern = trim(variable_get('pathauto_taxonomy_'. $vid .'_pattern', '')); + + // If it's not set, check the default + // TODO - if there's a default we shouldn't do this crazy where statement because all vocabs get aliases + // TODO - special casing to exclude the forum vid (and the images vid and...?) + if (empty($pattern)) { + $pattern = trim(variable_get('pathauto_taxonomy_pattern', '')); } - else { - $vid_where .= " OR vid = '%s'"; + if (!empty($pattern)) { + $pattern_vids[] = $vid; + if (empty($vid_where)) { + $vid_where = " AND (vid = '%s' "; + } + else { + $vid_where .= " OR vid = '%s'"; + } } } + $vid_where .= ')'; + + // Exclude the forums and join all the args into one array so they can be passed to db_query + $forum_vid[] = variable_get('forum_nav_vocabulary', ''); + $query_args = array_merge($forum_vid, $pattern_vids); + + $context['sandbox']['query'] = "FROM {term_data} LEFT JOIN {url_alias} ON CONCAT('taxonomy/term/', CAST(tid AS CHAR)) = src WHERE src IS NULL AND vid <> %d " . $vid_where; + $context['sandbox']['query_args'] = $query_args; } - $vid_where .= ')'; - // Exclude the forums and join all the args into one array so they can be passed to db_query - $forum_vid[] = variable_get('forum_nav_vocabulary', ''); - $query_args = array_merge($forum_vid, $pattern_vids); - $query = "SELECT tid, vid, name, src, dst FROM {term_data} LEFT JOIN {url_alias} ON CONCAT('taxonomy/term/', CAST(tid AS CHAR)) = src WHERE src IS NULL AND vid <> %d ". $vid_where; - $result = db_query_range($query, $query_args, 0, variable_get('pathauto_max_bulk_update', 50)); + // Get the total amount of items to process. + if (!isset($context['sandbox']['total'])) { + $context['sandbox']['total'] = db_result(db_query("SELECT COUNT(tid) " . $context['sandbox']['query'], $context['sandbox']['query_args'])); + $context['sandbox']['count'] = 0; + $context['sandbox']['items'] = array(); + } - $count = 0; - $placeholders = array(); - while ($category = db_fetch_object($result)) { - $count += _taxonomy_pathauto_alias($category, 'bulkupdate'); + // Get the next stack of items to process. + if (empty($context['sandbox']['items'])) { + $query = "SELECT tid " . $context['sandbox']['query']; + $result = db_query_range($query, $context['sandbox']['query_args'], $context['sandbox']['count'], 1000); + while ($uid = db_result($result)) { + $context['sandbox']['items'][] = $uid; + } + } + + // Process the next item in the stack. + if ($tid = array_shift($context['sandbox']['items'])) { + $context['sandbox']['count']++; + + $category = taxonomy_get_term($tid); + if (_taxonomy_pathauto_alias($category, 'bulkupdate')) { + $context['message'] = t('Updated alias for term %title', array('%title' => $category->name)); + // Update total counter. + $context['results']['count']++; + } } - drupal_set_message(format_plural($count, - 'Bulk generation of terms completed, one alias generated.', - 'Bulk generation of terms completed, @count aliases generated.')); + if ($context['sandbox']['total'] > 0) { + $context['finished'] = $context['sandbox']['count'] / $context['sandbox']['total']; + } } /** @@ -137,8 +168,8 @@ function forum_pathauto($op) { } } $settings['supportsfeeds'] = '0/feed'; - $settings['bulkname'] = t('Bulk generate forum paths'); - $settings['bulkdescr'] = t('Generate aliases for all existing forums and forum containers which do not already have aliases.'); + $settings['bulkname'] = t('Forums'); + $settings['bulkdescr'] = t('Forum containers and forums are handled separately from taxonomy terms.'); return (object) $settings; default: break; @@ -146,20 +177,47 @@ function forum_pathauto($op) { } /** - * Generate aliases for all forums and forum containers without aliases. + * Batch processing callback; Generate aliases for forums. */ -function forum_pathauto_bulkupdate() { - $forum_vid = variable_get('forum_nav_vocabulary', ''); - $query = "SELECT tid, vid, name, src, dst FROM {term_data} LEFT JOIN {url_alias} ON CONCAT('forum/', CAST(tid AS CHAR)) = src WHERE vid = %d AND src IS NULL"; - $result = db_query_range($query, $forum_vid, 0, variable_get('pathauto_max_bulk_update', 50)); +function forum_pathauto_batch_update(&$context) { + // Prepare query. + if (!isset($context['sandbox']['query'])) { + $forum_vid = variable_get('forum_nav_vocabulary', ''); + + $context['sandbox']['query'] = "FROM {term_data} LEFT JOIN {url_alias} ON CONCAT('forum/', CAST(tid AS CHAR)) = src WHERE vid = %d AND src IS NULL"; + $context['sandbox']['query_args'] = array($forum_vid); + } + + // Get the total amount of items to process. + if (!isset($context['sandbox']['total'])) { + $context['sandbox']['total'] = db_result(db_query("SELECT COUNT(tid) " . $context['sandbox']['query'], $context['sandbox']['query_args'])); + $context['sandbox']['count'] = 0; + $context['sandbox']['items'] = array(); + } + + // Get the next stack of items to process. + if (empty($context['sandbox']['items'])) { + $query = "SELECT tid " . $context['sandbox']['query']; + $result = db_query_range($query, $context['sandbox']['query_args'], $context['sandbox']['count'], 1000); + while ($tid = db_result($result)) { + $context['sandbox']['items'][] = $tid; + } + } - $count = 0; - $placeholders = array(); - while ($category = db_fetch_object($result)) { - $count = _taxonomy_pathauto_alias($category, 'bulkupdate') + $count; + // Process the next item in the stack. + if ($tid = array_shift($context['sandbox']['items'])) { + $context['sandbox']['count']++; + + $category = taxonomy_get_term($tid); + if (_taxonomy_pathauto_alias($category, 'bulkupdate')) { + $context['message'] = t('Updated alias for forum %title', array('%title' => $category->name)); + // Update total counter. + $context['results']['count']++; + } } - drupal_set_message(format_plural($count, - 'Bulk update of forums and forum containers completed, one alias generated.', - 'Bulk update of forums and forum containers completed, @count aliases generated.')); + if ($context['sandbox']['total'] > 0) { + $context['finished'] = $context['sandbox']['count'] / $context['sandbox']['total']; + } } + Index: pathauto_user.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/pathauto/pathauto_user.inc,v retrieving revision 1.31 diff -u -p -r1.31 pathauto_user.inc --- pathauto_user.inc 11 Jul 2008 20:01:22 -0000 1.31 +++ pathauto_user.inc 3 Mar 2010 00:23:50 -0000 @@ -29,8 +29,7 @@ function user_pathauto($op) { } } - $settings['bulkname'] = t('Bulk generate aliases for users that are not aliased'); - $settings['bulkdescr'] = t('Generate aliases for all existing user account pages which do not already have aliases.'); + $settings['bulkname'] = t('Users'); return (object) $settings; default: break; @@ -54,8 +53,7 @@ function blog_pathauto($op) { $settings['placeholders']['['. $pattern .']'] = $description; } $settings['supportsfeeds'] = 'feed'; - $settings['bulkname'] = t('Bulk generate aliases for blogs that are not aliased'); - $settings['bulkdescr'] = t('Generate aliases for all existing blog pages which do not already have aliases.'); + $settings['bulkname'] = t('User blogs'); return (object) $settings; default: break; @@ -79,8 +77,7 @@ function tracker_pathauto($op) { $settings['placeholders']['['. $pattern .']'] = $description; } $settings['supportsfeeds'] = 'feed'; - $settings['bulkname'] = t('Bulk generate aliases for user-tracker paths that are not aliased'); - $settings['bulkdescr'] = t('Generate aliases for all existing user-tracker pages which do not already have aliases.'); + $settings['bulkname'] = t('User trackers'); return (object) $settings; default: break; @@ -103,8 +100,7 @@ function contact_pathauto($op) { foreach ($patterns['user'] as $pattern => $description) { $settings['placeholders']['['. $pattern .']'] = $description; } - $settings['bulkname'] = t('Bulk generate aliases for user contact form paths that are not aliased'); - $settings['bulkdescr'] = t('Generate aliases for all existing user contact form pages which do not already have aliases.'); + $settings['bulkname'] = t('User contact forms'); return (object) $settings; default: break; @@ -112,91 +108,160 @@ function contact_pathauto($op) { } /** - * Bulk generate aliases for all users without aliases. + * Batch processing callback; Generate aliases for users. */ -function user_pathauto_bulkupdate() { - $query = "SELECT uid, name, src, dst FROM {users} LEFT JOIN {url_alias} ON CONCAT('user/', CAST(uid AS CHAR)) = src WHERE uid > 0 AND src IS NULL"; - $result = db_query_range($query, 0, variable_get('pathauto_max_bulk_update', 50)); +function user_pathauto_batch_update(&$context) { + // Get the total amount of items to process. + if (!isset($context['sandbox']['total'])) { + $context['sandbox']['total'] = db_result(db_query("SELECT COUNT(uid) FROM {users} LEFT JOIN {url_alias} ON CONCAT('user/', CAST(uid AS CHAR)) = src WHERE uid > 0 AND src IS NULL")); + $context['sandbox']['count'] = 0; + $context['sandbox']['items'] = array(); + } + + // Get the next stack of items to process. + if (empty($context['sandbox']['items'])) { + $query = "SELECT uid FROM {users} LEFT JOIN {url_alias} ON CONCAT('user/', CAST(uid AS CHAR)) = src WHERE uid > 0 AND src IS NULL"; + $result = db_query_range($query, $context['sandbox']['count'], 1000); + while ($uid = db_result($result)) { + $context['sandbox']['items'][] = $uid; + } + } - $count = 0; - $placeholders = array(); - while ($user = db_fetch_object($result)) { - $placeholders = pathauto_get_placeholders('user', $user); - $src = 'user/'. $user->uid; - if (pathauto_create_alias('user', 'bulkupdate', $placeholders, $src, $user->uid)) { - $count++; + // Process the next item in the stack. + if ($uid = array_shift($context['sandbox']['items'])) { + $context['sandbox']['count']++; + + $account = user_load(array('uid' => $uid)); + $placeholders = pathauto_get_placeholders('user', $account); + $src = 'user/' . $account->uid; + if (pathauto_create_alias('user', 'bulkupdate', $placeholders, $src, $account->uid)) { + $context['message'] = t('Updated alias for user %name', array('%name' => $account->name)); + // Update total counter. + $context['results']['count']++; } } - drupal_set_message(format_plural($count, - 'Bulk generation of users completed, one alias generated.', - 'Bulk generation of users completed, @count aliases generated.')); + if ($context['sandbox']['total'] > 0) { + $context['finished'] = $context['sandbox']['count'] / $context['sandbox']['total']; + } } /** - * Bulk generate aliases for all blogs without aliases. + * Batch processing callback; Generate aliases for user blogs. */ -function blog_pathauto_bulkupdate() { - $query = "SELECT uid, name, src, dst FROM {users} LEFT JOIN {url_alias} ON CONCAT('blog/', CAST(uid AS CHAR)) = src WHERE uid > 0 AND src IS NULL"; - $result = db_query_range($query, 0, variable_get('pathauto_max_bulk_update', 50)); +function blog_pathauto_batch_update(&$context) { + // Get the total amount of items to process. + if (!isset($context['sandbox']['total'])) { + $context['sandbox']['total'] = db_result(db_query("SELECT COUNT(uid) FROM {users} LEFT JOIN {url_alias} ON CONCAT('blog/', CAST(uid AS CHAR)) = src WHERE uid > 0 AND src IS NULL")); + $context['sandbox']['count'] = 0; + $context['sandbox']['items'] = array(); + } + + // Get the next stack of items to process. + if (empty($context['sandbox']['items'])) { + $query = "SELECT uid FROM {users} LEFT JOIN {url_alias} ON CONCAT('blog/', CAST(uid AS CHAR)) = src WHERE uid > 0 AND src IS NULL"; + $result = db_query_range($query, $context['sandbox']['count'], 1000); + while ($uid = db_result($result)) { + $context['sandbox']['items'][] = $uid; + } + } - $count = 0; - $placeholders = array(); - while ($user = db_fetch_object($result)) { - $placeholders = pathauto_get_placeholders('user', $user); - $src = 'blog/'. $user->uid; - if (pathauto_create_alias('blog', 'bulkupdate', $placeholders, $src, $user->uid)) { - $count++; + // Process the next item in the stack. + if ($uid = array_shift($context['sandbox']['items'])) { + $context['sandbox']['count']++; + + $account = user_load(array('uid' => $uid)); + $placeholders = pathauto_get_placeholders('user', $account); + $src = 'blog/'. $account->uid; + if (pathauto_create_alias('blog', 'bulkupdate', $placeholders, $src, $account->uid)) { + $context['message'] = t('Updated alias for blog of user %name', array('%name' => $account->name)); + // Update total counter. + $context['results']['count']++; } } - drupal_set_message(format_plural($count, - 'Bulk generation of user blogs completed, one alias generated.', - 'Bulk generation of user blogs completed, @count aliases generated.')); + if ($context['sandbox']['total'] > 0) { + $context['finished'] = $context['sandbox']['count'] / $context['sandbox']['total']; + } } /** - * Bulk generate aliases for user trackers without aliases. + * Batch processing callback; Generate aliases for user tracker pages. */ -function tracker_pathauto_bulkupdate() { - // We do the double CONCAT because Pgsql8.1 doesn't support more than three arguments to CONCAT - // Hopefully some day we can remove that. - $query = "SELECT uid, name, src, dst FROM {users} LEFT JOIN {url_alias} ON CONCAT(CONCAT('user/', CAST(uid AS CHAR)), '/track') = src WHERE uid > 0 AND src IS NULL"; - $result = db_query_range($query, 0, variable_get('pathauto_max_bulk_update', 50)); +function tracker_pathauto_batch_update(&$context) { + // Get the total amount of items to process. + if (!isset($context['sandbox']['total'])) { + $context['sandbox']['total'] = db_result(db_query("SELECT COUNT(uid) FROM {users} LEFT JOIN {url_alias} ON CONCAT(CONCAT('user/', CAST(uid AS CHAR)), '/track') = src WHERE uid > 0 AND src IS NULL")); + $context['sandbox']['count'] = 0; + $context['sandbox']['items'] = array(); + } - $count = 0; - $placeholders = array(); - while ($user = db_fetch_object($result)) { - $placeholders = pathauto_get_placeholders('user', $user); - $src = 'user/'. $user->uid .'/track'; - if (pathauto_create_alias('tracker', 'bulkupdate', $placeholders, $src, $user->uid)) { - $count++; + // Get the next stack of items to process. + if (empty($context['sandbox']['items'])) { + // We do the double CONCAT because Pgsql8.1 doesn't support more than three + // arguments to CONCAT. + $query = "SELECT uid FROM {users} LEFT JOIN {url_alias} ON CONCAT(CONCAT('user/', CAST(uid AS CHAR)), '/track') = src WHERE uid > 0 AND src IS NULL"; + $result = db_query_range($query, $context['sandbox']['count'], 1000); + while ($uid = db_result($result)) { + $context['sandbox']['items'][] = $uid; } } - drupal_set_message(format_plural($count, - 'Bulk generation of user tracker pages completed, one alias generated.', - 'Bulk generation of user tracker pages completed, @count aliases generated.')); + // Process the next item in the stack. + if ($uid = array_shift($context['sandbox']['items'])) { + $context['sandbox']['count']++; + + $account = user_load(array('uid' => $uid)); + $placeholders = pathauto_get_placeholders('user', $account); + $src = 'user/' . $account->uid . '/track'; + if (pathauto_create_alias('tracker', 'bulkupdate', $placeholders, $src, $account->uid)) { + $context['message'] = t('Updated alias for tracker of user %name', array('%name' => $account->name)); + // Update total counter. + $context['results']['count']++; + } + } + + if ($context['sandbox']['total'] > 0) { + $context['finished'] = $context['sandbox']['count'] / $context['sandbox']['total']; + } } /** - * Bulk generate aliases for all users without aliases + * Batch processing callback; Generate aliases for user contact forms. */ -function contact_pathauto_bulkupdate() { - $query = "SELECT uid, name, src, dst FROM {users} LEFT JOIN {url_alias} ON CONCAT(CONCAT('user/', CAST(uid AS CHAR)), '/contact') = src WHERE uid > 0 AND src IS NULL"; - $result = db_query_range($query, 0, variable_get('pathauto_max_bulk_update', 50)); +function contact_pathauto_batch_update(&$context) { + // Get the total amount of items to process. + if (!isset($context['sandbox']['total'])) { + $context['sandbox']['total'] = db_result(db_query("SELECT COUNT(uid) FROM {users} LEFT JOIN {url_alias} ON CONCAT(CONCAT('user/', CAST(uid AS CHAR)), '/contact') = src WHERE uid > 0 AND src IS NULL")); + $context['sandbox']['count'] = 0; + $context['sandbox']['items'] = array(); + } - $count = 0; - $placeholders = array(); - while ($user = db_fetch_object($result)) { - $placeholders = pathauto_get_placeholders('user', $user); - $src = 'user/'. $user->uid .'/contact'; - if (pathauto_create_alias('contact', 'bulkupdate', $placeholders, $src, $user->uid)) { - $count++; + // Get the next stack of items to process. + if (empty($context['sandbox']['items'])) { + $query = "SELECT uid FROM {users} LEFT JOIN {url_alias} ON CONCAT(CONCAT('user/', CAST(uid AS CHAR)), '/contact') = src WHERE uid > 0 AND src IS NULL"; + $result = db_query_range($query, $context['sandbox']['count'], 1000); + while ($uid = db_result($result)) { + $context['sandbox']['items'][] = $uid; } } - drupal_set_message(format_plural($count, - 'Bulk generation of contact pages completed, one alias generated.', - 'Bulk generation of contact pages completed, @count aliases generated.')); + // Process the next item in the stack. + if ($uid = array_shift($context['sandbox']['items'])) { + $context['sandbox']['count']++; + + $account = user_load(array('uid' => $uid)); + $placeholders = pathauto_get_placeholders('user', $account); + $src = 'user/' . $account->uid . '/contact'; + if (pathauto_create_alias('contact', 'bulkupdate', $placeholders, $src, $account->uid)) { + $context['message'] = t('Updated alias for contact form of user %name', array('%name' => $account->name)); + // Update total counter. + $context['results']['count']++; + } + } + + if ($context['sandbox']['total'] > 0) { + $context['finished'] = $context['sandbox']['count'] / $context['sandbox']['total']; + } } +