Merge pull request #660 from fabrixxm/moveme

uimport: check table columns before import
This commit is contained in:
friendica 2013-04-03 17:36:40 -07:00
commit 1e54f0022f

View file

@ -1,4 +1,5 @@
<?php <?php
/** /**
* import account file exported from mod/uexport * import account file exported from mod/uexport
* args: * args:
@ -8,242 +9,264 @@
require_once("include/Photo.php"); require_once("include/Photo.php");
define("IMPORT_DEBUG", False); define("IMPORT_DEBUG", False);
function last_insert_id(){ function last_insert_id() {
global $db; global $db;
if (IMPORT_DEBUG) return 1; if (IMPORT_DEBUG)
if($db->mysqli){ return 1;
$thedb = $db->getdb(); if ($db->mysqli) {
return $thedb->insert_id; $thedb = $db->getdb();
} else { return $thedb->insert_id;
return mysql_insert_id(); } else {
} return mysql_insert_id();
} }
}
function last_error(){ function last_error() {
global $db; global $db;
return $db->error; return $db->error;
} }
function db_import_assoc($table, $arr){ /**
if (IMPORT_DEBUG) return true; * Remove columns from array $arr that aren't in table $table
if (isset($arr['id'])) unset($arr['id']); *
$cols = implode("`,`", array_map('dbesc', array_keys($arr))); * @param string $table Table name
$vals = implode("','", array_map('dbesc', array_values($arr))); * @param array &$arr Column=>Value array from json (by ref)
$query = "INSERT INTO `$table` (`$cols`) VALUES ('$vals')"; */
logger("uimport: $query",LOGGER_TRACE); function check_cols($table, &$arr) {
return q($query); $query = sprintf("SHOW COLUMNS IN `%s`", dbesc($table));
} logger("uimport: $query", LOGGER_DEBUG);
$r = q($query);
$tcols = array();
// get a plain array of column names
foreach ($r as $tcol) {
$tcols[] = $tcol['Field'];
}
// remove inexistent columns
foreach ($arr as $icol => $ival) {
if (!in_array($icol, $tcols)) {
unset($arr[$icol]);
}
}
}
/**
* Import data into table $table
*
* @param string $table Table name
* @param array $arr Column=>Value array from json
*/
function db_import_assoc($table, $arr) {
if (isset($arr['id']))
unset($arr['id']);
check_cols($table, $arr);
$cols = implode("`,`", array_map('dbesc', array_keys($arr)));
$vals = implode("','", array_map('dbesc', array_values($arr)));
$query = "INSERT INTO `$table` (`$cols`) VALUES ('$vals')";
logger("uimport: $query", LOGGER_TRACE);
if (IMPORT_DEBUG)
return true;
return q($query);
}
function import_cleanup($newuid) { function import_cleanup($newuid) {
q("DELETE FROM `user` WHERE uid = %d", $newuid); q("DELETE FROM `user` WHERE uid = %d", $newuid);
q("DELETE FROM `contact` WHERE uid = %d", $newuid); q("DELETE FROM `contact` WHERE uid = %d", $newuid);
q("DELETE FROM `profile` WHERE uid = %d", $newuid); q("DELETE FROM `profile` WHERE uid = %d", $newuid);
q("DELETE FROM `photo` WHERE uid = %d", $newuid); q("DELETE FROM `photo` WHERE uid = %d", $newuid);
q("DELETE FROM `group` WHERE uid = %d", $newuid); q("DELETE FROM `group` WHERE uid = %d", $newuid);
q("DELETE FROM `group_member` WHERE uid = %d", $newuid); q("DELETE FROM `group_member` WHERE uid = %d", $newuid);
q("DELETE FROM `pconfig` WHERE uid = %d", $newuid); q("DELETE FROM `pconfig` WHERE uid = %d", $newuid);
} }
function import_account(&$a, $file) { function import_account(&$a, $file) {
logger("Start user import from ".$file['tmp_name']); logger("Start user import from " . $file['tmp_name']);
/* /*
STEPS STEPS
1. checks 1. checks
2. replace old baseurl with new baseurl 2. replace old baseurl with new baseurl
3. import data (look at user id and contacts id) 3. import data (look at user id and contacts id)
4. archive non-dfrn contacts 4. archive non-dfrn contacts
5. send message to dfrn contacts 5. send message to dfrn contacts
*/ */
$account = json_decode(file_get_contents($file['tmp_name']), true); $account = json_decode(file_get_contents($file['tmp_name']), true);
if ($account===null) { if ($account === null) {
notice(t("Error decoding account file")); notice(t("Error decoding account file"));
return; return;
} }
if (!x($account, 'version')) { if (!x($account, 'version')) {
notice(t("Error! No version data in file! This is not a Friendica account file?")); notice(t("Error! No version data in file! This is not a Friendica account file?"));
return; return;
} }
if ($account['schema'] != DB_UPDATE_VERSION) { if ($account['schema'] != DB_UPDATE_VERSION) {
notice(t("Error! I can't import this file: DB schema version is not compatible.")); notice(t("Error! I can't import this file: DB schema version is not compatible."));
return; return;
} }
// check for username // check for username
$r = q("SELECT uid FROM user WHERE nickname='%s'", $account['user']['nickname']); $r = q("SELECT uid FROM user WHERE nickname='%s'", $account['user']['nickname']);
if ($r===false) { if ($r === false) {
logger("uimport:check nickname : ERROR : ".last_error(), LOGGER_NORMAL); logger("uimport:check nickname : ERROR : " . last_error(), LOGGER_NORMAL);
notice(t('Error! Cannot check nickname')); notice(t('Error! Cannot check nickname'));
return; return;
} }
if (count($r)>0) { if (count($r) > 0) {
notice(sprintf(t("User '%s' already exists on this server!"),$account['user']['nickname'])); notice(sprintf(t("User '%s' already exists on this server!"), $account['user']['nickname']));
return; return;
} }
$oldbaseurl = $account['baseurl']; $oldbaseurl = $account['baseurl'];
$newbaseurl = $a->get_baseurl(); $newbaseurl = $a->get_baseurl();
$olduid = $account['user']['uid']; $olduid = $account['user']['uid'];
unset($account['user']['uid']); unset($account['user']['uid']);
foreach($account['user'] as $k => &$v) { foreach ($account['user'] as $k => &$v) {
$v = str_replace($oldbaseurl, $newbaseurl, $v); $v = str_replace($oldbaseurl, $newbaseurl, $v);
} }
// import user // import user
$r = db_import_assoc('user', $account['user']); $r = db_import_assoc('user', $account['user']);
if ($r===false) { if ($r === false) {
//echo "<pre>"; var_dump($r, $query, mysql_error()); killme(); //echo "<pre>"; var_dump($r, $query, mysql_error()); killme();
logger("uimport:insert user : ERROR : ".last_error(), LOGGER_NORMAL); logger("uimport:insert user : ERROR : " . last_error(), LOGGER_NORMAL);
notice(t("User creation error")); notice(t("User creation error"));
return; return;
} }
$newuid = last_insert_id(); $newuid = last_insert_id();
//~ $newuid = 1; //~ $newuid = 1;
foreach($account['profile'] as &$profile) { foreach ($account['profile'] as &$profile) {
foreach($profile as $k=>&$v) { foreach ($profile as $k => &$v) {
$v = str_replace($oldbaseurl, $newbaseurl, $v); $v = str_replace($oldbaseurl, $newbaseurl, $v);
foreach(array("profile","avatar") as $k) foreach (array("profile", "avatar") as $k)
$v = str_replace($newbaseurl."/photo/".$k."/".$olduid.".jpg", $newbaseurl."/photo/".$k."/".$newuid.".jpg", $v); $v = str_replace($newbaseurl . "/photo/" . $k . "/" . $olduid . ".jpg", $newbaseurl . "/photo/" . $k . "/" . $newuid . ".jpg", $v);
} }
$profile['uid'] = $newuid; $profile['uid'] = $newuid;
$r = db_import_assoc('profile', $profile); $r = db_import_assoc('profile', $profile);
if ($r===false) { if ($r === false) {
logger("uimport:insert profile ".$profile['profile-name']." : ERROR : ".last_error(), LOGGER_NORMAL); logger("uimport:insert profile " . $profile['profile-name'] . " : ERROR : " . last_error(), LOGGER_NORMAL);
info(t("User profile creation error")); info(t("User profile creation error"));
import_cleanup($newuid); import_cleanup($newuid);
return; return;
} }
} }
$errorcount=0; $errorcount = 0;
foreach($account['contact'] as &$contact) { foreach ($account['contact'] as &$contact) {
if ($contact['uid'] == $olduid && $contact['self'] == '1'){ if ($contact['uid'] == $olduid && $contact['self'] == '1') {
foreach($contact as $k=>&$v) { foreach ($contact as $k => &$v) {
$v = str_replace($oldbaseurl, $newbaseurl, $v); $v = str_replace($oldbaseurl, $newbaseurl, $v);
foreach(array("profile","avatar","micro") as $k) foreach (array("profile", "avatar", "micro") as $k)
$v = str_replace($newbaseurl."/photo/".$k."/".$olduid.".jpg", $newbaseurl."/photo/".$k."/".$newuid.".jpg", $v); $v = str_replace($newbaseurl . "/photo/" . $k . "/" . $olduid . ".jpg", $newbaseurl . "/photo/" . $k . "/" . $newuid . ".jpg", $v);
} }
} }
if ($contact['uid'] == $olduid && $contact['self'] == '0') { if ($contact['uid'] == $olduid && $contact['self'] == '0') {
switch ($contact['network']){ switch ($contact['network']) {
case NETWORK_DFRN: case NETWORK_DFRN:
// send relocate message (below) // send relocate message (below)
break; break;
case NETWORK_ZOT: case NETWORK_ZOT:
// TODO handle zot network // TODO handle zot network
break; break;
case NETWORK_MAIL2: case NETWORK_MAIL2:
// TODO ? // TODO ?
break; break;
case NETWORK_FEED: case NETWORK_FEED:
case NETWORK_MAIL: case NETWORK_MAIL:
// Nothing to do // Nothing to do
break; break;
default: default:
// archive other contacts // archive other contacts
$contact['archive'] = "1"; $contact['archive'] = "1";
} }
} }
$contact['uid'] = $newuid; $contact['uid'] = $newuid;
$r = db_import_assoc('contact', $contact); $r = db_import_assoc('contact', $contact);
if ($r===false) { if ($r === false) {
logger("uimport:insert contact ".$contact['nick'].",".$contact['network']." : ERROR : ".last_error(), LOGGER_NORMAL); logger("uimport:insert contact " . $contact['nick'] . "," . $contact['network'] . " : ERROR : " . last_error(), LOGGER_NORMAL);
$errorcount++; $errorcount++;
} else { } else {
$contact['newid'] = last_insert_id(); $contact['newid'] = last_insert_id();
} }
} }
if ($errorcount>0) { if ($errorcount > 0) {
notice( sprintf(tt("%d contact not imported", "%d contacts not imported", $errorcount), $errorcount) ); notice(sprintf(tt("%d contact not imported", "%d contacts not imported", $errorcount), $errorcount));
} }
foreach($account['group'] as &$group) { foreach ($account['group'] as &$group) {
$group['uid'] = $newuid; $group['uid'] = $newuid;
$r = db_import_assoc('group', $group); $r = db_import_assoc('group', $group);
if ($r===false) { if ($r === false) {
logger("uimport:insert group ".$group['name']." : ERROR : ".last_error(), LOGGER_NORMAL); logger("uimport:insert group " . $group['name'] . " : ERROR : " . last_error(), LOGGER_NORMAL);
} else { } else {
$group['newid'] = last_insert_id(); $group['newid'] = last_insert_id();
} }
} }
foreach($account['group_member'] as &$group_member) { foreach ($account['group_member'] as &$group_member) {
$group_member['uid'] = $newuid; $group_member['uid'] = $newuid;
$import = 0; $import = 0;
foreach($account['group'] as $group) { foreach ($account['group'] as $group) {
if ($group['id'] == $group_member['gid'] && isset($group['newid'])) { if ($group['id'] == $group_member['gid'] && isset($group['newid'])) {
$group_member['gid'] = $group['newid']; $group_member['gid'] = $group['newid'];
$import++; $import++;
break; break;
} }
} }
foreach($account['contact'] as $contact) { foreach ($account['contact'] as $contact) {
if ($contact['id'] == $group_member['contact-id'] && isset($contact['newid'])) { if ($contact['id'] == $group_member['contact-id'] && isset($contact['newid'])) {
$group_member['contact-id'] = $contact['newid']; $group_member['contact-id'] = $contact['newid'];
$import++; $import++;
break; break;
} }
} }
if ($import==2) { if ($import == 2) {
$r = db_import_assoc('group_member', $group_member); $r = db_import_assoc('group_member', $group_member);
if ($r===false) { if ($r === false) {
logger("uimport:insert group member ".$group_member['id']." : ERROR : ".last_error(), LOGGER_NORMAL); logger("uimport:insert group member " . $group_member['id'] . " : ERROR : " . last_error(), LOGGER_NORMAL);
} }
} }
} }
foreach($account['photo'] as &$photo) { foreach ($account['photo'] as &$photo) {
$photo['uid'] = $newuid; $photo['uid'] = $newuid;
$photo['data'] = hex2bin($photo['data']); $photo['data'] = hex2bin($photo['data']);
$p = new Photo($photo['data'], $photo['type']); $p = new Photo($photo['data'], $photo['type']);
$r = $p->store( $r = $p->store(
$photo['uid'], $photo['uid'], $photo['contact-id'], //0
$photo['contact-id'], //0 $photo['resource-id'], $photo['filename'], $photo['album'], $photo['scale'], $photo['profile'], //1
$photo['resource-id'], $photo['allow_cid'], $photo['allow_gid'], $photo['deny_cid'], $photo['deny_gid']
$photo['filename'], );
$photo['album'],
$photo['scale'],
$photo['profile'], //1
$photo['allow_cid'],
$photo['allow_gid'],
$photo['deny_cid'],
$photo['deny_gid']
);
if ($r===false) { if ($r === false) {
logger("uimport:insert photo ".$photo['resource-id'].",". $photo['scale']. " : ERROR : ".last_error(), LOGGER_NORMAL); logger("uimport:insert photo " . $photo['resource-id'] . "," . $photo['scale'] . " : ERROR : " . last_error(), LOGGER_NORMAL);
} }
} }
foreach($account['pconfig'] as &$pconfig) { foreach ($account['pconfig'] as &$pconfig) {
$pconfig['uid'] = $newuid; $pconfig['uid'] = $newuid;
$r = db_import_assoc('pconfig', $pconfig); $r = db_import_assoc('pconfig', $pconfig);
if ($r===false) { if ($r === false) {
logger("uimport:insert pconfig ".$pconfig['id']. " : ERROR : ".last_error(), LOGGER_NORMAL); logger("uimport:insert pconfig " . $pconfig['id'] . " : ERROR : " . last_error(), LOGGER_NORMAL);
} }
} }
// send relocate messages
proc_run('php', 'include/notifier.php', 'relocate' , $newuid);
info(t("Done. You can now login with your username and password"));
goaway( $a->get_baseurl() ."/login");
// send relocate messages
proc_run('php', 'include/notifier.php', 'relocate', $newuid);
info(t("Done. You can now login with your username and password"));
goaway($a->get_baseurl() . "/login");
} }