4

I want to change all the nodes where $user1 is author and set $user2 as author. I use this PHP Code and it works, but is it the correct way to do it? Or should I use a batch process and load each node to change the author?

   $num_updated = db_update('node')
      ->fields(array(
        'uid' => $user2->uid,
      ))
      ->condition('uid', $user1->uid, '=')
      ->execute();
1
  • I think what you've done is acceptable. Oct 2, 2013 at 16:20

5 Answers 5

2

It sounds like your Administering a Drupal site (not just a content moderator) -- but a site administration / developer.

Your code is fine. I recommend using Drush and calling your code as $ drush php-script massively-change-node-author.php from the command line. This way there is no timeout issues and you don't need to worry about using the Batch API and stuff like that.

Running code from php-script and drush performs a FULL BOOTSTRAP of drupal by default, and if needed you can pass a user argument to run the script as (faking a logged in user of $user) by using --user=1 for instance. For example: $ drush php-script --user=1 massively-change-node-author.php.

EDIT:

To avoid out-of-sync errors between node and node_revision table it's recommend to use node_load() and node_save() on the Nodes you want to update. Eg,

global $user;
foreach ($node_ids as $nid) {
  $node = node_load($nid);
  $node->uid = $user->uid;
  node_save($node);
}

Getting the list of node ids you want to affect, I leave as a task for you. The issues such as timeouts, using batch api etc -- are all still gone when using Drush. The logic is very similiar just using the better drupal API rather than direct database updates.

5
  • +1. Running the query is just fine. Doing a batch script to load nodes, change user and re-save nodes may be the more 'Drupal-correct' way, but IMO it's silly and massive overkill. Oct 2, 2013 at 16:26
  • @YuriyBabenko Not using the API means hooks won't fire. This may or may not cause problems. It will probably cause problems if the site uses node access permissions, but rebuilding the permissions should fix it. It may cause problems with revisioning and workflow.
    – mpdonadio
    Oct 2, 2013 at 16:52
  • It's also worth noting that the {node} and {node_revision} tables will get out of sync with this code.
    – mpdonadio
    Oct 2, 2013 at 16:52
  • @MPD - Yes, not firing the hooks is an obvious downside, but in my experience it's rarely an issue for such mass changes. Updating the node_revision table is obviously a good idea - assumed this was already being done... Oct 2, 2013 at 17:46
  • Thanks for your answers! In fact, I'm developing a module that shows a message when you block a user saying : "this user has X nodes. do you want to assign these nodes to a new author ?" because in some node with comments,the node author is in charge to validate the comments. That's why I was asking, tenken solution is better than mine, but I will do some test to see if I need to use batch API or not.
    – Franperr
    Oct 3, 2013 at 10:53
1

Well, at the end, because in my organization there is an important turn over and everybody has to manage its own nodes, I decided to create a module and to do things properly. I used the node_load/node_save functions to do it.

I put the module in my sandbox if you need it: https://drupal.org/sandbox/franperr/2109987 Feel free to send me a message for bugs/help/new features...

1

You can use Bulk Author Update module or also you can use views bulk operations module

The First solution is

  1. Install the views, views_bulk_operations, and admin_views modules.
  2. Go to the content listing (admin/content).
  3. Filter the results to get the nodes you are interested in.
  4. Check the checkboxes next to the node (there is also an option to select all).
  5. Select "Change author" from the operations dropdown and click the "Execute" button.
  6. Select the user you want to change the author to and click the "Next" button.

Admin views uses views bulk operations to override the default drupal administration views with something a lot more useful.

0

May you can schedule the update task on cron run when site expects the least tracffic.In order to schedule the udpate process at specific time you can use elysia cron module. This way you will be able to update in bulk keeping revisions update as well and also the script will run as standalone.

Step 1 : Schedule the updat task(assuming you are using elysia module).

function mymodule_cron_cronapi($op, $job = NULL) {

    $items['update_node_user_author'] = array(
    'description' => 'Update node user author',
    'rule' => '0 12 * * *', 
    'callback' => 'mymodule_update_node_author',
  );
 return $items;
}

 //cron call back
function mymodule_update_node_author() {
  // add logic to get $uid and $uid2
  // $uid is the user id you want to change for.
  // $uid2 is the user id you want to change with.
  exec("/usr/bin/php update_author.php $uid $uid2> /dev/null 2>&1 &");  
}

Now create a php script named as update_author.php in your drupal root add the following code inside it.

<?php

if (!isset($_SERVER['REMOTE_ADDR'])) {
  $_SERVER['REMOTE_ADDR'] = '127.0.0.1';
}
$uid = $argv[1];
$uid2 = $argv[2];

define('DRUPAL_ROOT', getcwd());
require_once DRUPAL_ROOT . '/includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);

  $query = new EntityFieldQuery();
  $query->entityCondition('entity_type', 'node');
  $query->propertyCondition('uid',$uid);
  $result = $query->execute();

  if (isset($result['node'])) {
    $nids = array_keys($result['node']);
    $nodes = node_load('node', $nids);
  }
  foreach($nodes as $node) {
    $node = node_load($nid);
    $node->uid = $uid2;
    node_save($node);
  }
1
  • Thanks arpitr, but as I said above, it is used just when a user is blocked, so using cron will not be very useful here.
    – Franperr
    Oct 3, 2013 at 10:57
0

I think the most comfortable and clean solution is to prepare view based on views_bulk_operations module (remember to install it).

Here is my exported view (you can import it on admin/structure/views/import).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.