Merge pull request #12816 from annando/view
[friendica.git/.git] / update.php
1 <?php
2 /**
3  * @copyright Copyright (C) 2010-2023, the Friendica project
4  *
5  * @license GNU AGPL version 3 or any later version
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU Affero General Public License as
9  * published by the Free Software Foundation, either version 3 of the
10  * License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU Affero General Public License for more details.
16  *
17  * You should have received a copy of the GNU Affero General Public License
18  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
19  *
20  * Automatic post-database structure change updates
21  *
22  * These functions are responsible for doing critical post update changes to the data (not the structure) in the database.
23  *
24  * Database structure changes are done in static/dbstructure.config.php
25  *
26  * For non-critical database migrations, please add a method in the Database\PostUpdate class
27  *
28  * If there is a need for a post update to a structure change, update this file
29  * by adding a new function at the end with the number of the new DB_UPDATE_VERSION.
30  *
31  * The numbered script in this file has to be exactly like the DB_UPDATE_VERSION
32  *
33  * Example:
34  * You are currently on version 4711 and you are preparing changes that demand an update script.
35  *
36  * 1. Create a function "update_4712()" here in the update.php
37  * 2. Apply the needed structural changes in static/dbStructure.php
38  * 3. Set DB_UPDATE_VERSION in static/dbstructure.config.php to 4712.
39  *
40  * If you need to run a script before the database update, name the function "pre_update_4712()"
41  */
42
43 use Friendica\Core\Config\ValueObject\Cache;
44 use Friendica\Core\Logger;
45 use Friendica\Core\Protocol;
46 use Friendica\Core\Storage\Capability\ICanReadFromStorage;
47 use Friendica\Core\Storage\Type\Database as DatabaseStorage;
48 use Friendica\Core\Update;
49 use Friendica\Core\Worker;
50 use Friendica\Database\Database;
51 use Friendica\Database\DBA;
52 use Friendica\Database\DBStructure;
53 use Friendica\DI;
54 use Friendica\Model\Contact;
55 use Friendica\Model\Item;
56 use Friendica\Model\ItemURI;
57 use Friendica\Model\Notification;
58 use Friendica\Model\Photo;
59 use Friendica\Model\Post;
60 use Friendica\Model\Profile;
61 use Friendica\Model\User;
62 use Friendica\Protocol\Activity;
63 use Friendica\Protocol\Delivery;
64 use Friendica\Security\PermissionSet\Repository\PermissionSet;
65
66 // Post-update script of PR 5751
67 function update_1298()
68 {
69         $keys = ['gender', 'marital', 'sexual'];
70         foreach ($keys as $translateKey) {
71                 $allData = DBA::select('profile', ['id', $translateKey]);
72                 $allLangs = DI::l10n()->getAvailableLanguages();
73                 $success = 0;
74                 $fail = 0;
75                 foreach ($allData as $key => $data) {
76                         $toTranslate = $data[$translateKey];
77                         if ($toTranslate != '') {
78                                 foreach ($allLangs as $key => $lang) {
79                                         $a = new \stdClass();
80                                         $a->strings = [];
81
82                                         // First we get the the localizations
83                                         if (file_exists('view/lang/$lang/strings.php')) {
84                                                 include 'view/lang/$lang/strings.php';
85                                         }
86                                         if (file_exists('addon/morechoice/lang/$lang/strings.php')) {
87                                                 include 'addon/morechoice/lang/$lang/strings.php';
88                                         }
89
90                                         $localizedStrings = $a->strings;
91                                         unset($a);
92
93                                         $key = array_search($toTranslate, $localizedStrings);
94                                         if ($key !== false) {
95                                                 break;
96                                         }
97
98                                         // defaulting to empty string
99                                         $key = '';
100                                 }
101
102                                 if ($key == '') {
103                                         $fail++;
104                                 } else {
105                                         DBA::update('profile', [$translateKey => $key], ['id' => $data['id']]);
106                                         Logger::notice('Updated contact', ['action' => 'update', 'contact' => $data['id'], "$translateKey" => $key,
107                                                 'was' => $data[$translateKey]]);
108
109                                         Contact::updateSelfFromUserID($data['id']);
110                                         Profile::publishUpdate($data['id']);
111                                         $success++;
112                                 }
113                         }
114                 }
115
116                 Logger::notice($translateKey . ' fix completed', ['action' => 'update', 'translateKey' => $translateKey, 'Success' => $success, 'Fail' => $fail ]);
117         }
118         return Update::SUCCESS;
119 }
120
121 function update_1309()
122 {
123         $queue = DBA::select('queue', ['id', 'cid', 'guid']);
124         while ($entry = DBA::fetch($queue)) {
125                 $contact = DBA::selectFirst('contact', ['uid'], ['id' => $entry['cid']]);
126                 if (!DBA::isResult($contact)) {
127                         continue;
128                 }
129
130                 $item = Post::selectFirst(['id', 'gravity'], ['uid' => $contact['uid'], 'guid' => $entry['guid']]);
131                 if (!DBA::isResult($item)) {
132                         continue;
133                 }
134
135                 $deliver_options = ['priority' => Worker::PRIORITY_MEDIUM, 'dont_fork' => true];
136                 Worker::add($deliver_options, 'Delivery', Delivery::POST, $item['id'], $entry['cid']);
137                 Logger::info('Added delivery worker', ['item' => $item['id'], 'contact' => $entry['cid']]);
138                 DBA::delete('queue', ['id' => $entry['id']]);
139         }
140         return Update::SUCCESS;
141 }
142
143 function update_1315()
144 {
145         if (DBStructure::existsTable('item-delivery-data')) {
146                 DBA::delete('item-delivery-data', ['postopts' => '', 'inform' => '', 'queue_count' => 0, 'queue_done' => 0]);
147         }
148         return Update::SUCCESS;
149 }
150
151 function update_1318()
152 {
153         DBA::update('profile', ['marital' => 'In a relation'], ['marital' => 'Unavailable']);
154         DBA::update('profile', ['marital' => 'Single'], ['marital' => 'Available']);
155
156         Worker::add(Worker::PRIORITY_LOW, 'ProfileUpdate');
157         return Update::SUCCESS;
158 }
159
160 function update_1323()
161 {
162         $users = DBA::select('user', ['uid']);
163         while ($user = DBA::fetch($users)) {
164                 if (Contact::updateSelfFromUserID($user['uid'])) {
165                         Profile::publishUpdate($user['uid']);
166                 }
167         }
168         DBA::close($users);
169
170         return Update::SUCCESS;
171 }
172
173 function update_1327()
174 {
175         $contacts = DBA::select('contact', ['uid', 'id', 'blocked', 'readonly'], ["`uid` != ? AND (`blocked` OR `readonly`) AND NOT `pending`", 0]);
176         while ($contact = DBA::fetch($contacts)) {
177                 Contact\User::setBlocked($contact['id'], $contact['uid'], $contact['blocked']);
178                 Contact\User::setIgnored($contact['id'], $contact['uid'], $contact['readonly']);
179         }
180         DBA::close($contacts);
181
182         return Update::SUCCESS;
183 }
184
185 function update_1330()
186 {
187         $currStorage = DI::config()->get('storage', 'class', '');
188
189         // set the name of the storage instead of the classpath as config
190         if (!empty($currStorage)) {
191                 /** @var ICanReadFromStorage $currStorage */
192                 if (!DI::config()->set('storage', 'name', $currStorage::getName())) {
193                         return Update::FAILED;
194                 }
195
196                 // try to delete the class since it isn't needed. This won't work with config files
197                 DI::config()->delete('storage', 'class');
198         }
199
200         // Update attachments and photos
201         if (!DBA::e("UPDATE `photo` SET `photo`.`backend-class` = SUBSTR(`photo`.`backend-class`, 25) WHERE `photo`.`backend-class` LIKE 'Friendica\\\Model\\\Storage\\\%' ESCAPE '|'") ||
202             !DBA::e("UPDATE `attach` SET `attach`.`backend-class` = SUBSTR(`attach`.`backend-class`, 25) WHERE `attach`.`backend-class` LIKE 'Friendica\\\Model\\\Storage\\\%' ESCAPE '|'")) {
203                 return Update::FAILED;
204         };
205
206         return Update::SUCCESS;
207 }
208
209 function update_1332()
210 {
211         $condition = ["`is-default` IS NOT NULL"];
212         $profiles = DBA::select('profile', [], $condition);
213
214         while ($profile = DBA::fetch($profiles)) {
215                 Profile::migrate($profile);
216         }
217         DBA::close($profiles);
218
219         DBA::update('contact', ['profile-id' => null], ['`profile-id` IS NOT NULL']);
220
221         return Update::SUCCESS;
222 }
223
224 function update_1347()
225 {
226         foreach (Item::ACTIVITIES as $index => $activity) {
227                 DBA::insert('verb', ['id' => $index + 1, 'name' => $activity], Database::INSERT_IGNORE);
228         }
229
230         return Update::SUCCESS;
231 }
232
233 function pre_update_1348()
234 {
235         if (!DBA::exists('contact', ['id' => 0])) {
236                 DBA::insert('contact', ['nurl' => '']);
237                 $lastid = DBA::lastInsertId();
238                 if ($lastid != 0) {
239                         DBA::update('contact', ['id' => 0], ['id' => $lastid]);
240                 }
241         }
242
243         // The tables "permissionset" and "tag" could or could not exist during the update.
244         // This depends upon the previous version. Depending upon this situation we have to add
245         // the "0" values before adding the foreign keys - or after would be sufficient.
246
247         update_1348();
248
249         if (DBStructure::existsTable('auth_codes') && DBStructure::existsTable('clients')) {
250                 DBA::e("DELETE FROM `auth_codes` WHERE NOT `client_id` IN (SELECT `client_id` FROM `clients`)");
251         }
252         if (DBStructure::existsTable('tokens') && DBStructure::existsTable('clients')) {
253                 DBA::e("DELETE FROM `tokens` WHERE NOT `client_id` IN (SELECT `client_id` FROM `clients`)");
254         }
255         return Update::SUCCESS;
256 }
257
258 function update_1348()
259 {
260         // Insert a permissionset with id=0
261         // Inserting it without an ID and then changing the value to 0 tricks the auto increment
262         if (!DBA::exists('permissionset', ['id' => 0])) {
263                 DBA::insert('permissionset', ['allow_cid' => '', 'allow_gid' => '', 'deny_cid' => '', 'deny_gid' => '']);
264                 $lastid = DBA::lastInsertId();
265                 if ($lastid != 0) {
266                         DBA::update('permissionset', ['id' => 0], ['id' => $lastid]);
267                 }
268         }
269
270         if (!DBA::exists('tag', ['id' => 0])) {
271                 DBA::insert('tag', ['name' => '']);
272                 $lastid = DBA::lastInsertId();
273                 if ($lastid != 0) {
274                         DBA::update('tag', ['id' => 0], ['id' => $lastid]);
275                 }
276         }
277
278         return Update::SUCCESS;
279 }
280
281 function update_1349()
282 {
283         if (!DBStructure::existsTable('item-activity')) {
284                 return Update::SUCCESS;
285         }
286
287         $correct = true;
288         foreach (Item::ACTIVITIES as $index => $activity) {
289                 if (!DBA::exists('verb', ['id' => $index + 1, 'name' => $activity])) {
290                         $correct = false;
291                 }
292         }
293
294         if (!$correct) {
295                 // The update failed - but it cannot be recovered, since the data doesn't match our expectation
296                 // This means that we can't use this "shortcut" to fill the "vid" field and we have to rely upon
297                 // the postupdate. This is not fatal, but means that it will take some longer time for the system
298                 // to fill all data.
299                 return Update::SUCCESS;
300         }
301
302         if (!DBA::e("UPDATE `item` INNER JOIN `item-activity` ON `item`.`uri-id` = `item-activity`.`uri-id`
303                 SET `vid` = `item-activity`.`activity` + 1 WHERE `gravity` = ? AND (`vid` IS NULL OR `vid` = 0)", Item::GRAVITY_ACTIVITY)) {
304                 return Update::FAILED;
305         }
306
307         return Update::SUCCESS;
308 }
309
310 function update_1351()
311 {
312         if (DBStructure::existsTable('thread') && !DBA::e("UPDATE `thread` INNER JOIN `item` ON `thread`.`iid` = `item`.`id` SET `thread`.`uri-id` = `item`.`uri-id`")) {
313                 return Update::FAILED;
314         }
315
316         return Update::SUCCESS;
317 }
318
319 function pre_update_1354()
320 {
321         if (DBStructure::existsColumn('contact', ['ffi_keyword_blacklist'])
322                 && !DBStructure::existsColumn('contact', ['ffi_keyword_denylist'])
323                 && !DBA::e("ALTER TABLE `contact` CHANGE `ffi_keyword_blacklist` `ffi_keyword_denylist` text null")) {
324                 return Update::FAILED;
325         }
326         return Update::SUCCESS;
327 }
328
329 function update_1354()
330 {
331         if (DBStructure::existsColumn('contact', ['ffi_keyword_blacklist'])
332                 && DBStructure::existsColumn('contact', ['ffi_keyword_denylist'])) {
333                 if (!DBA::e("UPDATE `contact` SET `ffi_keyword_denylist` = `ffi_keyword_blacklist`")) {
334                         return Update::FAILED;
335                 }
336
337                 // When the data had been copied then the main task is done.
338                 // Having the old field removed is only beauty but not crucial.
339                 // So we don't care if this was successful or not.
340                 DBA::e("ALTER TABLE `contact` DROP `ffi_keyword_blacklist`");
341         }
342         return Update::SUCCESS;
343 }
344
345 function update_1357()
346 {
347         if (!DBA::e("UPDATE `contact` SET `failed` = true WHERE `success_update` < `failure_update` AND `failed` IS NULL")) {
348                 return Update::FAILED;
349         }
350
351         if (!DBA::e("UPDATE `contact` SET `failed` = false WHERE `success_update` > `failure_update` AND `failed` IS NULL")) {
352                 return Update::FAILED;
353         }
354
355         if (!DBA::e("UPDATE `contact` SET `failed` = false WHERE `updated` > `failure_update` AND `failed` IS NULL")) {
356                 return Update::FAILED;
357         }
358
359         if (!DBA::e("UPDATE `contact` SET `failed` = false WHERE `last-item` > `failure_update` AND `failed` IS NULL")) {
360                 return Update::FAILED;
361         }
362
363         if (!DBA::e("UPDATE `gserver` SET `failed` = true WHERE `last_contact` < `last_failure` AND `failed` IS NULL")) {
364                 return Update::FAILED;
365         }
366
367         if (!DBA::e("UPDATE `gserver` SET `failed` = false WHERE `last_contact` > `last_failure` AND `failed` IS NULL")) {
368                 return Update::FAILED;
369         }
370
371         return Update::SUCCESS;
372 }
373
374 function pre_update_1358()
375 {
376         if (!DBA::e("DELETE FROM `contact-relation` WHERE NOT `relation-cid` IN (SELECT `id` FROM `contact`) OR NOT `cid` IN (SELECT `id` FROM `contact`)")) {
377                 return Update::FAILED;
378         }
379
380         return Update::SUCCESS;
381 }
382
383 function pre_update_1363()
384 {
385         Photo::delete(["`contact-id` != ? AND NOT `contact-id` IN (SELECT `id` FROM `contact`)", 0]);
386         return Update::SUCCESS;
387 }
388
389 function pre_update_1364()
390 {
391         if (!DBA::e("DELETE FROM `2fa_recovery_codes` WHERE NOT `uid` IN (SELECT `uid` FROM `user`)")) {
392                 return Update::FAILED;
393         }
394
395         if (!DBA::e("DELETE FROM `2fa_app_specific_password` WHERE NOT `uid` IN (SELECT `uid` FROM `user`)")) {
396                 return Update::FAILED;
397         }
398
399         if (!DBA::e("DELETE FROM `attach` WHERE NOT `uid` IN (SELECT `uid` FROM `user`)")) {
400                 return Update::FAILED;
401         }
402
403         if (DBStructure::existsTable('clients') && !DBA::e("DELETE FROM `clients` WHERE NOT `uid` IN (SELECT `uid` FROM `user`)")) {
404                 return Update::FAILED;
405         }
406
407         if (!DBA::e("DELETE FROM `conv` WHERE NOT `uid` IN (SELECT `uid` FROM `user`)")) {
408                 return Update::FAILED;
409         }
410
411         if (!DBA::e("DELETE FROM `fsuggest` WHERE NOT `uid` IN (SELECT `uid` FROM `user`)")) {
412                 return Update::FAILED;
413         }
414
415         if (!DBA::e("DELETE FROM `group` WHERE NOT `uid` IN (SELECT `uid` FROM `user`)")) {
416                 return Update::FAILED;
417         }
418
419         if (!DBA::e("DELETE FROM `intro` WHERE NOT `uid` IN (SELECT `uid` FROM `user`)")) {
420                 return Update::FAILED;
421         }
422
423         if (!DBA::e("DELETE FROM `manage` WHERE NOT `uid` IN (SELECT `uid` FROM `user`)")) {
424                 return Update::FAILED;
425         }
426
427         if (!DBA::e("DELETE FROM `manage` WHERE NOT `mid` IN (SELECT `uid` FROM `user`)")) {
428                 return Update::FAILED;
429         }
430
431         if (!DBA::e("DELETE FROM `mail` WHERE NOT `uid` IN (SELECT `uid` FROM `user`)")) {
432                 return Update::FAILED;
433         }
434
435         if (!DBA::e("DELETE FROM `mailacct` WHERE NOT `uid` IN (SELECT `uid` FROM `user`)")) {
436                 return Update::FAILED;
437         }
438
439         if (!DBA::e("DELETE FROM `notify` WHERE NOT `uid` IN (SELECT `uid` FROM `user`)")) {
440                 return Update::FAILED;
441         }
442
443         if (!DBA::e("DELETE FROM `openwebauth-token` WHERE NOT `uid` IN (SELECT `uid` FROM `user`)")) {
444                 return Update::FAILED;
445         }
446
447         if (!DBA::e("DELETE FROM `pconfig` WHERE NOT `uid` IN (SELECT `uid` FROM `user`)")) {
448                 return Update::FAILED;
449         }
450
451         if (!DBA::e("DELETE FROM `profile` WHERE NOT `uid` IN (SELECT `uid` FROM `user`)")) {
452                 return Update::FAILED;
453         }
454
455         if (DBStructure::existsTable('profile_check') && !DBA::e("DELETE FROM `profile_check` WHERE NOT `uid` IN (SELECT `uid` FROM `user`)")) {
456                 return Update::FAILED;
457         }
458
459         if (!DBA::e("DELETE FROM `profile_field` WHERE NOT `uid` IN (SELECT `uid` FROM `user`)")) {
460                 return Update::FAILED;
461         }
462
463         if (!DBA::e("DELETE FROM `push_subscriber` WHERE NOT `uid` IN (SELECT `uid` FROM `user`)")) {
464                 return Update::FAILED;
465         }
466
467         if (!DBA::e("DELETE FROM `register` WHERE NOT `uid` IN (SELECT `uid` FROM `user`)")) {
468                 return Update::FAILED;
469         }
470
471         if (!DBA::e("DELETE FROM `search` WHERE NOT `uid` IN (SELECT `uid` FROM `user`)")) {
472                 return Update::FAILED;
473         }
474
475         if (DBStructure::existsTable('tokens') && !DBA::e("DELETE FROM `tokens` WHERE NOT `uid` IN (SELECT `uid` FROM `user`)")) {
476                 return Update::FAILED;
477         }
478
479         if (!DBA::e("DELETE FROM `user-contact` WHERE NOT `uid` IN (SELECT `uid` FROM `user`)")) {
480                 return Update::FAILED;
481         }
482
483         if (DBStructure::existsTable('user-item') && !DBA::e("DELETE FROM `user-item` WHERE NOT `uid` IN (SELECT `uid` FROM `user`)")) {
484                 return Update::FAILED;
485         }
486
487         if (!DBA::e("DELETE FROM `notify-threads` WHERE NOT `receiver-uid` IN (SELECT `uid` FROM `user`)")) {
488                 return Update::FAILED;
489         }
490
491         if (!DBA::e("DELETE FROM `event` WHERE NOT `cid` IN (SELECT `id` FROM `contact`)")) {
492                 return Update::FAILED;
493         }
494
495         if (!DBA::e("DELETE FROM `fsuggest` WHERE NOT `cid` IN (SELECT `id` FROM `contact`)")) {
496                 return Update::FAILED;
497         }
498
499         if (!DBA::e("DELETE FROM `group_member` WHERE NOT `contact-id` IN (SELECT `id` FROM `contact`)")) {
500                 return Update::FAILED;
501         }
502
503         if (!DBA::e("DELETE FROM `intro` WHERE NOT `contact-id` IN (SELECT `id` FROM `contact`)")) {
504                 return Update::FAILED;
505         }
506
507         if (DBStructure::existsTable('profile_check') && !DBA::e("DELETE FROM `profile_check` WHERE NOT `cid` IN (SELECT `id` FROM `contact`)")) {
508                 return Update::FAILED;
509         }
510
511         if (!DBA::e("DELETE FROM `user-contact` WHERE NOT `cid` IN (SELECT `id` FROM `contact`)")) {
512                 return Update::FAILED;
513         }
514
515         if (!DBA::e("DELETE FROM `group_member` WHERE NOT `gid` IN (SELECT `id` FROM `group`)")) {
516                 return Update::FAILED;
517         }
518
519         if (!DBA::e("DELETE FROM `gserver-tag` WHERE NOT `gserver-id` IN (SELECT `id` FROM `gserver`)")) {
520                 return Update::FAILED;
521         }
522
523         if (DBStructure::existsTable('user-item') && !DBA::e("DELETE FROM `user-item` WHERE NOT `iid` IN (SELECT `id` FROM `item`)")) {
524                 return Update::FAILED;
525         }
526
527         return Update::SUCCESS;
528 }
529
530 function pre_update_1365()
531 {
532         if (!DBA::e("DELETE FROM `notify-threads` WHERE NOT `notify-id` IN (SELECT `id` FROM `notify`)")) {
533                 return Update::FAILED;
534         }
535
536         if (DBStructure::existsTable('thread') && !DBA::e("DELETE FROM `thread` WHERE NOT `iid` IN (SELECT `id` FROM `item`)")) {
537                 return Update::FAILED;
538         }
539
540         return Update::SUCCESS;
541 }
542
543 function update_1375()
544 {
545         if (!DBA::e("UPDATE `item` SET `thr-parent` = `parent-uri`, `thr-parent-id` = `parent-uri-id` WHERE `thr-parent` = ''")) {
546                 return Update::FAILED;
547         }
548
549         return Update::SUCCESS;
550 }
551
552 function pre_update_1376()
553 {
554         // Insert a user with uid=0
555         DBStructure::checkInitialValues();
556
557         if (!DBA::e("DELETE FROM `item` WHERE NOT `uid` IN (SELECT `uid` FROM `user`)")) {
558                 return Update::FAILED;
559         }
560
561         if (!DBA::e("DELETE FROM `event` WHERE NOT `uid` IN (SELECT `uid` FROM `user`)")) {
562                 return Update::FAILED;
563         }
564
565         if (DBStructure::existsTable('thread') && !DBA::e("DELETE FROM `thread` WHERE NOT `uid` IN (SELECT `uid` FROM `user`)")) {
566                 return Update::FAILED;
567         }
568
569         if (!DBA::e("DELETE FROM `permissionset` WHERE NOT `uid` IN (SELECT `uid` FROM `user`)")) {
570                 return Update::FAILED;
571         }
572
573         if (!DBA::e("DELETE FROM `openwebauth-token` WHERE NOT `uid` IN (SELECT `uid` FROM `user`)")) {
574                 return Update::FAILED;
575         }
576
577         if (!DBA::e("DELETE FROM `post-category` WHERE NOT `uid` IN (SELECT `uid` FROM `user`)")) {
578                 return Update::FAILED;
579         }
580
581         Photo::delete(["NOT `uid` IN (SELECT `uid` FROM `user`)"]);
582
583         if (!DBA::e("DELETE FROM `contact` WHERE NOT `uid` IN (SELECT `uid` FROM `user`)")) {
584                 return Update::FAILED;
585         }
586
587         return Update::SUCCESS;
588 }
589
590 function pre_update_1377()
591 {
592         DBStructure::checkInitialValues();
593
594         if (!DBA::e("DELETE FROM `item` WHERE NOT `author-id` IN (SELECT `id` FROM `contact`)")) {
595                 return Update::FAILED;
596         }
597
598         if (!DBA::e("DELETE FROM `item` WHERE NOT `owner-id` IN (SELECT `id` FROM `contact`)")) {
599                 return Update::FAILED;
600         }
601
602         if (!DBA::e("UPDATE `item` SET `contact-id` = `owner-id` WHERE NOT `contact-id` IN (SELECT `id` FROM `contact`)")) {
603                 return Update::FAILED;
604         }
605
606         if (DBStructure::existsTable('thread') && !DBA::e("DELETE FROM `thread` WHERE NOT `author-id` IN (SELECT `id` FROM `contact`)")) {
607                 return Update::FAILED;
608         }
609
610         if (DBStructure::existsTable('thread') && !DBA::e("DELETE FROM `thread` WHERE NOT `owner-id` IN (SELECT `id` FROM `contact`)")) {
611                 return Update::FAILED;
612         }
613
614         if (DBStructure::existsTable('thread') && !DBA::e("UPDATE `thread` SET `contact-id` = `owner-id` WHERE NOT `contact-id` IN (SELECT `id` FROM `contact`)")) {
615                 return Update::FAILED;
616         }
617
618         if (!DBA::e("UPDATE `notify` SET `uri-id` = NULL WHERE `uri-id` = 0")) {
619                 return Update::FAILED;
620         }
621
622         if (DBStructure::existsTable('diaspora-interaction') && !DBA::e("DELETE FROM `diaspora-interaction` WHERE `uri-id` NOT IN (SELECT `id` FROM `item-uri`)")) {
623                 return Update::FAILED;
624         }
625
626         if (DBStructure::existsTable('item-activity') && !DBA::e("DELETE FROM `item-activity` WHERE `uri-id` NOT IN (SELECT `id` FROM `item-uri`)")) {
627                 return Update::FAILED;
628         }
629
630         if (DBStructure::existsTable('item-content') && !DBA::e("DELETE FROM `item-content` WHERE `uri-id` NOT IN (SELECT `id` FROM `item-uri`)")) {
631                 return Update::FAILED;
632         }
633
634         if (!DBA::e("DELETE FROM `notify` WHERE `uri-id` NOT IN (SELECT `id` FROM `item-uri`)")) {
635                 return Update::FAILED;
636         }
637
638         if (!DBA::e("UPDATE `notify` SET `parent-uri-id` = NULL WHERE `parent-uri-id` = 0")) {
639                 return Update::FAILED;
640         }
641         if (!DBA::e("DELETE FROM `notify` WHERE `parent-uri-id` NOT IN (SELECT `id` FROM `item-uri`)")) {
642                 return Update::FAILED;
643         }
644
645         if (!DBA::e("UPDATE `notify-threads` SET `master-parent-uri-id` = NULL WHERE `master-parent-uri-id` = 0")) {
646                 return Update::FAILED;
647         }
648
649         if (!DBA::e("DELETE FROM `notify-threads` WHERE `master-parent-uri-id` NOT IN (SELECT `id` FROM `item-uri`)")) {
650                 return Update::FAILED;
651         }
652
653         if (!DBA::e("DELETE FROM `notify-threads` WHERE `master-parent-item` NOT IN (SELECT `id` FROM `item`)")) {
654                 return Update::FAILED;
655         }
656
657         return Update::SUCCESS;
658 }
659
660 function update_1380()
661 {
662         if (!DBA::e("UPDATE `notify` INNER JOIN `item` ON `item`.`id` = `notify`.`iid` SET `notify`.`uri-id` = `item`.`uri-id` WHERE `notify`.`uri-id` IS NULL AND `notify`.`otype` IN (?, ?)",
663                 Notification\ObjectType::ITEM, Notification\ObjectType::PERSON)) {
664                 return Update::FAILED;
665         }
666
667         if (!DBA::e("UPDATE `notify` INNER JOIN `item` ON `item`.`id` = `notify`.`parent` SET `notify`.`parent-uri-id` = `item`.`uri-id` WHERE `notify`.`parent-uri-id` IS NULL AND `notify`.`otype` IN (?, ?)",
668                 Notification\ObjectType::ITEM, Notification\ObjectType::PERSON)) {
669                 return Update::FAILED;
670         }
671
672         return Update::SUCCESS;
673 }
674
675 function pre_update_1395()
676 {
677         if (DBStructure::existsTable('post-user') && !DBStructure::existsColumn('post-user', ['id']) && !DBA::e("DROP TABLE `post-user`")) {
678                 return Update::FAILED;
679         }
680         return Update::SUCCESS;
681 }
682
683 function update_1395()
684 {
685         if (!DBA::e("INSERT INTO `post-user`(`id`, `uri-id`, `uid`, `contact-id`, `unseen`, `origin`, `psid`)
686                 SELECT `id`, `uri-id`, `uid`, `contact-id`, `unseen`, `origin`, `psid` FROM `item`
687                 ON DUPLICATE KEY UPDATE `contact-id` = `item`.`contact-id`, `unseen` = `item`.`unseen`, `origin` = `item`.`origin`, `psid` = `item`.`psid`")) {
688                 return Update::FAILED;
689         }
690
691         if (DBStructure::existsTable('user-item') && !DBA::e("INSERT INTO `post-user`(`uri-id`, `uid`, `hidden`, `notification-type`)
692                 SELECT `uri-id`, `user-item`.`uid`, `hidden`,`notification-type` FROM `user-item`
693                         INNER JOIN `item` ON `item`.`id` = `user-item`.`iid`
694                 ON DUPLICATE KEY UPDATE `hidden` = `user-item`.`hidden`, `notification-type` = `user-item`.`notification-type`")) {
695                 return Update::FAILED;
696         }
697         return Update::SUCCESS;
698 }
699
700 function update_1396()
701 {
702         if (!DBStructure::existsTable('item-content')) {
703                 return Update::SUCCESS;
704         }
705
706         if (DBStructure::existsColumn('item-content', ['raw-body'])) {
707                 if (!DBA::e("INSERT IGNORE INTO `post-content`(`uri-id`, `title`, `content-warning`, `body`, `raw-body`,
708                         `location`, `coord`, `language`, `app`, `rendered-hash`, `rendered-html`,
709                         `object-type`, `object`, `target-type`, `target`, `resource-id`, `plink`)
710                         SELECT `item-content`.`uri-id`, `item-content`.`title`, `item-content`.`content-warning`,
711                                 `item-content`.`body`, `item-content`.`raw-body`, `item-content`.`location`, `item-content`.`coord`,
712                                 `item-content`.`language`, `item-content`.`app`, `item-content`.`rendered-hash`,
713                                 `item-content`.`rendered-html`, `item-content`.`object-type`, `item-content`.`object`,
714                                 `item-content`.`target-type`, `item-content`.`target`, `item`.`resource-id`, `item-content`.`plink`
715                                 FROM `item-content` INNER JOIN `item` ON `item`.`uri-id` = `item-content`.`uri-id`")) {
716                         return Update::FAILED;
717                 }
718         } else {
719                 if (!DBA::e("INSERT IGNORE INTO `post-content`(`uri-id`, `title`, `content-warning`, `body`,
720                         `location`, `coord`, `language`, `app`, `rendered-hash`, `rendered-html`,
721                         `object-type`, `object`, `target-type`, `target`, `resource-id`, `plink`)
722                         SELECT `item-content`.`uri-id`, `item-content`.`title`, `item-content`.`content-warning`,
723                                 `item-content`.`body`, `item-content`.`location`, `item-content`.`coord`,
724                                 `item-content`.`language`, `item-content`.`app`, `item-content`.`rendered-hash`,
725                                 `item-content`.`rendered-html`, `item-content`.`object-type`, `item-content`.`object`,
726                                 `item-content`.`target-type`, `item-content`.`target`, `item`.`resource-id`, `item-content`.`plink`
727                                 FROM `item-content` INNER JOIN `item` ON `item`.`uri-id` = `item-content`.`uri-id`")) {
728                         return Update::FAILED;
729                 }
730         }
731         return Update::SUCCESS;
732 }
733
734 function update_1397()
735 {
736         if (!DBA::e("INSERT INTO `post-user-notification`(`uri-id`, `uid`, `notification-type`)
737                 SELECT `uri-id`, `uid`, `notification-type` FROM `post-user` WHERE `notification-type` != 0
738                 ON DUPLICATE KEY UPDATE `uri-id` = `post-user`.`uri-id`, `uid` = `post-user`.`uid`, `notification-type` = `post-user`.`notification-type`")) {
739                 return Update::FAILED;
740         }
741
742         if (!DBStructure::existsTable('user-item')) {
743                 return Update::SUCCESS;
744         }
745
746         if (!DBA::e("INSERT INTO `post-user-notification`(`uri-id`, `uid`, `notification-type`)
747                 SELECT `uri-id`, `user-item`.`uid`, `notification-type` FROM `user-item`
748                         INNER JOIN `item` ON `item`.`id` = `user-item`.`iid` WHERE `notification-type` != 0
749                 ON DUPLICATE KEY UPDATE `notification-type` = `user-item`.`notification-type`")) {
750                 return Update::FAILED;
751         }
752
753         if (!DBStructure::existsTable('thread')) {
754                 return Update::SUCCESS;
755         }
756
757         if (!DBA::e("INSERT IGNORE INTO `post-thread-user`(`uri-id`, `uid`, `pinned`, `starred`, `ignored`, `wall`, `pubmail`, `forum_mode`)
758                 SELECT `thread`.`uri-id`, `thread`.`uid`, `user-item`.`pinned`, `thread`.`starred`,
759                         `thread`.`ignored`, `thread`.`wall`, `thread`.`pubmail`, `thread`.`forum_mode`
760                 FROM `thread` LEFT JOIN `user-item` ON `user-item`.`iid` = `thread`.`iid`")) {
761                 return Update::FAILED;
762         }
763
764         return Update::SUCCESS;
765 }
766
767 function update_1398()
768 {
769         if (!DBStructure::existsTable('thread')) {
770                 return Update::SUCCESS;
771         }
772
773         if (!DBA::e("INSERT IGNORE INTO `post-thread` (`uri-id`, `owner-id`, `author-id`, `network`, `created`, `received`, `changed`, `commented`)
774                 SELECT `uri-id`, `owner-id`, `author-id`, `network`, `created`, `received`, `changed`, `commented` FROM `thread`")) {
775                         return Update::FAILED;
776         }
777
778         if (!DBStructure::existsTable('thread')) {
779                 return Update::SUCCESS;
780         }
781
782         if (!DBA::e("UPDATE `post-thread-user` INNER JOIN `thread` ON `thread`.`uid` = `post-thread-user`.`uid` AND `thread`.`uri-id` = `post-thread-user`.`uri-id`
783                 SET `post-thread-user`.`mention` = `thread`.`mention`")) {
784                         return Update::FAILED;
785         }
786
787         return Update::SUCCESS;
788 }
789
790 function update_1399()
791 {
792         if (!DBA::e("UPDATE `post-thread-user` INNER JOIN `post-user` ON `post-user`.`uid` = `post-thread-user`.`uid` AND `post-user`.`uri-id` = `post-thread-user`.`uri-id`
793                 SET `post-thread-user`.`contact-id` = `post-user`.`contact-id`, `post-thread-user`.`unseen` = `post-user`.`unseen`,
794                 `post-thread-user`.`hidden` = `post-user`.`hidden`, `post-thread-user`.`origin` = `post-user`.`origin`,
795                 `post-thread-user`.`psid` = `post-user`.`psid`, `post-thread-user`.`post-user-id` = `post-user`.`id`")) {
796                         return Update::FAILED;
797         }
798
799         return Update::SUCCESS;
800 }
801
802 function update_1400()
803 {
804         if (!DBA::e("INSERT IGNORE INTO `post` (`uri-id`, `parent-uri-id`, `thr-parent-id`, `owner-id`, `author-id`, `network`,
805                 `created`, `received`, `edited`, `gravity`, `causer-id`, `post-type`, `vid`, `private`, `visible`, `deleted`, `global`)
806                 SELECT `uri-id`, `parent-uri-id`, `thr-parent-id`, `owner-id`, `author-id`, `network`, `created`, `received`, `edited`,
807                         `gravity`, `causer-id`, `post-type`, `vid`, `private`, `visible`, `deleted`, `global` FROM `item`")) {
808                         return Update::FAILED;
809         }
810
811         if (!DBA::e("UPDATE `post-user` INNER JOIN `item` ON `item`.`uri-id` = `post-user`.`uri-id` AND `item`.`uid` = `post-user`.`uid`
812                 INNER JOIN `event` ON `item`.`event-id` = `event`.`id` AND `event`.`id` != 0
813                 SET `post-user`.`event-id` = `item`.`event-id`")) {
814                 return Update::FAILED;
815         }
816
817         if (!DBA::e("UPDATE `post-user` INNER JOIN `item` ON `item`.`uri-id` = `post-user`.`uri-id` AND `item`.`uid` = `post-user`.`uid`
818                 SET `post-user`.`wall` = `item`.`wall`, `post-user`.`parent-uri-id` = `item`.`parent-uri-id`,
819                 `post-user`.`thr-parent-id` = `item`.`thr-parent-id`,
820                 `post-user`.`created` = `item`.`created`, `post-user`.`edited` = `item`.`edited`,
821                 `post-user`.`received` = `item`.`received`, `post-user`.`gravity` = `item`.`gravity`,
822                 `post-user`.`network` = `item`.`network`, `post-user`.`owner-id` = `item`.`owner-id`,
823                 `post-user`.`author-id` = `item`.`author-id`, `post-user`.`causer-id` = `item`.`causer-id`,
824                 `post-user`.`post-type` = `item`.`post-type`, `post-user`.`vid` = `item`.`vid`,
825                 `post-user`.`private` = `item`.`private`, `post-user`.`global` = `item`.`global`,
826                 `post-user`.`visible` = `item`.`visible`, `post-user`.`deleted` = `item`.`deleted`")) {
827                 return Update::FAILED;
828         }
829
830         if (!DBA::e("INSERT IGNORE INTO `post-thread-user` (`uri-id`, `owner-id`, `author-id`, `causer-id`, `network`,
831                 `created`, `received`, `changed`, `commented`, `uid`,  `wall`, `contact-id`, `unseen`, `hidden`, `origin`, `psid`, `post-user-id`)
832                 SELECT `uri-id`, `owner-id`, `author-id`, `causer-id`, `network`, `created`, `received`, `received`, `received`,
833                         `uid`, `wall`, `contact-id`, `unseen`, `hidden`, `origin`, `psid`, `id`
834                 FROM `post-user` WHERE `gravity` = 0 AND NOT EXISTS(SELECT `uri-id` FROM `post-thread-user` WHERE `post-user-id` = `post-user`.id)")) {
835                 return Update::FAILED;
836         }
837
838         if (!DBA::e("UPDATE `post-thread-user` INNER JOIN `post-thread` ON `post-thread-user`.`uri-id` = `post-thread`.`uri-id`
839                 SET `post-thread-user`.`owner-id` = `post-thread`.`owner-id`, `post-thread-user`.`author-id` = `post-thread`.`author-id`,
840                 `post-thread-user`.`causer-id` = `post-thread`.`causer-id`, `post-thread-user`.`network` = `post-thread`.`network`,
841                 `post-thread-user`.`created` = `post-thread`.`created`, `post-thread-user`.`received` = `post-thread`.`received`,
842                 `post-thread-user`.`changed` = `post-thread`.`changed`, `post-thread-user`.`commented` = `post-thread`.`commented`")) {
843                 return Update::FAILED;
844         }
845
846         return Update::SUCCESS;
847 }
848
849 function pre_update_1403()
850 {
851         // Necessary before a primary key change
852         if (DBStructure::existsTable('parsed_url') && !DBA::e("DROP TABLE `parsed_url`")) {
853                 return Update::FAILED;
854         }
855
856         return Update::SUCCESS;
857 }
858
859 function update_1404()
860 {
861         $tasks = DBA::select('workerqueue', ['id', 'command', 'parameter'], ['command' => ['notifier', 'delivery', 'apdelivery', 'done' => false]]);
862         while ($task = DBA::fetch($tasks)) {
863                 $parameters = json_decode($task['parameter'], true);
864
865                 if (is_array($parameters) && count($parameters) && in_array($parameters[0], [Delivery::MAIL, Delivery::SUGGESTION, Delivery::REMOVAL, Delivery::RELOCATION])) {
866                         continue;
867                 }
868
869                 switch (strtolower($task['command'])) {
870                         case 'notifier':
871                                 if (count($parameters) == 3) {
872                                         continue 2;
873                                 }
874                                 $item = DBA::selectFirst('item', ['uid', 'uri-id'], ['id' => $parameters[1]]);
875                                 if (!DBA::isResult($item)) {
876                                         continue 2;
877                                 }
878
879                                 $parameters[1] = $item['uri-id'];
880                                 $parameters[2] = $item['uid'];
881                                 break;
882                         case 'delivery':
883                                 if (count($parameters) == 4) {
884                                         continue 2;
885                                 }
886                                 $item = DBA::selectFirst('item', ['uid', 'uri-id'], ['id' => $parameters[1]]);
887                                 if (!DBA::isResult($item)) {
888                                         continue 2;
889                                 }
890
891                                 $parameters[1] = $item['uri-id'];
892                                 $parameters[3] = $item['uid'];
893                                 break;
894                         case 'apdelivery':
895                                 if (count($parameters) == 6) {
896                                         continue 2;
897                                 }
898
899                                 if (empty($parameters[4])) {
900                                         $parameters[4] = [];
901                                 }
902
903                                 $item = DBA::selectFirst('item', ['uri-id'], ['id' => $parameters[1]]);
904                                 if (!DBA::isResult($item)) {
905                                         continue 2;
906                                 }
907
908                                 $parameters[5] = $item['uri-id'];
909                                 break;
910                         default:
911                                 continue 2;
912                 }
913                 DBA::update('workerqueue', ['parameter' => json_encode($parameters)], ['id' => $task['id']]);
914
915                 return Update::SUCCESS;
916         }
917 }
918
919 function update_1407()
920 {
921         if (!DBA::e("UPDATE `post` SET `causer-id` = NULL WHERE `causer-id` = 0")) {
922                 return Update::FAILED;
923         }
924         if (!DBA::e("UPDATE `post-user` SET `causer-id` = NULL WHERE `causer-id` = 0")) {
925                 return Update::FAILED;
926         }
927         if (!DBA::e("UPDATE `post-thread` SET `causer-id` = NULL WHERE `causer-id` = 0")) {
928                 return Update::FAILED;
929         }
930         if (!DBA::e("UPDATE `post-thread-user` SET `causer-id` = NULL WHERE `causer-id` = 0")) {
931                 return Update::FAILED;
932         }
933
934         return Update::SUCCESS;
935 }
936
937 function update_1413()
938 {
939         if (!DBA::e("UPDATE `post-user` SET `post-reason` = `post-type` WHERE `post-type` >= 64 and `post-type` <= 75")) {
940                 return Update::FAILED;
941         }
942 }
943
944 function update_1419()
945 {
946         $mails = DBA::select('mail', ['id', 'from-url', 'uri', 'parent-uri', 'guid'], [], ['order' => ['id']]);
947         while ($mail = DBA::fetch($mails)) {
948                 $fields = [];
949                 $fields['author-id'] = Contact::getIdForURL($mail['from-url'], 0, false);
950                 if (empty($fields['author-id'])) {
951                         continue;
952                 }
953
954                 $fields['uri-id']        = ItemURI::insert(['uri' => $mail['uri'], 'guid' => $mail['guid']]);
955                 $fields['parent-uri-id'] = ItemURI::getIdByURI($mail['parent-uri']);
956
957                 $reply = DBA::selectFirst('mail', ['uri', 'uri-id', 'guid'], ['parent-uri' => $mail['parent-uri'], 'reply' => false]);
958                 if (!empty($reply)) {
959                         $fields['thr-parent'] = $reply['uri'];
960                         if (!empty($reply['uri-id'])) {
961                                 $fields['thr-parent-id'] = $reply['uri-id'];
962                         } else {
963                                 $fields['thr-parent-id'] = ItemURI::insert(['uri' => $reply['uri'], 'guid' => $reply['guid']]);
964                         }
965                 }
966
967                 DBA::update('mail', $fields, ['id' => $mail['id']]);
968         }
969         return Update::SUCCESS;
970 }
971
972 function update_1429()
973 {
974         if (!DBA::e("UPDATE `contact` SET `uri-id` = null WHERE NOT `uri-id` IS NULL")) {
975                 return Update::FAILED;
976         }
977
978         if (DBStructure::existsTable('fcontact') && !DBA::e("UPDATE `fcontact` SET `uri-id` = null WHERE NOT `uri-id` IS NULL")) {
979                 return Update::FAILED;
980         }
981
982         if (!DBA::e("UPDATE `apcontact` SET `uri-id` = null WHERE NOT `uri-id` IS NULL")) {
983                 return Update::FAILED;
984         }
985
986         DI::keyValue()->set('post_update_version', 1423);
987
988         return Update::SUCCESS;
989 }
990
991 function update_1434()
992 {
993         $name = DI::config()->get('storage', 'name');
994
995         // In case of an empty config, set "Database" as default storage backend
996         if (empty($name)) {
997                 DI::config()->set('storage', 'name', DatabaseStorage::getName());
998         }
999
1000         // In case of a Using deprecated storage class value, set the right name for it
1001         if (stristr($name, 'Friendica\Model\Storage\\')) {
1002                 DI::config()->set('storage', 'name', substr($name, 24));
1003         }
1004
1005         return Update::SUCCESS;
1006 }
1007
1008 function update_1438()
1009 {
1010         DBA::update('photo', ['photo-type' => Photo::USER_AVATAR], ['profile' => true]);
1011         DBA::update('photo', ['photo-type' => Photo::CONTACT_AVATAR], ["NOT `profile` AND NOT `contact-id` IS NULL AND `contact-id` != ?", 0]);
1012         DBA::update('photo', ['photo-type' => Photo::DEFAULT], ["NOT `profile` AND (`contact-id` IS NULL OR `contact-id` = ?) AND `photo-type` IS NULL AND `album` != ?", 0, Photo::CONTACT_PHOTOS]);
1013 }
1014
1015 function update_1439()
1016 {
1017         if (!DBStructure::existsTable('fcontact')) {
1018                 return Update::SUCCESS;
1019         }
1020
1021         $intros = DBA::select('intro', ['id', 'fid'], ["NOT `fid` IS NULL AND `fid` != ?", 0]);
1022         while ($intro = DBA::fetch($intros)) {
1023                 $fcontact = DBA::selectFirst('fcontact', ['url'], ['id' => $intro['fid']]);
1024                 if (!empty($fcontact['url'])) {
1025                         $id = Contact::getIdForURL($fcontact['url']);
1026                         if (!empty($id)) {
1027                                 DBA::update('intro',['suggest-cid' => $id], ['id' => $intro['id']]);
1028                         }
1029                 }
1030         }
1031         DBA::close($intros);
1032
1033         return Update::SUCCESS;
1034 }
1035
1036 function update_1440()
1037 {
1038         // Fix wrong public permissionset
1039         DBA::p("UPDATE `profile_field` SET `psid` = ? WHERE psid IN (SELECT `id` FROM `permissionset` WHERE `id` != ? AND `allow_cid` = '' AND `allow_gid` = '' AND `deny_cid` = '' AND `deny_gid` = '')", PermissionSet::PUBLIC, PermissionSet::PUBLIC);
1040         DBA::delete('permissionset', ["`id` != ? AND `allow_cid` = '' AND `allow_gid` = '' AND `deny_cid` = '' AND `deny_gid` = ''", PermissionSet::PUBLIC]);
1041
1042         return Update::SUCCESS;
1043 }
1044
1045 function update_1441()
1046 {
1047         $languages = DI::l10n()->getAvailableLanguages();
1048
1049         $albums = [Photo::PROFILE_PHOTOS];
1050         foreach ($languages as $language) {
1051                 $albums[] = DI::l10n()->withLang($language)->t(Photo::PROFILE_PHOTOS);
1052         }
1053         $albums = array_unique($albums);
1054
1055         Photo::update(['photo-type' => Photo::USER_AVATAR], ['album' => $albums]);
1056
1057         return Update::SUCCESS;
1058 }
1059
1060 function update_1442()
1061 {
1062         // transform blocked intros into ignored intros
1063         DBA::update('intro', ['ignore' => 1, 'blocked' => 0], ['blocked' => 1]);
1064
1065         return Update::SUCCESS;
1066 }
1067
1068 /**
1069  * A bug in Contact\User::updateByContactUpdate prevented any update to the user-contact table since the rows have been
1070  * created in version 1435. This version fixes this bug but the user-contact rows are outdated, we need to regenerate
1071  * them.
1072  */
1073 function update_1444()
1074 {
1075         DBA::e('TRUNCATE TABLE `user-contact`');
1076
1077         $contacts = DBA::select('contact', [], ["`uid` != ?", 0]);
1078         while ($contact = DBA::fetch($contacts)) {
1079                 Contact\User::insertForContactArray($contact);
1080         }
1081
1082         return Update::SUCCESS;
1083 }
1084
1085 function update_1446()
1086 {
1087         $distributed_cache_driver_source = DI::config()->getCache()->getSource('system', 'distributed_cache_driver');
1088         $cache_driver_source = DI::config()->getCache()->getSource('system', 'cache_driver');
1089
1090         // In case the distributed cache driver is the default value, but the current cache driver isn't default,
1091         // we assume that the distributed cache driver should be the same as the current cache driver
1092         if ($distributed_cache_driver_source === Cache::SOURCE_STATIC && $cache_driver_source > Cache::SOURCE_STATIC) {
1093                 DI::config()->set('system', 'distributed_cache_driver', DI::config()->get('system', 'cache_driver'));
1094         }
1095
1096         return Update::SUCCESS;
1097 }
1098
1099 function update_1451()
1100 {
1101         DBA::update('user', ['account-type' => User::ACCOUNT_TYPE_COMMUNITY], ['page-flags' => [User::PAGE_FLAGS_COMMUNITY, User::PAGE_FLAGS_PRVGROUP]]);
1102         DBA::update('contact', ['contact-type' => Contact::TYPE_COMMUNITY], ["`forum` OR `prv`"]);
1103         DBA::update('contact', ['manually-approve' => true], ['prv' => true]);
1104
1105         return Update::SUCCESS;
1106 }
1107
1108 function update_1457()
1109 {
1110         $pinned = DBA::select('post-thread-user', ['uri-id', 'author-id'], ['pinned' => true]);
1111         while ($post = DBA::fetch($pinned)) {
1112                 Post\Collection::add($post['uri-id'], Post\Collection::FEATURED, $post['author-id']);
1113         }
1114         DBA::close($pinned);
1115
1116         return Update::SUCCESS;
1117 }
1118
1119 function update_1480()
1120 {
1121         DBA::update('contact', ['next-update' => DBA::NULL_DATETIME], ['network' => Protocol::FEDERATED]);
1122         DBA::update('post', ['deleted' => false], ["`uri-id` IN (SELECT `uri-id` FROM `post-user` WHERE NOT `deleted`)"]);
1123         return Update::SUCCESS;
1124 }
1125
1126 function update_1481()
1127 {
1128         DBA::e("UPDATE `post-collection` INNER JOIN `post` ON `post`.`uri-id` = `post-collection`.`uri-id` SET `post-collection`.`author-id` = `post`.`author-id` WHERE `post-collection`.`author-id` IS null");
1129         return Update::SUCCESS;
1130 }
1131
1132 function update_1491()
1133 {
1134         DBA::update('contact', ['remote_self' => Contact::MIRROR_OWN_POST], ['remote_self' => Contact::MIRROR_FORWARDED]);
1135         return Update::SUCCESS;
1136 }
1137
1138 function update_1497()
1139 {
1140         DBA::e("UPDATE `user` SET `last-activity` = DATE(`login_date`) WHERE `last-activity` IS NULL");
1141         return Update::SUCCESS;
1142 }
1143
1144 function update_1502()
1145 {
1146         DBA::e("UPDATE `pconfig` SET `cat` = 'calendar' WHERE `k` = 'first_day_of_week'");
1147         return Update::SUCCESS;
1148 }
1149
1150 function update_1505()
1151 {
1152         if (!DBStructure::existsTable('config')) {
1153                 return Update::SUCCESS;
1154         }
1155
1156         $conditions = [
1157                 "((`cat`  = ?) AND ((`k` LIKE ?) OR (`k` = ?) OR (`k` LIKE ?) OR (`k` = ?))) OR " .
1158                 "((`cat` != ?) AND  (`k` LIKE ?)) OR " .
1159                 "((`cat`  = ?) AND  (`k` LIKE ?))",
1160                 "system",
1161                 "post_update_%",
1162                 "worker_last_cleaned",
1163                 "last%",
1164                 "worker_daemon_mode",
1165                 "system",
1166                 "last_%",
1167                 "database",
1168                 "update_%",
1169         ];
1170
1171         $postUpdateEntries = DBA::selectToArray('config', ['cat', 'k', 'v'], $conditions);
1172
1173         foreach ($postUpdateEntries as $postUpdateEntry) {
1174                 if ($postUpdateEntry['cat'] === 'system') {
1175                         DI::keyValue()->set($postUpdateEntry['k'], $postUpdateEntry['v']);
1176                 } else {
1177                         DI::keyValue()->set(sprintf('%s_%s', $postUpdateEntry['cat'], $postUpdateEntry['k']), $postUpdateEntry['v']);
1178                 }
1179         }
1180
1181         return DBA::delete('config', $conditions) ? Update::SUCCESS : Update::FAILED;
1182 }
1183
1184 function update_1508()
1185 {
1186         $config = DBA::selectToArray('config');
1187
1188         $newConfig = DI::config()->beginTransaction();
1189
1190         foreach ($config as $entry) {
1191                 $newConfig->set($entry['cat'], $entry['k'], $entry['v']);
1192         }
1193
1194         $newConfig->commit();
1195
1196         return Update::SUCCESS;
1197 }
1198
1199 function update_1509()
1200 {
1201         $addons = DBA::selectToArray('addon');
1202
1203         $newConfig = DI::config()->beginTransaction();
1204
1205         foreach ($addons as $addon) {
1206                 $newConfig->set('addons', $addon['name'], [
1207                         'last_update' => $addon['timestamp'],
1208                         'admin' => (bool)$addon['plugin_admin'],
1209                 ]);
1210         }
1211
1212         $newConfig->commit();
1213
1214         return Update::SUCCESS;
1215 }
1216
1217 function update_1510()
1218 {
1219         $blocks = DBA::select('pconfig', ['uid', 'v'], ['cat' => 'blockem', 'k' => 'words']);
1220         while ($block = DBA::fetch($blocks)) {
1221                 foreach (explode(',', $block['v']) as $account) {
1222                         $id = Contact::getIdForURL(trim($account), 0, false);
1223                         if (empty($id)) {
1224                                 continue;
1225                         }
1226                         Contact\User::setCollapsed($id, $block['uid'], true);
1227                 }
1228         }
1229         return Update::SUCCESS;
1230 }
1231
1232 function update_1512()
1233 {
1234         DI::keyValue()->set('nodeinfo_total_users', DI::config()->get('nodeinfo', 'total_users'));
1235         DI::keyValue()->set('nodeinfo_active_users_halfyear', DI::config()->get('nodeinfo', 'active_users_halfyear'));
1236         DI::keyValue()->set('nodeinfo_active_users_monthly', DI::config()->get('nodeinfo', 'active_users_monthly'));
1237         DI::keyValue()->set('nodeinfo_active_users_weekly', DI::config()->get('nodeinfo', 'active_users_weekly'));
1238         DI::keyValue()->set('nodeinfo_local_posts', DI::config()->get('nodeinfo', 'local_posts'));
1239         DI::keyValue()->set('nodeinfo_local_comments', DI::config()->get('nodeinfo', 'local_comments'));
1240
1241         DI::config()->delete('nodeinfo', 'total_users');
1242         DI::config()->delete('nodeinfo', 'active_users_halfyear');
1243         DI::config()->delete('nodeinfo', 'active_users_monthly');
1244         DI::config()->delete('nodeinfo', 'active_users_weekly');
1245         DI::config()->delete('nodeinfo', 'local_posts');
1246         DI::config()->delete('nodeinfo', 'local_comments');
1247 }
1248
1249 function update_1513()
1250 {
1251         DI::keyValue()->set('git_friendica_version', DI::config()->get('system', 'git_friendica_version'));
1252         DI::keyValue()->set('twitter_application_name', DI::config()->get('twitter', 'application_name'));
1253
1254         DI::config()->delete('system', 'git_friendica_version');
1255         DI::config()->delete('twitter', 'application_name');
1256 }
1257
1258 function update_1514()
1259 {
1260         if (file_exists(dirname(__FILE__) . '/config/node.config.php')) {
1261
1262                 $transactionalConfig = DI::config()->beginTransaction();
1263                 $oldConfig = include dirname(__FILE__) . '/config/node.config.php';
1264
1265                 if (is_array($oldConfig)) {
1266                         $categories = array_keys($oldConfig);
1267
1268                         foreach ($categories as $category) {
1269                                 if (is_array($oldConfig[$category])) {
1270                                         $keys = array_keys($oldConfig[$category]);
1271
1272                                         foreach ($keys as $key) {
1273                                                 $transactionalConfig->set($category, $key, $oldConfig[$category][$key]);
1274                                         }
1275                                 }
1276                         }
1277                 }
1278
1279                 $transactionalConfig->commit();
1280
1281                 // Rename the node.config.php so it won't get used, but it isn't deleted.
1282                 if (rename(dirname(__FILE__) . '/config/node.config.php', dirname(__FILE__) . '/config/node.config.php.bak')) {
1283                         return Update::SUCCESS;
1284                 } else {
1285                         return Update::FAILED;
1286                 }
1287         }
1288
1289         return Update::SUCCESS;
1290 }
1291
1292 function update_1515()
1293 {
1294         DBA::update('verb', ['name' => Activity::READ], ['name' => 'https://www.w3.org/ns/activitystreams#read']);
1295         DBA::update('verb', ['name' => Activity::VIEW], ['name' => 'https://joinpeertube.org/view']);
1296         return Update::SUCCESS;
1297 }