]> git.mxchange.org Git - friendica.git/blob - include/uimport.php
707d535fc8b87abbd47b988f622f7d291ce749f9
[friendica.git] / include / uimport.php
1 <?php\r
2 \r
3 use Friendica\App;\r
4 \r
5 require_once("include/Photo.php");\r
6 define("IMPORT_DEBUG", False);\r
7 \r
8 function last_insert_id() {\r
9         global $db;\r
10 \r
11         if (IMPORT_DEBUG)\r
12                 return 1;\r
13 \r
14         return $db->insert_id();\r
15 }\r
16 \r
17 function last_error() {\r
18         global $db;\r
19         return $db->error;\r
20 }\r
21 \r
22 /**\r
23  * Remove columns from array $arr that aren't in table $table\r
24  *\r
25  * @param string $table Table name\r
26  * @param array &$arr Column=>Value array from json (by ref)\r
27  */\r
28 function check_cols($table, &$arr) {\r
29         $query = sprintf("SHOW COLUMNS IN `%s`", dbesc($table));\r
30         logger("uimport: $query", LOGGER_DEBUG);\r
31         $r = q($query);\r
32         $tcols = array();\r
33         // get a plain array of column names\r
34         foreach ($r as $tcol) {\r
35                 $tcols[] = $tcol['Field'];\r
36         }\r
37         // remove inexistent columns\r
38         foreach ($arr as $icol => $ival) {\r
39                 if (!in_array($icol, $tcols)) {\r
40                         unset($arr[$icol]);\r
41                 }\r
42         }\r
43 }\r
44 \r
45 /**\r
46  * Import data into table $table\r
47  *\r
48  * @param string $table Table name\r
49  * @param array $arr Column=>Value array from json\r
50  */\r
51 function db_import_assoc($table, $arr) {\r
52         if (isset($arr['id']))\r
53                 unset($arr['id']);\r
54         check_cols($table, $arr);\r
55         $cols = implode("`,`", array_map('dbesc', array_keys($arr)));\r
56         $vals = implode("','", array_map('dbesc', array_values($arr)));\r
57         $query = "INSERT INTO `$table` (`$cols`) VALUES ('$vals')";\r
58         logger("uimport: $query", LOGGER_TRACE);\r
59         if (IMPORT_DEBUG)\r
60                 return true;\r
61         return q($query);\r
62 }\r
63 \r
64 function import_cleanup($newuid) {\r
65         dba::delete('user', array('uid' => $newuid));\r
66 }\r
67 \r
68 /**\r
69  * @brief Import account file exported from mod/uexport\r
70  *\r
71  * @param App $a Friendica App Class\r
72  * @param array $file array from $_FILES\r
73  */\r
74 function import_account(App $a, $file) {\r
75         logger("Start user import from " . $file['tmp_name']);\r
76         /*\r
77           STEPS\r
78           1. checks\r
79           2. replace old baseurl with new baseurl\r
80           3. import data (look at user id and contacts id)\r
81           4. archive non-dfrn contacts\r
82           5. send message to dfrn contacts\r
83          */\r
84 \r
85         $account = json_decode(file_get_contents($file['tmp_name']), true);\r
86         if ($account === null) {\r
87                 notice(t("Error decoding account file"));\r
88                 return;\r
89         }\r
90 \r
91 \r
92         if (!x($account, 'version')) {\r
93                 notice(t("Error! No version data in file! This is not a Friendica account file?"));\r
94                 return;\r
95         }\r
96 \r
97         /*\r
98         // this is not required as we remove columns in json not in current db schema\r
99         if ($account['schema'] != DB_UPDATE_VERSION) {\r
100                 notice(t("Error! I can't import this file: DB schema version is not compatible."));\r
101                 return;\r
102         }\r
103         */\r
104 \r
105         // check for username\r
106         $r = q("SELECT uid FROM user WHERE nickname='%s'", $account['user']['nickname']);\r
107         if ($r === false) {\r
108                 logger("uimport:check nickname : ERROR : " . last_error(), LOGGER_NORMAL);\r
109                 notice(t('Error! Cannot check nickname'));\r
110                 return;\r
111         }\r
112         if (dbm::is_result($r) > 0) {\r
113                 notice(sprintf(t("User '%s' already exists on this server!"), $account['user']['nickname']));\r
114                 return;\r
115         }\r
116         // check if username matches deleted account\r
117         $r = q("SELECT id FROM userd WHERE username='%s'", $account['user']['nickname']);\r
118         if ($r === false) {\r
119                 logger("uimport:check nickname : ERROR : " . last_error(), LOGGER_NORMAL);\r
120                 notice(t('Error! Cannot check nickname'));\r
121                 return;\r
122         }\r
123         if (dbm::is_result($r) > 0) {\r
124                 notice(sprintf(t("User '%s' already exists on this server!"), $account['user']['nickname']));\r
125                 return;\r
126         }\r
127 \r
128         $oldbaseurl = $account['baseurl'];\r
129         $newbaseurl = App::get_baseurl();\r
130         $olduid = $account['user']['uid'];\r
131 \r
132         unset($account['user']['uid']);\r
133         unset($account['user']['account_expired']);\r
134         unset($account['user']['account_expires_on']);\r
135         unset($account['user']['expire_notification_sent']);\r
136         foreach ($account['user'] as $k => &$v) {\r
137                 $v = str_replace($oldbaseurl, $newbaseurl, $v);\r
138         }\r
139 \r
140 \r
141         // import user\r
142         $r = db_import_assoc('user', $account['user']);\r
143         if ($r === false) {\r
144                 //echo "<pre>"; var_dump($r, $query, mysql_error()); killme();\r
145                 logger("uimport:insert user : ERROR : " . last_error(), LOGGER_NORMAL);\r
146                 notice(t("User creation error"));\r
147                 return;\r
148         }\r
149         $newuid = last_insert_id();\r
150         //~ $newuid = 1;\r
151 \r
152         // Generate a new guid for the account. Otherwise there will be problems with diaspora\r
153         q("UPDATE `user` SET `guid` = '%s' WHERE `uid` = %d",\r
154                 dbesc(generate_user_guid()), intval($newuid));\r
155 \r
156         foreach ($account['profile'] as &$profile) {\r
157                 foreach ($profile as $k => &$v) {\r
158                         $v = str_replace($oldbaseurl, $newbaseurl, $v);\r
159                         foreach (array("profile", "avatar") as $k)\r
160                                 $v = str_replace($oldbaseurl . "/photo/" . $k . "/" . $olduid . ".jpg", $newbaseurl . "/photo/" . $k . "/" . $newuid . ".jpg", $v);\r
161                 }\r
162                 $profile['uid'] = $newuid;\r
163                 $r = db_import_assoc('profile', $profile);\r
164                 if ($r === false) {\r
165                         logger("uimport:insert profile " . $profile['profile-name'] . " : ERROR : " . last_error(), LOGGER_NORMAL);\r
166                         info(t("User profile creation error"));\r
167                         import_cleanup($newuid);\r
168                         return;\r
169                 }\r
170         }\r
171 \r
172         $errorcount = 0;\r
173         foreach ($account['contact'] as &$contact) {\r
174                 if ($contact['uid'] == $olduid && $contact['self'] == '1') {\r
175                         foreach ($contact as $k => &$v) {\r
176                                 $v = str_replace($oldbaseurl, $newbaseurl, $v);\r
177                                 foreach (array("profile", "avatar", "micro") as $k)\r
178                                         $v = str_replace($oldbaseurl . "/photo/" . $k . "/" . $olduid . ".jpg", $newbaseurl . "/photo/" . $k . "/" . $newuid . ".jpg", $v);\r
179                         }\r
180                 }\r
181                 if ($contact['uid'] == $olduid && $contact['self'] == '0') {\r
182                         // set contacts 'avatar-date' to NULL_DATE to let poller to update urls\r
183                         $contact["avatar-date"] = NULL_DATE;\r
184 \r
185 \r
186                         switch ($contact['network']) {\r
187                                 case NETWORK_DFRN:\r
188                                         //  send relocate message (below)\r
189                                         break;\r
190                                 case NETWORK_ZOT:\r
191                                         /// @TODO handle zot network\r
192                                         break;\r
193                                 case NETWORK_MAIL2:\r
194                                         /// @TODO ?\r
195                                         break;\r
196                                 case NETWORK_FEED:\r
197                                 case NETWORK_MAIL:\r
198                                         // Nothing to do\r
199                                         break;\r
200                                 default:\r
201                                         // archive other contacts\r
202                                         $contact['archive'] = "1";\r
203                         }\r
204                 }\r
205                 $contact['uid'] = $newuid;\r
206                 $r = db_import_assoc('contact', $contact);\r
207                 if ($r === false) {\r
208                         logger("uimport:insert contact " . $contact['nick'] . "," . $contact['network'] . " : ERROR : " . last_error(), LOGGER_NORMAL);\r
209                         $errorcount++;\r
210                 } else {\r
211                         $contact['newid'] = last_insert_id();\r
212                 }\r
213         }\r
214         if ($errorcount > 0) {\r
215                 notice(sprintf(tt("%d contact not imported", "%d contacts not imported", $errorcount), $errorcount));\r
216         }\r
217 \r
218         foreach ($account['group'] as &$group) {\r
219                 $group['uid'] = $newuid;\r
220                 $r = db_import_assoc('group', $group);\r
221                 if ($r === false) {\r
222                         logger("uimport:insert group " . $group['name'] . " : ERROR : " . last_error(), LOGGER_NORMAL);\r
223                 } else {\r
224                         $group['newid'] = last_insert_id();\r
225                 }\r
226         }\r
227 \r
228         foreach ($account['group_member'] as &$group_member) {\r
229                 $group_member['uid'] = $newuid;\r
230 \r
231                 $import = 0;\r
232                 foreach ($account['group'] as $group) {\r
233                         if ($group['id'] == $group_member['gid'] && isset($group['newid'])) {\r
234                                 $group_member['gid'] = $group['newid'];\r
235                                 $import++;\r
236                                 break;\r
237                         }\r
238                 }\r
239                 foreach ($account['contact'] as $contact) {\r
240                         if ($contact['id'] == $group_member['contact-id'] && isset($contact['newid'])) {\r
241                                 $group_member['contact-id'] = $contact['newid'];\r
242                                 $import++;\r
243                                 break;\r
244                         }\r
245                 }\r
246                 if ($import == 2) {\r
247                         $r = db_import_assoc('group_member', $group_member);\r
248                         if ($r === false) {\r
249                                 logger("uimport:insert group member " . $group_member['id'] . " : ERROR : " . last_error(), LOGGER_NORMAL);\r
250                         }\r
251                 }\r
252         }\r
253 \r
254         foreach ($account['photo'] as &$photo) {\r
255                 $photo['uid'] = $newuid;\r
256                 $photo['data'] = hex2bin($photo['data']);\r
257 \r
258                 $p = new Photo($photo['data'], $photo['type']);\r
259                 $r = $p->store(\r
260                                 $photo['uid'], $photo['contact-id'], //0\r
261                                 $photo['resource-id'], $photo['filename'], $photo['album'], $photo['scale'], $photo['profile'], //1\r
262                                 $photo['allow_cid'], $photo['allow_gid'], $photo['deny_cid'], $photo['deny_gid']\r
263                 );\r
264 \r
265                 if ($r === false) {\r
266                         logger("uimport:insert photo " . $photo['resource-id'] . "," . $photo['scale'] . " : ERROR : " . last_error(), LOGGER_NORMAL);\r
267                 }\r
268         }\r
269 \r
270         foreach ($account['pconfig'] as &$pconfig) {\r
271                 $pconfig['uid'] = $newuid;\r
272                 $r = db_import_assoc('pconfig', $pconfig);\r
273                 if ($r === false) {\r
274                         logger("uimport:insert pconfig " . $pconfig['id'] . " : ERROR : " . last_error(), LOGGER_NORMAL);\r
275                 }\r
276         }\r
277 \r
278         // send relocate messages\r
279         proc_run(PRIORITY_HIGH, 'include/notifier.php', 'relocate', $newuid);\r
280 \r
281         info(t("Done. You can now login with your username and password"));\r
282         goaway(App::get_baseurl() . "/login");\r
283 }\r