Move relocation feature in its separate class
- Create Database->replaceInTableFields method
This commit is contained in:
parent
697b8a6cb8
commit
7d09ce86c4
|
@ -0,0 +1,95 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (C) 2010-2022, the Friendica project
|
||||||
|
*
|
||||||
|
* @license GNU AGPL version 3 or any later version
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Friendica\Core;
|
||||||
|
|
||||||
|
use Friendica\App;
|
||||||
|
use Friendica\Database;
|
||||||
|
use Friendica\Util\Strings;
|
||||||
|
use Friendica\Worker\Delivery;
|
||||||
|
|
||||||
|
class Relocate
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var App\BaseURL
|
||||||
|
*/
|
||||||
|
private $baseUrl;
|
||||||
|
/**
|
||||||
|
* @var Database\Database
|
||||||
|
*/
|
||||||
|
private $database;
|
||||||
|
/**
|
||||||
|
* @var Config\Capability\IManageConfigValues
|
||||||
|
*/
|
||||||
|
private $config;
|
||||||
|
|
||||||
|
public function __construct(App\BaseURL $baseUrl, Database\Database $database, Config\Capability\IManageConfigValues $config)
|
||||||
|
{
|
||||||
|
$this->baseUrl = $baseUrl;
|
||||||
|
$this->database = $database;
|
||||||
|
$this->config = $config;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs relocation
|
||||||
|
*
|
||||||
|
* @param string $new_url The new node URL, including the scheme
|
||||||
|
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||||
|
*/
|
||||||
|
public function run(string $new_url)
|
||||||
|
{
|
||||||
|
$new_url = rtrim($new_url, '/');
|
||||||
|
|
||||||
|
$parsed = @parse_url($new_url);
|
||||||
|
if (!is_array($parsed) || empty($parsed['host']) || empty($parsed['scheme'])) {
|
||||||
|
throw new \InvalidArgumentException('Can not parse base URL. Must have at least <scheme>://<domain>');
|
||||||
|
}
|
||||||
|
|
||||||
|
/* steps:
|
||||||
|
* replace all "baseurl" to "new_url" in config, profile, term, items and contacts
|
||||||
|
* send relocate for every local user
|
||||||
|
* */
|
||||||
|
$old_url = $this->baseUrl->get(true);
|
||||||
|
|
||||||
|
// Generate host names for relocation the addresses in the format user@address.tld
|
||||||
|
$new_host = str_replace('http://', '@', Strings::normaliseLink($new_url));
|
||||||
|
$old_host = str_replace('http://', '@', Strings::normaliseLink($old_url));
|
||||||
|
|
||||||
|
// update tables
|
||||||
|
// update profile links in the format "http://server.tld"
|
||||||
|
$this->database->replaceInTableFields('profile', ['photo', 'thumb'], $old_url, $new_url);
|
||||||
|
$this->database->replaceInTableFields('contact', ['photo', 'thumb', 'micro', 'url', 'nurl', 'alias', 'request', 'notify', 'poll', 'confirm', 'poco', 'avatar'], $old_url, $new_url);
|
||||||
|
$this->database->replaceInTableFields('post-content', ['body'], $old_url, $new_url);
|
||||||
|
|
||||||
|
// update profile addresses in the format "user@server.tld"
|
||||||
|
$this->database->replaceInTableFields('contact', ['addr'], $old_host, $new_host);
|
||||||
|
|
||||||
|
// update config
|
||||||
|
$this->config->set('system', 'url', $new_url);
|
||||||
|
$this->baseUrl->saveByURL($new_url);
|
||||||
|
|
||||||
|
// send relocate
|
||||||
|
$users = $this->database->selectToArray('user', ['uid'], ['account_removed' => false, 'account_expired' => false]);
|
||||||
|
foreach ($users as $user) {
|
||||||
|
Worker::add(PRIORITY_HIGH, 'Notifier', Delivery::RELOCATION, $user['uid']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1790,4 +1790,32 @@ class Database
|
||||||
{
|
{
|
||||||
array_walk($arr, [$this, 'escapeArrayCallback'], $add_quotation);
|
array_walk($arr, [$this, 'escapeArrayCallback'], $add_quotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replaces a string in the provided fields of the provided table
|
||||||
|
*
|
||||||
|
* @param string $table_name
|
||||||
|
* @param array $fields List of field names in the provided table
|
||||||
|
* @param string $search
|
||||||
|
* @param string $replace
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
public function replaceInTableFields(string $table_name, array $fields, string $search, string $replace)
|
||||||
|
{
|
||||||
|
$search = $this->escape($search);
|
||||||
|
$replace = $this->escape($replace);
|
||||||
|
|
||||||
|
$upd = [];
|
||||||
|
foreach ($fields as $field) {
|
||||||
|
$field = DBA::quoteIdentifier($field);
|
||||||
|
$upd[] = "$field = REPLACE($field, '$search', '$replace')";
|
||||||
|
}
|
||||||
|
|
||||||
|
$upds = implode(', ', $upd);
|
||||||
|
|
||||||
|
$r = $this->e(sprintf("UPDATE %s SET %s;", $table_name, $upds));
|
||||||
|
if (!$this->isResult($r)) {
|
||||||
|
throw new \RuntimeException("Failed updating `$table_name`: " . $this->errorMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
namespace Friendica\Module\Admin;
|
namespace Friendica\Module\Admin;
|
||||||
|
|
||||||
use Friendica\App;
|
use Friendica\App;
|
||||||
|
use Friendica\Core\Relocate;
|
||||||
use Friendica\Core\Renderer;
|
use Friendica\Core\Renderer;
|
||||||
use Friendica\Core\Search;
|
use Friendica\Core\Search;
|
||||||
use Friendica\Core\System;
|
use Friendica\Core\System;
|
||||||
|
@ -60,70 +61,19 @@ class Site extends BaseAdmin
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// relocate
|
if (!empty($_POST['relocate']) && !empty($_POST['relocate_url'])) {
|
||||||
// @TODO This file could benefit from moving this feature away in a Module\Admin\Relocate class for example
|
try {
|
||||||
if (!empty($_POST['relocate']) && !empty($_POST['relocate_url']) && $_POST['relocate_url'] != "") {
|
$relocate = new Relocate(DI::baseUrl(), DI::dba(), DI::config());
|
||||||
$new_url = $_POST['relocate_url'];
|
$relocate->run($_POST['relocate_url']);
|
||||||
$new_url = rtrim($new_url, "/");
|
|
||||||
|
|
||||||
$parsed = @parse_url($new_url);
|
info(DI::l10n()->t('Relocation started. Could take a while to complete.'));
|
||||||
if (!is_array($parsed) || empty($parsed['host']) || empty($parsed['scheme'])) {
|
} catch (\InvalidArgumentException $e) {
|
||||||
notice(DI::l10n()->t("Can not parse base url. Must have at least <scheme>://<domain>"));
|
notice(DI::l10n()->t('Can not parse base url. Must have at least <scheme>://<domain>'));
|
||||||
DI::baseUrl()->redirect('admin/site');
|
} catch (\Throwable $e) {
|
||||||
|
notice(DI::l10n()->t('Unable to perform the relocation, please retry later or check the application logs.'));
|
||||||
|
notice($e->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* steps:
|
|
||||||
* replace all "baseurl" to "new_url" in config, profile, term, items and contacts
|
|
||||||
* send relocate for every local user
|
|
||||||
* */
|
|
||||||
|
|
||||||
$old_url = DI::baseUrl()->get(true);
|
|
||||||
|
|
||||||
// Generate host names for relocation the addresses in the format user@address.tld
|
|
||||||
$new_host = str_replace("http://", "@", Strings::normaliseLink($new_url));
|
|
||||||
$old_host = str_replace("http://", "@", Strings::normaliseLink($old_url));
|
|
||||||
|
|
||||||
function update_table(App $a, $table_name, $fields, $old_url, $new_url)
|
|
||||||
{
|
|
||||||
$dbold = DBA::escape($old_url);
|
|
||||||
$dbnew = DBA::escape($new_url);
|
|
||||||
|
|
||||||
$upd = [];
|
|
||||||
foreach ($fields as $f) {
|
|
||||||
$upd[] = "`$f` = REPLACE(`$f`, '$dbold', '$dbnew')";
|
|
||||||
}
|
|
||||||
|
|
||||||
$upds = implode(", ", $upd);
|
|
||||||
|
|
||||||
$r = DBA::e(sprintf("UPDATE %s SET %s;", $table_name, $upds));
|
|
||||||
if (!DBA::isResult($r)) {
|
|
||||||
notice("Failed updating '$table_name': " . DBA::errorMessage());
|
|
||||||
DI::baseUrl()->redirect('admin/site');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// update tables
|
|
||||||
// update profile links in the format "http://server.tld"
|
|
||||||
update_table($a, "profile", ['photo', 'thumb'], $old_url, $new_url);
|
|
||||||
update_table($a, "contact", ['photo', 'thumb', 'micro', 'url', 'nurl', 'alias', 'request', 'notify', 'poll', 'confirm', 'poco', 'avatar'], $old_url, $new_url);
|
|
||||||
update_table($a, "post-content", ['body'], $old_url, $new_url);
|
|
||||||
|
|
||||||
// update profile addresses in the format "user@server.tld"
|
|
||||||
update_table($a, "contact", ['addr'], $old_host, $new_host);
|
|
||||||
|
|
||||||
// update config
|
|
||||||
DI::config()->set('system', 'url', $new_url);
|
|
||||||
DI::baseUrl()->saveByURL($new_url);
|
|
||||||
|
|
||||||
// send relocate
|
|
||||||
$usersStmt = DBA::select('user', ['uid'], ['account_removed' => false, 'account_expired' => false]);
|
|
||||||
while ($user = DBA::fetch($usersStmt)) {
|
|
||||||
Worker::add(PRIORITY_HIGH, 'Notifier', Delivery::RELOCATION, $user['uid']);
|
|
||||||
}
|
|
||||||
DBA::close($usersStmt);
|
|
||||||
|
|
||||||
info(DI::l10n()->t("Relocation started. Could take a while to complete."));
|
|
||||||
|
|
||||||
DI::baseUrl()->redirect('admin/site');
|
DI::baseUrl()->redirect('admin/site');
|
||||||
}
|
}
|
||||||
// end relocate
|
// end relocate
|
||||||
|
|
Loading…
Reference in New Issue
Block a user