]> git.mxchange.org Git - friendica.git/commitdiff
move account. first step.
authorFabrixxm <fabrix.xm@gmail.com>
Wed, 17 Oct 2012 15:13:01 +0000 (11:13 -0400)
committerFabrixxm <fabrix.xm@gmail.com>
Wed, 17 Oct 2012 15:13:01 +0000 (11:13 -0400)
export basic account data as json
import basic account data in db (dbs must be at same schema version)

include/dba.php
include/uimport.php [new file with mode: 0644]
mod/register.php
mod/uexport.php
mod/uimport.php [new file with mode: 0644]
view/register.tpl
view/uexport.tpl [new file with mode: 0644]
view/uimport.tpl [new file with mode: 0644]

index 8d224b570f44299c431f087392cc5e735787ef27..63b75c49483857e421cee382ea5a1b5bdb2a92f2 100644 (file)
@@ -233,7 +233,7 @@ function q($sql) {
        if($db && $db->connected) {
                $stmt = vsprintf($sql,$args);
                if($stmt === false)
-                       logger('dba: vsprintf error: ' . print_r(debug_backtrace(),true));
+                       logger('dba: vsprintf error: ' . print_r(debug_backtrace(),true), LOGGER_DEBUG);
                return $db->q($stmt);
        }
 
diff --git a/include/uimport.php b/include/uimport.php
new file mode 100644 (file)
index 0000000..0de6652
--- /dev/null
@@ -0,0 +1,235 @@
+<?php\r
+/**\r
+ * import account file exported from mod/uexport\r
+ * args:\r
+ *  $a       App     Friendica App Class\r
+ *  $file   Array   array from $_FILES\r
+ */\r
+require_once("include/Photo.php");\r
+define("IMPORT_DEBUG", False);\r
+\r
+function last_insert_id(){\r
+    global $db; \r
+    if (IMPORT_DEBUG) return 1;\r
+    if($db->mysqli){\r
+        $thedb = $db->getdb();\r
+        return $thedb->insert_id;\r
+    } else {\r
+        return mysql_insert_id();\r
+    }\r
+ }\r
\r
+ function last_error(){\r
+    global $db; \r
+    return $db->error;\r
+ }\r
\r
+ function db_import_assoc($table, $arr){\r
+    if (IMPORT_DEBUG) return true;\r
+    if (isset($arr['id'])) unset($arr['id']);\r
+    $cols = implode("`,`", array_map('dbesc', array_keys($arr)));\r
+    $vals = implode("','", array_map('dbesc', array_values($arr)));\r
+    $query = "INSERT INTO `$table` (`$cols`) VALUES ('$vals')";\r
+    logger("uimport: $query",LOGGER_TRACE);\r
+    return q($query);\r
+ }\r
+\r
+function import_cleanup($newuid) {\r
+    q("DELETE FROM `user` WHERE uid = %d", $newuid);\r
+    q("DELETE FROM `contact` WHERE uid = %d", $newuid);\r
+    q("DELETE FROM `profile` WHERE uid = %d", $newuid);\r
+    q("DELETE FROM `photo` WHERE uid = %d", $newuid);\r
+    q("DELETE FROM `group` WHERE uid = %d", $newuid);\r
+    q("DELETE FROM `group_member` WHERE uid = %d", $newuid);\r
+    q("DELETE FROM `pconfig` WHERE uid = %d", $newuid);\r
+\r
+}\r
+\r
+function import_account(&$a, $file) {\r
+    logger("Start user import from ".$file['tmp_name']);\r
+    /*\r
+        STEPS\r
+        1. checks\r
+        2. replace old baseurl with new baseurl\r
+        3. import data (look at user id and contacts id)\r
+        4. archive non-dfrn contacts\r
+        5. send message to dfrn contacts\r
+     */\r
+\r
+    $account = json_decode(file_get_contents($file['tmp_name']), true);\r
+    if ($account===null) {\r
+        notice(t("Error decoding account file"));\r
+        return;\r
+    }\r
+       \r
+\r
+    if (!x($account, 'version')) { \r
+        notice(t("Error! No version data in file! This is not a Friendica account file?"));\r
+        return;\r
+    }\r
+   \r
+    if ($account['schema'] != DB_UPDATE_VERSION) {\r
+        notice(t("Error! I can't import this file: DB schema version is not compatible."));\r
+        return;\r
+    }\r
+   \r
+\r
+    $oldbaseurl  = $account['baseurl'];\r
+    $newbaseurl = $a->get_baseurl();\r
+    $olduid = $account['user']['uid'];\r
+  \r
+    unset($account['user']['uid']);\r
+    foreach($account['user'] as $k => &$v) {\r
+        $v = str_replace($oldbaseurl, $newbaseurl, $v);\r
+    }\r
+\r
+    \r
+    // import user\r
+    $r = db_import_assoc('user', $account['user']);\r
+    if ($r===false) {\r
+        //echo "<pre>"; var_dump($r, $query, mysql_error()); killme();\r
+        logger("uimport:insert user : ERROR : ".last_error(), LOGGER_NORMAL);\r
+        notice(t("User creation error"));\r
+        return;\r
+    }\r
+    $newuid = last_insert_id();\r
+    //~ $newuid = 1;\r
+    \r
+\r
+\r
+    foreach($account['profile'] as &$profile) {\r
+        foreach($profile as $k=>&$v) {\r
+            $v = str_replace($oldbaseurl, $newbaseurl, $v);\r
+            foreach(array("profile","avatar") as $k)\r
+                $v = str_replace($newbaseurl."/photo/".$k."/".$olduid.".jpg", $newbaseurl."/photo/".$k."/".$newuid.".jpg", $v);\r
+        }\r
+        $profile['uid'] = $newuid;\r
+        $r = db_import_assoc('profile', $profile);\r
+        if ($r===false) {\r
+            logger("uimport:insert profile ".$profile['profile-name']." : ERROR : ".last_error(), LOGGER_NORMAL);\r
+            info(t("User profile creation error"));\r
+            import_cleanup($newuid);\r
+            return;\r
+        }\r
+    }\r
+\r
+    $errorcount=0;\r
+    foreach($account['contact'] as &$contact) {\r
+        if ($contact['uid'] == $olduid && $contact['self'] == '1'){\r
+            foreach($contact as $k=>&$v) {\r
+                $v = str_replace($oldbaseurl, $newbaseurl, $v);\r
+                foreach(array("profile","avatar","micro") as $k)\r
+                    $v = str_replace($newbaseurl."/photo/".$k."/".$olduid.".jpg", $newbaseurl."/photo/".$k."/".$newuid.".jpg", $v);\r
+            }\r
+        }\r
+         if ($contact['uid'] == $olduid && $contact['self'] == '0') {\r
+            switch ($contact['network']){\r
+                case NETWORK_DFRN:\r
+                    // send moved message\r
+                    break;\r
+                case NETWORK_ZOT:\r
+                    // TODO handle zot network\r
+                    break;\r
+                case NETWORK_MAIL2:\r
+                    // TODO ?\r
+                    break;\r
+                case NETWORK_FEED:\r
+                case NETWORK_MAIL:\r
+                    // Nothing to do\r
+                    break;\r
+                default:\r
+                    // archive other contacts\r
+                    $contact['archive'] = "1";\r
+            }\r
+        }\r
+        $contact['uid'] = $newuid;\r
+        $r = db_import_assoc('contact', $contact);\r
+        if ($r===false) {\r
+            logger("uimport:insert contact ".$contact['nick'].",".$contact['network']." : ERROR : ".last_error(), LOGGER_NORMAL);\r
+            $errorcount++;\r
+        } else {\r
+            $contact['newid'] = last_insert_id();\r
+        }\r
+    }\r
+    if ($errorcount>0) {\r
+        notice( sprintf(tt("%d contact not imported", "%d contacts not imported", $errorcount), $errorcount) );\r
+    }\r
+\r
+    foreach($account['group'] as &$group) {\r
+        $group['uid'] = $newuid;\r
+        $r = db_import_assoc('group', $group);\r
+        if ($r===false) {\r
+            logger("uimport:insert group ".$group['name']." : ERROR : ".last_error(), LOGGER_NORMAL);\r
+        } else {\r
+            $group['newid'] = last_insert_id();\r
+        }\r
+    }\r
+\r
+    foreach($account['group_member'] as &$group_member) {\r
+        $group_member['uid'] = $newuid;\r
+        \r
+        $import = 0;\r
+        foreach($account['group'] as $group) {\r
+            if ($group['id'] == $group_member['gid'] && isset($group['newid'])) {\r
+                $group_member['gid'] = $group['newid'];\r
+                $import++;\r
+                break;\r
+            }\r
+        }\r
+        foreach($account['contact'] as $contact) {\r
+            if ($contact['id'] == $group_member['contact-id'] && isset($contact['newid'])) {\r
+                $group_member['contact-id'] = $contact['newid'];\r
+                $import++;\r
+                break;\r
+            }\r
+        }\r
+        if ($import==2) {\r
+            $r = db_import_assoc('group_member', $group_member);\r
+            if ($r===false) {\r
+                logger("uimport:insert group member ".$group_member['id']." : ERROR : ".last_error(), LOGGER_NORMAL);\r
+            }\r
+        }\r
+    }\r
+\r
+\r
+\r
+    \r
+    \r
+    foreach($account['photo'] as &$photo) {\r
+        $photo['uid'] = $newuid;\r
+        $photo['data'] = hex2bin($photo['data']);\r
+        \r
+        $p = new Photo($photo['data'], $photo['type']);\r
+        $r = $p->store(\r
+            $photo['uid'],\r
+            $photo['contact-id'], //0\r
+            $photo['resource-id'],\r
+            $photo['filename'],\r
+            $photo['album'],\r
+            $photo['scale'],\r
+            $photo['profile'], //1\r
+            $photo['allow_cid'],\r
+            $photo['allow_gid'],\r
+            $photo['deny_cid'],\r
+            $photo['deny_gid']\r
+        );\r
+        \r
+        if ($r===false) {\r
+            logger("uimport:insert photo ".$photo['resource-id'].",". $photo['scale']. " : ERROR : ".last_error(), LOGGER_NORMAL);\r
+        }\r
+    } \r
+    \r
+    foreach($account['pconfig'] as &$pconfig) {\r
+        $pconfig['uid'] = $newuid;\r
+        $r = db_import_assoc('pconfig', $pconfig);\r
+        if ($r===false) {\r
+            logger("uimport:insert pconfig ".$pconfig['id']. " : ERROR : ".last_error(), LOGGER_NORMAL);\r
+        }\r
+    } \r
+     \r
+    \r
+    info(t("Done. You can now login with your username and password"));\r
+    goaway( $a->get_baseurl() ."/login");\r
+    \r
+    \r
+}
\ No newline at end of file
index a8fa100c8f9c7109552405e9ea1369f187f8ee63..208f97bcb66fa51fa3836238ce4535517aab5ec8 100644 (file)
@@ -42,6 +42,7 @@ function register_post(&$a) {
                $verified = 0;
                break;
        }
+    
 
        require_once('include/user.php');
 
@@ -234,7 +235,7 @@ function register_content(&$a) {
                        '$yes_selected' => ' checked="checked" ',
                        '$no_selected'  => '',
                        '$str_yes'      => t('Yes'),
-                       '$str_no'       => t('No')
+                       '$str_no'       => t('No'),
                ));
        }
 
@@ -275,7 +276,8 @@ function register_content(&$a) {
                '$email'     => $email,
                '$nickname'  => $nickname,
                '$license'   => $license,
-               '$sitename'  => $a->get_hostname()
+               '$sitename'  => $a->get_hostname(),
+      
        ));
        return $o;
 
index e1fb22855a6066fa8b99336b837f29ef9ebbb0ea..f216f551fa191f412bc66bdf408cb45933e2afea 100644 (file)
 <?php
 
-function uexport_init(&$a) {
 
+function uexport_init(&$a){
        if(! local_user())
                killme();
-
-       $user = array();
-       $r = q("SELECT * FROM `user` WHERE `uid` = %d LIMIT 1",
-               local_user()
+        
+       $tabs = array(
+               array(
+                       'label' => t('Account settings'),
+                       'url'   => $a->get_baseurl(true).'/settings',
+                       'selected'      => '',
+               ),      
+               array(
+                       'label' => t('Display settings'),
+                       'url'   => $a->get_baseurl(true).'/settings/display',
+                       'selected'      =>'',
+               ),      
+               
+               array(
+                       'label' => t('Connector settings'),
+                       'url'   => $a->get_baseurl(true).'/settings/connectors',
+                       'selected'      => '',
+               ),
+               array(
+                       'label' => t('Plugin settings'),
+                       'url'   => $a->get_baseurl(true).'/settings/addon',
+                       'selected'      => '',
+               ),
+               array(
+                       'label' => t('Connected apps'),
+                       'url' => $a->get_baseurl(true) . '/settings/oauth',
+                       'selected' => '',
+               ),
+               array(
+                       'label' => t('Export personal data'),
+                       'url' => $a->get_baseurl(true) . '/uexport',
+                       'selected' => 'active'
+               ),
+               array(
+                       'label' => t('Remove account'),
+                       'url' => $a->get_baseurl(true) . '/removeme',
+                       'selected' => ''
+               )
        );
+       
+       $tabtpl = get_markup_template("generic_links_widget.tpl");
+       $a->page['aside'] = replace_macros($tabtpl, array(
+               '$title' => t('Settings'),
+               '$class' => 'settings-widget',
+               '$items' => $tabs,
+       ));
+}
+
+function uexport_content(&$a){
+    
+    if ($a->argc > 1) {
+        header("Content-type: application/json");
+        header('Content-Disposition: attachment; filename="'.$a->user['nickname'].'.'.$a->argv[1].'"');
+        switch($a->argv[1]) {
+            case "backup": uexport_all($a); killme(); break;
+            case "account": uexport_account($a); killme(); break;
+            default:
+                killme();
+        }
+    }
+
+    /**
+      * options shown on "Export personal data" page
+      * list of array( 'link url', 'link text', 'help text' )
+      */
+    $options = array(
+            array('/uexport/account',t('Export account'),t('Export your account info and contacts. Use this to make a backup of your account and/or to move it to another server.')),
+            array('/uexport/backup',t('Export all'),t('Export your accout info, contacts and all your items as json. Could be a very big file, and could take a lot of time. Use this to make a full backup of your account (photos are not exported)')),
+    );
+    call_hooks('uexport_options', $options);
+        
+    $tpl = get_markup_template("uexport.tpl");
+    return replace_macros($tpl, array(
+        '$baseurl' => $a->get_baseurl(),
+        '$title' => t('Export personal data'),
+        '$options' => $options
+    ));
+    
+    
+}
+
+function _uexport_multirow($query) {
+       $result = array();
+       $r = q($query);
        if(count($r)) {
-               foreach($r as $rr)
+               foreach($r as $rr){
+            $p = array();
                        foreach($rr as $k => $v)
-                               $user[$k] = $v;
-
+                               $p[$k] = $v;
+            $result[] = $p;
+        }
        }
-       $contact = array();
-       $r = q("SELECT * FROM `contact` WHERE `uid` = %d ",
-               intval(local_user())
-       );
+    return $result;
+}
+
+function _uexport_row($query) {
+       $result = array();
+       $r = q($query);
        if(count($r)) {
                foreach($r as $rr)
                        foreach($rr as $k => $v)
-                               $contact[][$k] = $v;
+                               $result[$k] = $v;
 
        }
+    return $result;
+}
 
-       $profile = array();
-       $r = q("SELECT * FROM `profile` WHERE `uid` = %d ",
-               intval(local_user())
+
+function uexport_account($a){
+
+       $user = _uexport_row(
+        sprintf( "SELECT * FROM `user` WHERE `uid` = %d LIMIT 1", intval(local_user()) )
        );
-       if(count($r)) {
-               foreach($r as $rr)
-                       foreach($rr as $k => $v)
-                               $profile[][$k] = $v;
-       }
+    
+       $contact = _uexport_multirow(
+        sprintf( "SELECT * FROM `contact` WHERE `uid` = %d ",intval(local_user()) )
+       );
+
+
+       $profile =_uexport_multirow(
+        sprintf( "SELECT * FROM `profile` WHERE `uid` = %d ", intval(local_user()) )
+       );
+
+    $photo = _uexport_multirow(
+        sprintf( "SELECT * FROM photo WHERE uid = %d AND profile = 1", intval(local_user()) )
+    );
+    foreach ($photo as &$p) $p['data'] = bin2hex($p['data']);
 
-       $output = array('user' => $user, 'contact' => $contact, 'profile' => $profile );
+    $pconfig = _uexport_multirow(
+        sprintf( "SELECT * FROM pconfig WHERE uid = %d",intval(local_user()) )
+    );
 
-       header("Content-type: application/json");
+    $group = _uexport_multirow(
+        sprintf( "SELECT * FROM group WHERE uid = %d",intval(local_user()) )
+    );
+    
+    $group_member = _uexport_multirow(
+        sprintf( "SELECT * FROM group_member WHERE uid = %d",intval(local_user()) )
+    );
+
+       $output = array(
+        'version' => FRIENDICA_VERSION,
+        'schema' => DB_UPDATE_VERSION,
+        'baseurl' => $a->get_baseurl(),
+        'user' => $user, 
+        'contact' => $contact, 
+        'profile' => $profile, 
+        'photo' => $photo,
+        'pconfig' => $pconfig,
+        'group' => $group,
+        'group_member' => $group_member,
+    );
+
+    //echo "<pre>"; var_dump(json_encode($output)); killme();
        echo json_encode($output);
 
+}
+
+/**
+ * echoes account data and items as separated json, one per line
+ */
+function uexport_all(&$a) {
+    
+    uexport_account($a);
+
        $r = q("SELECT count(*) as `total` FROM `item` WHERE `uid` = %d ",
                intval(local_user())
        );
@@ -66,7 +194,4 @@ function uexport_init(&$a) {
                echo json_encode($output);
        }
 
-
-       killme();
-
 }
\ No newline at end of file
diff --git a/mod/uimport.php b/mod/uimport.php
new file mode 100644 (file)
index 0000000..f5f7366
--- /dev/null
@@ -0,0 +1,50 @@
+<?php\r
+/**\r
+ * View for user import\r
+ */\r
+\r
+require_once("include/uimport.php");\r
+\r
+function uimport_post(&$a) {\r
+       switch($a->config['register_policy']) {\r
+        case REGISTER_OPEN:\r
+            $blocked = 0;\r
+            $verified = 1;\r
+            break;\r
+\r
+        case REGISTER_APPROVE:\r
+            $blocked = 1;\r
+            $verified = 0;\r
+            break;\r
+\r
+        default:\r
+        case REGISTER_CLOSED:\r
+            if((! x($_SESSION,'authenticated') && (! x($_SESSION,'administrator')))) {\r
+                notice( t('Permission denied.') . EOL );\r
+                return;\r
+            }\r
+            $blocked = 1;\r
+            $verified = 0;\r
+            break;\r
+       }\r
+    \r
+    if (x($_FILES,'accountfile')){\r
+        // TODO: pass $blocked / $verified, send email to admin on REGISTER_APPROVE\r
+        import_account($a, $_FILES['accountfile']);\r
+        return;\r
+    }\r
+}\r
+\r
+function uimport_content(&$a) {\r
+    $tpl = get_markup_template("uimport.tpl");\r
+    return replace_macros($tpl, array(\r
+        '$regbutt' => t('Import'),\r
+        '$import' => array(\r
+            'title' => t("Move account"),\r
+            'text' => t("You can move here an account from another Friendica server. <br>\r
+                            You need to export your account form the old server and upload it here. We will create here your old account with all your contacts. We will try also to inform you friends that you moved here.<br>\r
+                            <b>This feature is experimental. We can't move here contacts from ostatus network (statusnet/identi.ca) or from diaspora"),\r
+            'field' => array('accountfile', t('Account file'),'<input id="id_accountfile" name="accountfile" type="file">', t('To export your accont, go to "Settings->Export your porsonal data" and select "Export account"')),\r
+        ),  \r
+    ));\r
+}\r
index 8ce1d20acbae31def0f1364f1fbe3fd01ddc2561..7cf11881adfa476893a2e7fe8170fabb0ecf9d80 100644 (file)
@@ -55,6 +55,7 @@
                <input type="submit" name="submit" id="register-submit-button" value="$regbutt" />
        </div>
        <div id="register-submit-end" ></div>
+    
 </form>
 
 $license
diff --git a/view/uexport.tpl b/view/uexport.tpl
new file mode 100644 (file)
index 0000000..30d11d5
--- /dev/null
@@ -0,0 +1,9 @@
+<h3>$title</h3>\r
+\r
+\r
+{{ for $options as $o }}\r
+<dl>\r
+    <dt><a href="$baseurl/$o.0">$o.1</a></dt>\r
+    <dd>$o.2</dd>\r
+</dl>\r
+{{ endfor }}
\ No newline at end of file
diff --git a/view/uimport.tpl b/view/uimport.tpl
new file mode 100644 (file)
index 0000000..fb34add
--- /dev/null
@@ -0,0 +1,11 @@
+<form action="uimport" method="post" id="uimport-form" enctype="multipart/form-data">\r
+<h1>$import.title</h1>\r
+    <p>$import.text</p>\r
+     {{inc field_custom.tpl with $field=$import.field }}{{ endinc }}\r
+     \r
+     \r
+       <div id="register-submit-wrapper">\r
+               <input type="submit" name="submit" id="register-submit-button" value="$regbutt" />\r
+       </div>\r
+       <div id="register-submit-end" ></div>    \r
+</form>
\ No newline at end of file