user_relationship_migrate.module in User Relationships 5
Same filename and directory in other branches
Drupal Module: User Relationship Migrate
@author: JB Christy <JBChristy [at] pacbell. [dot] net>
Migrate buddylist relationships to user relationships
File
plugins/user_relationship_migrate/user_relationship_migrate.moduleView source
<?php
/**
* Drupal Module: User Relationship Migrate
*
* @author: JB Christy <JBChristy [at] pacbell. [dot] net>
* @file
* Migrate buddylist relationships to user relationships
*/
/**
* hook_menu()
*/
function user_relationship_migrate_menu($may_cache) {
$items = array();
if ($may_cache) {
// configuration form (select relationship type)
$items[] = array(
'path' => 'admin/user/relationships/migrate',
'title' => t('Migrate buddylist'),
'callback' => 'drupal_get_form',
'callback arguments' => array(
'user_relationship_migrate_form',
),
'access' => user_access('administer user relationships'),
'type' => MENU_LOCAL_TASK,
'weight' => 4,
);
}
else {
// page to actually do the migration
$items[] = array(
'path' => 'admin/user/relationships/migrate/migrating',
'title' => t('Migrating buddylist'),
'callback' => 'user_relationship_migrate_migrate',
'access' => user_access('administer user relationships'),
'type' => MENU_CALLBACK,
);
}
return $items;
}
/**
* Migrate relationship form
*
* This function just provides the form elements. theme_user_relationship_migrate_form()
* provides (most of) the supporting text/descriptions.
*/
function user_relationship_migrate_form() {
$status = variable_get('user_relationship_migrate_status', '');
$form['status'] = array(
'#type' => 'value',
'#value' => $status,
);
switch ($status) {
case 'IN PROGRESS':
case 'COMPLETE':
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Reset'),
);
return $form;
}
$rtypes = user_relationships_relationship_types_load();
if (!sizeof($rtypes)) {
// must have at least one relationship type to migrate to
$form['status']['#value'] = 'NO TYPES';
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('OK'),
);
return $form;
}
$form['relationship_type_name'] = array(
'#type' => 'textfield',
'#title' => t('Relationship type for migrated relationships'),
'#maxlength' => 255,
'#description' => t('Start typing the name of a relationship type to use for buddylist relationships'),
'#default_value' => variable_get('user_relationship_migrate_rtype', ''),
'#required' => TRUE,
'#autocomplete_path' => 'relationship_types/autocomplete',
);
$count = db_result(db_query("SELECT COUNT(*) FROM {buddylist_pending_requests}"));
$form['migrate_pending'] = array(
'#type' => 'checkbox',
'#title' => t('Also migrate pending requests (@count pending requests)', array(
'@count' => $count,
)),
'#default_value' => variable_get('user_relationship_migrate_pending', 0),
);
$form['migrate_email'] = array(
'#type' => 'checkbox',
'#title' => t("Also migrate users' email settings"),
'#default_value' => variable_get('user_relationship_migrate_email', 0),
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Migrate'),
);
return $form;
}
/**
* function theme_user_relationship_migrate_form($form)
*
* Display some additional useful text, depending on the migration status
*/
function theme_user_relationship_migrate_form($form) {
$output = '<h2>' . t('Migrate Buddy List relationships to User Relationships') . '</h2>';
switch ($form['status']['#value']) {
case 'NO TYPES':
$output .= '<p>';
$output .= t('You must define at least one relationship type before you can migrate relationships.');
$output .= '</p>';
break;
case 'IN PROGRESS':
case 'COMPLETE':
$output .= '<p>';
$output .= t('It appears that the migration @status. If you would like to reset the status so that you can continue an aborted migration, click the Reset button. Otherwise, click !here to return the Relationships admin page.', array(
'@status' => $form['status']['#value'] == 'COMPLETE' ? 'has already completed successfully' : 'is already in progress',
'!here' => l('here', 'admin/user/relationships'),
));
$output .= '</p>';
break;
case 'PARTIALLY COMPLETE':
$checkpoint = array(
'migrated' => 0,
'last_uid' => -1,
'last_buddy' => -1,
'last_pending_uid' => -1,
'last_pending_buddy' => -1,
);
$checkpoint = variable_get('user_relationship_migrate_checkpoint', $checkpoint);
if ($checkpoint['migrated'] > 0) {
$output .= '<p>';
$output .= t('@count relationships have already been migrated. Click Migrate to migrate the remaining relationships.', array(
'@count' => $checkpoint['migrated'],
));
$output .= '</p>';
}
break;
}
$output .= drupal_render($form);
if ($form['submit']['#value'] == 'Migrate') {
$buddies = db_result(db_query('SELECT COUNT(*) FROM {buddylist}'));
$pendings = db_result(db_query('SELECT COUNT(*) FROM {buddylist_pending_requests}'));
if ($buddies + $pendings > 100000) {
$output .= '<br />';
$output .= t('WARNING: You have @buddies buddy list entries and @pendings pending requests. Migration may take a while! Do not click Migrate more than once.', array(
'@buddies' => $buddies,
'@pendings' => $pendings,
));
}
}
return $output;
}
/**
* Validate migrate relationship form submission.
*/
function user_relationship_migrate_form_validate($form_id, &$form_values) {
if (!empty($form_values['relationship_type_name'])) {
if (!user_relationships_relationship_type_load(array(
'name' => $form_values['relationship_type_name'],
))) {
form_set_error('relationship_type_name', t("You must enter the name of an existing relationship type."));
}
}
}
/**
* Process migrate relationship form submission.
*/
function user_relationship_migrate_form_submit($form_id, &$form_values) {
switch ($form_values['op']) {
case 'Migrate':
variable_set('user_relationship_migrate_rtype', $form_values['relationship_type_name']);
variable_set('user_relationship_migrate_pending', $form_values['migrate_pending']);
variable_set('user_relationship_migrate_email', $form_values['migrate_email']);
return "admin/user/relationships/migrate/migrating";
case 'Reset':
// status is IN PROGRESS or COMPLETE, and admin wants to reset it
$checkpoint = array(
// set default values prior to checking the variable
'migrated' => 0,
'last_uid' => -1,
'last_buddy' => -1,
'last_pending_uid' => -1,
'last_pending_buddy' => -1,
'last_email_uid' => -1,
);
$checkpoint = variable_get('user_relationship_migrate_checkpoint', $checkpoint);
variable_set('user_relationship_migrate_status', $checkpoint['migrated'] > 0 ? 'PARTIALLY COMPLETE' : '');
return 'admin/user/relationships/migrate';
default:
// no types defined, so can't migrate
return 'admin/user/relationships';
}
}
/**
* Actually migrate the data
*/
function user_relationship_migrate_migrate() {
$status = variable_get('user_relationship_migrate_status', 'N/A');
if ($status == 'IN PROGRESS') {
// protect against clicking 'Migrate' twice (the button stays up and active during the whole migration)
$output = t("Migration is already in progress. You don't want to run this twice!") . "<br />";
$output .= "<br />" . t("Return to ") . l(t('User Relationships'), 'admin/user/relationships');
return $output;
}
if ($status == 'COMPLETE') {
$output = t("Migration has already completed successfully. You don't want to run this twice!") . "<br />";
$output .= "<br />" . t("Return to ") . l(t('User Relationships'), 'admin/user/relationships');
return $output;
}
// find the appropriate relationship type id
$rtype_name = variable_get('user_relationship_migrate_rtype', '');
$rtype = user_relationships_relationship_type_load(array(
'name' => $rtype_name,
));
if (!$rtype) {
drupal_set_message(t('@type is not a valid relationship type name', array(
'@type' => $rtype_name,
)), 'error');
return 'admin/user/relationships/migrate';
}
$rtid = $rtype->rtid;
// start the migration
variable_set('user_relationship_migrate_status', 'IN PROGRESS');
$successes = 0;
$errors = 0;
$insert_query = "INSERT INTO {user_relationships} (rid, requester_id, requestee_id, rtid, approved, created_at) ";
$insert_query .= "VALUES (%d, %d, %d, %d, %d, '%s')";
// if there's alot of data to migrate, this process may have failed partway through;
// if so, pick up where we left off
$checkpoint = array(
'migrated' => 0,
'last_uid' => -1,
'last_buddy' => -1,
'last_pending_uid' => -1,
'last_pending_buddy' => -1,
'last_email_uid' => -1,
);
$checkpoint = variable_get('user_relationship_migrate_checkpoint', $checkpoint);
$buddy_query = "SELECT * FROM {buddylist} WHERE (uid = %d AND buddy > %d) OR uid > %d ORDER BY uid, buddy";
$buddy_args = array(
$checkpoint['last_uid'],
$checkpoint['last_buddy'],
$checkpoint['last_uid'],
);
// migrate the approved relationships
$buddies = db_query($buddy_query, $buddy_args);
while ($buddy = db_fetch_object($buddies)) {
// 2 rows in the buddylist table map to 1 row in the user_relationships table,
// so only enter the relationship when uid < buddy
if ($buddy->uid < $buddy->buddy) {
$rid = db_next_id('{user_relationships}_id');
$timestamp = date('Y-m-d H:i:s', $buddy->timestamp);
$insert_args = array(
$rid,
$buddy->uid,
$buddy->buddy,
$rtid,
1,
$timestamp,
);
// start a transaction so that the insert and the variable_set either both happen or neither happen
db_query("START TRANSACTION");
if (db_query($insert_query, $insert_args)) {
$checkpoint['migrated'] += 2;
// 2 rows in the buddylist table have been accounted for
$checkpoint['last_uid'] = (int) $buddy->uid;
$checkpoint['last_buddy'] = (int) $buddy->buddy;
variable_set('user_relationship_migrate_checkpoint', $checkpoint);
$successes++;
}
else {
$output .= t("ERROR: Unable to insert rid @rid between @uid and @buddy", array(
'@rid' => $rid,
'@uid' => $buddy->uid,
'@buddy' => $buddy->buddy,
)) . "<br />";
$errors++;
}
db_query("COMMIT");
// end the transaction
if ($errors > 100) {
drupal_set_message(t("More than 100 errors inserting relationships - aborting migration."), 'error');
break;
}
}
}
// migrate the pending relationships, if admin requested it
if ($errors <= 100 && variable_get('user_relationship_migrate_pending', 0)) {
$timestamp = date('Y-m-d H:i:s');
// if there's alot of data to migrate, this process may have failed partway through;
// if so, pick up where we left off
$pending_query = "SELECT * FROM {buddylist_pending_requests} ";
$pending_query .= "WHERE (requester_uid = %d AND requestee_uid > %d) OR requester_uid > %d ";
$pending_query .= "ORDER BY requester_uid, requestee_uid";
$pending_args = array(
$checkpoint['last_pending_uid'],
$checkpoint['last_pending_buddy'],
$checkpoint['last_pending_uid'],
);
$pendings = db_query($pending_query, $pending_args);
while ($pending = db_fetch_object($pendings)) {
$rid = db_next_id('{user_relationships}_id');
$insert_args = array(
$rid,
$pending->requester_uid,
$pending->requestee_uid,
$rtid,
0,
$timestamp,
);
// start a transaction so that the insert and the variable set either both happen or neither happen
db_query("START TRANSACTION");
if (db_query($insert_query, $insert_args)) {
$checkpoint['migrated']++;
$checkpoint['last_pending_uid'] = (int) $pending->requester_uid;
$checkpoint['last_pending_buddy'] = (int) $pending->requestee_uid;
variable_set('user_relationship_migrate_checkpoint', $checkpoint);
$successes++;
}
else {
$output .= t("ERROR: Unable to insert rid @rid between @uid and @buddy", array(
'@rid' => $rid,
'@uid' => $pending->requester_uid,
'@buddy' => $pending->requester_uid,
)) . "<br />";
$errors++;
}
db_query("COMMIT");
// end the transaction
if ($errors > 100) {
drupal_set_message(t("More than 100 errors inserting relationships - aborting migration."), 'error');
break;
}
}
}
// migrate the email settings, if admin requested it
if ($errors <= 100 && variable_get('user_relationship_migrate_email', 0)) {
$users = db_query("SELECT uid, data FROM {users} WHERE uid > %d", $checkpoint['last_email_uid']);
while ($user_object = db_fetch_object($users)) {
$user_data = unserialize($user_object->data);
if (isset($user_data['buddylist_mail'])) {
$user_data['user_relationship_mailer_send_mail'] = $user_data['buddylist_mail'];
unset($user_data['buddylist_mail']);
$user_data = serialize($user_data);
// start a transaction so that the update and the variable set either both happen or neither happen
db_query("START TRANSACTION");
if (db_query("UPDATE {users} SET data = '%s' WHERE uid = %d", $user_data, $user_object->uid)) {
$checkpoint['last_email_uid'] = (int) $user_object->uid;
variable_set('user_relationship_migrate_checkpoint', $checkpoint);
$updated_users++;
}
else {
$output .= t("ERROR: Unable to update email settings for user @uid", array(
'@uid' => $user_object->uid,
)) . "<br />";
$errors++;
}
db_query("COMMIT");
// end the transaction
}
}
}
// Tidy up
$output .= "<p>";
$output .= t('Successfully migrated @count buddies to relationship type @type.', array(
'@count' => $checkpoint['migrated'],
'@type' => $rtype_name,
));
if ($updated_users > 0) {
$output .= t(" @count users' email settings were updated.", array(
'@count' => $updated_users,
));
}
$output .= "</p>";
if (!$errors) {
variable_set('user_relationship_migrate_status', 'COMPLETE');
module_disable(array(
'user_relationship_migrate',
));
$output .= "<p>";
$output .= t("Buddy List data has been successfully migrated. The User Relationship Migrate plug in has been disabled. Don't forget to disable the Buddy List module.");
$output .= "</p>";
}
else {
variable_set('user_relationship_migrate_status', 'PARTIALLY COMPLETE');
$output .= "<p>";
$output .= t("Unable to migrate {$errors} buddies.");
$output .= "</p>";
}
$output .= "<p>";
$output .= t("Return to ") . l(t('User Relationships'), 'admin/user/relationships');
$output .= "</p>";
return $output;
}
Functions
Name | Description |
---|---|
theme_user_relationship_migrate_form | function theme_user_relationship_migrate_form($form) |
user_relationship_migrate_form | Migrate relationship form |
user_relationship_migrate_form_submit | Process migrate relationship form submission. |
user_relationship_migrate_form_validate | Validate migrate relationship form submission. |
user_relationship_migrate_menu | hook_menu() |
user_relationship_migrate_migrate | Actually migrate the data |