Bug in copying users with New Blog Templates

There is a bug in copying users across from a template site to a new site. I have a client who has just created approximately 100 sites and has, for example, only one user assigned to site number 80, but the users page lists 4096 See screenshot here http://dl.dropbox.com/u/5950198/new-blog-templates-user-count.png

The problem seems to be in this code here on line 275 of file blogtemplatesfiles/blog_templates.php

$users = $wpdb->get_results("SELECT * FROM $wpdb->usermeta WHERE meta_key LIKE '" . mysql_escape_string($template_prefix) . "%'");

So if, for example your template site has id 8, then it will retrieve the usermeta rows which begin ‘wp_8_’ and copy them to the new site (id 9) replacing wp_8_ with wp_9_ in lines 293 – 296

$user->meta_key = str_replace($template_prefix, $new_prefix,$user->meta_key);
unset($user->umeta_id); //Remove the umeta_id field, let it autoincrement
//Insert the user
$wpdb->insert($wpdb->usermeta,(array) $user);

The problems start after you have created site id 80.

I want to create site 81. Now when I come to run line 276 again, it is going to retrieve all the rows for wp_8 *and* all the rows for wp_80 because the trailing underscore in the prefix is a SQL wildcard.

It will insert twice as many rows as it should, the first lot with wp_8_ replaced with wp_81_, and the second lot unchanged (because the replacement code did not match wp_80_ ). So now we have duplicate entries for each user in site 80.

When we do site 82, it will retrieve all the 8, 80, and 81 rows. Then it will create all the 82 rows, and duplicate the 80, and 81 rows again.

You can see where this is going… The screen shot shows a count of 4096 users for a site with 1 user.

The fix is to escape the underscores in line 275, (I’ve also used wpdb->prepare())

it should become:

$users = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->usermeta WHERE meta_key LIKE %s" , str_replace( '_', '\_', $template_prefix . "%%" ) ) );

Now I’ve got some cleaning up to do (>20,000 extra rows in usermeta)