]> git.mxchange.org Git - friendica.git/blob - src/Console/Relocate.php
spelling: unable
[friendica.git] / src / Console / Relocate.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  */
21
22 namespace Friendica\Console;
23
24 use Asika\SimpleConsole\Console;
25 use Friendica\Core\Config\Capability\IManageConfigValues;
26 use Friendica\Core\Worker;
27 use Friendica\Protocol\Delivery;
28 use Friendica\Util\Strings;
29
30 class Relocate extends Console
31 {
32         protected $helpOptions = ['h', 'help', '?'];
33
34         /**
35          * @var IManageConfigValues
36          */
37         private $config;
38         /**
39          * @var \Friendica\App\BaseURL
40          */
41         private $baseUrl;
42         /**
43          * @var \Friendica\Database\Database
44          */
45         private $database;
46
47         protected function getHelp()
48         {
49                 $help = <<<HELP
50 console relocate - Update the node base URL
51 Usage
52     bin/console relocate <new base URL> [-h|--help|-?] [-v]
53
54 Description
55     Warning! Advanced function. Could make this server unreachable.
56
57     Change the base URL for this server. Sends relocation message to all the Friendica and Diaspora* contacts of all local users.
58     This process updates all the database fields that may contain a URL pointing at the current domain, as a result it takes
59     a while and the node will be in maintenance mode for the whole duration.
60
61 Options
62     -h|--help|-? Show help information
63     -v           Show more debug information.
64 HELP;
65                 return $help;
66         }
67
68         public function __construct(\Friendica\App\BaseURL $baseUrl, \Friendica\Database\Database $database, IManageConfigValues $config, $argv = null)
69         {
70                 parent::__construct($argv);
71
72                 $this->baseUrl  = $baseUrl;
73                 $this->database = $database;
74                 $this->config   = $config;
75         }
76
77         protected function doExecute(): int
78         {
79                 if (count($this->args) == 0) {
80                         $this->out($this->getHelp());
81                         return 0;
82                 }
83
84                 if (count($this->args) > 1) {
85                         throw new \Asika\SimpleConsole\CommandArgsException('Too many arguments');
86                 }
87
88                 $new_url = rtrim($this->getArgument(0), '/');
89
90                 $parsed = @parse_url($new_url);
91                 if (!is_array($parsed) || empty($parsed['host']) || empty($parsed['scheme'])) {
92                         throw new \InvalidArgumentException('Can not parse new base URL. Must have at least <scheme>://<domain>');
93                 }
94
95                 $this->out(sprintf('Relocation started from %s to %s. Could take a while to complete.', $this->baseUrl, $this->getArgument(0)));
96
97                 $old_url = $this->baseUrl;
98
99                 // Generate host names for relocation the addresses in the format user@address.tld
100                 $new_host = str_replace('http://', '@', Strings::normaliseLink($new_url));
101                 $old_host = str_replace('http://', '@', Strings::normaliseLink($old_url));
102
103                 $this->out('Entering maintenance mode');
104                 $this->config->beginTransaction()
105                                          ->set('system', 'maintenance', true)
106                                          ->set('system', 'maintenance_reason', 'Relocating node to ' . $new_url)
107                                          ->commit();
108                 try {
109                         if (!$this->database->transaction()) {
110                                 throw new \Exception('Unable to start a transaction, please retry later.');
111                         }
112
113                         // update tables
114                         $this->out('Updating apcontact table fields');
115                         $this->database->replaceInTableFields('apcontact', ['url', 'inbox', 'outbox', 'sharedinbox', 'photo', 'header', 'alias', 'subscribe', 'baseurl'], $old_url, $new_url);
116                         $this->database->replaceInTableFields('apcontact', ['addr'], $old_host, $new_host);
117
118                         $this->out('Updating contact table fields');
119                         $this->database->replaceInTableFields('contact', ['photo', 'thumb', 'micro', 'url', 'alias', 'request', 'batch', 'notify', 'poll', 'subscribe', 'baseurl', 'confirm', 'poco', 'avatar', 'header'], $old_url, $new_url);
120                         $this->database->replaceInTableFields('contact', ['nurl'], Strings::normaliseLink($old_url), Strings::normaliseLink($new_url));
121                         $this->database->replaceInTableFields('contact', ['addr'], $old_host, $new_host);
122
123                         $this->out('Updating conv table fields');
124                         $this->database->replaceInTableFields('conv', ['creator', 'recips'], $old_host, $new_host);
125
126                         $this->out('Updating delayed-post table fields');
127                         $this->database->replaceInTableFields('delayed-post', ['uri'], $old_url, $new_url);
128
129                         $this->out('Updating endpoint table fields');
130                         $this->database->replaceInTableFields('endpoint', ['url'], $old_url, $new_url);
131
132                         $this->out('Updating event table fields');
133                         $this->database->replaceInTableFields('event', ['uri'], $old_url, $new_url);
134
135                         $this->out('Updating diaspora-contact table fields');
136                         $this->database->replaceInTableFields('diaspora-contact', ['alias', 'photo', 'photo-medium', 'photo-small', 'batch', 'notify', 'poll', 'subscribe'], $old_url, $new_url);
137                         $this->database->replaceInTableFields('diaspora-contact', ['addr'], $old_host, $new_host);
138
139                         $this->out('Updating fsuggest table fields');
140                         $this->database->replaceInTableFields('fsuggest', ['url', 'request', 'photo'], $old_url, $new_url);
141
142                         $this->out('Updating gserver table fields');
143                         $this->database->replaceInTableFields('gserver', ['url'], $old_url, $new_url);
144                         $this->database->replaceInTableFields('gserver', ['nurl'], Strings::normaliseLink($old_url), Strings::normaliseLink($new_url));
145
146                         $this->out('Updating inbox-status table fields');
147                         $this->database->replaceInTableFields('inbox-status', ['url'], $old_url, $new_url);
148
149                         $this->out('Updating item-uri table fields');
150                         $this->database->replaceInTableFields('item-uri', ['uri'], $old_url, $new_url);
151
152                         $this->out('Updating mail table fields');
153                         $this->database->replaceInTableFields('mail', ['from-photo', 'from-url', 'uri', 'thr-parent'], $old_url, $new_url);
154                         $this->database->replaceInTableFields('mail', ['parent-uri'], $old_host, $new_host);
155
156                         $this->out('Updating notify table fields');
157                         $this->database->replaceInTableFields('notify', ['url', 'photo', 'link', 'msg', 'name_cache', 'msg_cache'], $old_url, $new_url);
158
159                         $this->out('Updating profile table fields');
160                         $this->database->replaceInTableFields('profile', ['photo', 'thumb'], $old_url, $new_url);
161
162                         $this->out('Updating post-content table fields');
163                         $this->database->replaceInTableFields('post-content', ['body', 'raw-body', 'rendered-html', 'target', 'plink'], $old_url, $new_url);
164                         $this->database->replaceInTableFields('post-content', ['body', 'raw-body', 'rendered-html', 'target'], $old_host, $new_host);
165
166                         $this->out('Updating post-history table fields');
167                         $this->database->replaceInTableFields('post-history', ['body', 'raw-body', 'rendered-html', 'target', 'plink'], $old_url, $new_url);
168                         $this->database->replaceInTableFields('post-history', ['body', 'raw-body', 'rendered-html', 'target'], $old_host, $new_host);
169
170                         $this->out('Updating post-link table fields');
171                         $this->database->replaceInTableFields('post-link', ['url'], $old_url, $new_url);
172
173                         $this->out('Updating post-media table fields');
174                         $this->database->replaceInTableFields('post-media', ['url', 'preview', 'author-url', 'author-image', 'publisher-url', 'publisher-image'], $old_url, $new_url);
175
176                         $this->out('Updating tag table fields');
177                         $this->database->replaceInTableFields('tag', ['url'], $old_url, $new_url);
178
179                         // update config
180                         $this->out('Updating config values');
181                         $this->config->set('system', 'url', $new_url);
182
183                         $this->database->commit();
184                 } catch (\Throwable $e) {
185                         $this->database->rollback();
186
187                         $this->out('Process aborted with message: ' . $e->getMessage() . ' thrown in ' . $e->getFile() . ':' . $e->getLine());
188
189                         return 1;
190                 } finally {
191                         $this->out('Leaving maintenance mode');
192                         $this->config->beginTransaction()
193                                                  ->set('system', 'maintenance', false)
194                                                  ->delete('system', 'maintenance_reason')
195                                                  ->commit();
196                 }
197
198                 // send relocate
199                 $this->out('Schedule relocation messages to remote Friendica and Diaspora hosts');
200                 $users = $this->database->selectToArray('user', ['uid'], ['account_removed' => false, 'account_expired' => false]);
201                 foreach ($users as $user) {
202                         Worker::add(Worker::PRIORITY_HIGH, 'Notifier', Delivery::RELOCATION, $user['uid']);
203                 }
204
205                 return 0;
206         }
207 }