mirror of
https://github.com/friendica/friendica
synced 2024-11-19 06:23:40 +00:00
383 lines
14 KiB
PHP
383 lines
14 KiB
PHP
<?php
|
|
/**
|
|
* @copyright Copyright (C) 2010-2023, 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\Module;
|
|
|
|
use Friendica\App;
|
|
use Friendica\BaseModule;
|
|
use Friendica\Core;
|
|
use Friendica\Core\Config\ValueObject\Cache;
|
|
use Friendica\Core\L10n;
|
|
use Friendica\Core\Renderer;
|
|
use Friendica\Core\Theme;
|
|
use Friendica\DI;
|
|
use Friendica\Network\HTTPException;
|
|
use Friendica\Util\BasePath;
|
|
use Friendica\Util\Profiler;
|
|
use Friendica\Util\Temporal;
|
|
use Psr\Log\LoggerInterface;
|
|
use GuzzleHttp\Psr7\Uri;
|
|
|
|
class Install extends BaseModule
|
|
{
|
|
/**
|
|
* Step one - System check
|
|
*/
|
|
const SYSTEM_CHECK = 1;
|
|
/**
|
|
* Step two - Base information
|
|
*/
|
|
const BASE_CONFIG = 2;
|
|
/**
|
|
* Step three - Database configuration
|
|
*/
|
|
const DATABASE_CONFIG = 3;
|
|
/**
|
|
* Step four - Adapt site settings
|
|
*/
|
|
const SITE_SETTINGS = 4;
|
|
/**
|
|
* Step five - All steps finished
|
|
*/
|
|
const FINISHED = 5;
|
|
|
|
/**
|
|
* @var int The current step of the wizard
|
|
*/
|
|
private $currentWizardStep;
|
|
|
|
/**
|
|
* @var Core\Installer The installer
|
|
*/
|
|
private $installer;
|
|
|
|
/** @var App */
|
|
protected $app;
|
|
/** @var App\Mode */
|
|
protected $mode;
|
|
|
|
public function __construct(App $app, BasePath $basePath, App\Mode $mode, L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, Core\Installer $installer, array $server, array $parameters = [])
|
|
{
|
|
parent::__construct($l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
|
|
|
|
$this->app = $app;
|
|
$this->mode = $mode;
|
|
$this->installer = $installer;
|
|
|
|
if (!$this->mode->isInstall()) {
|
|
throw new HTTPException\ForbiddenException();
|
|
}
|
|
|
|
// route: install/testrwrite
|
|
// $baseurl/install/testrwrite to test if rewrite in .htaccess is working
|
|
if ($args->get(1, '') == 'testrewrite') {
|
|
// Status Code 204 means that it worked without content
|
|
throw new HTTPException\NoContentException();
|
|
}
|
|
|
|
// get basic installation information and save them to the config cache
|
|
$configCache = $this->app->getConfigCache();
|
|
$this->installer->setUpCache($configCache, $basePath->getPath());
|
|
|
|
// We overwrite current theme css, because during install we may not have a working mod_rewrite
|
|
// so we may not have a css at all. Here we set a static css file for the install procedure pages
|
|
Renderer::$theme['stylesheet'] = $this->baseUrl . '/view/install/style.css';
|
|
|
|
$this->currentWizardStep = ($_POST['pass'] ?? '') ?: self::SYSTEM_CHECK;
|
|
}
|
|
|
|
protected function post(array $request = [])
|
|
{
|
|
$configCache = $this->app->getConfigCache();
|
|
|
|
switch ($this->currentWizardStep) {
|
|
case self::SYSTEM_CHECK:
|
|
case self::BASE_CONFIG:
|
|
$this->checkSetting($configCache, $_POST, 'config', 'php_path');
|
|
break;
|
|
|
|
case self::DATABASE_CONFIG:
|
|
$this->checkSetting($configCache, $_POST, 'config', 'php_path');
|
|
|
|
$this->checkSetting($configCache, $_POST, 'system', 'basepath');
|
|
$this->checkSetting($configCache, $_POST, 'system', 'url');
|
|
break;
|
|
|
|
case self::SITE_SETTINGS:
|
|
$this->checkSetting($configCache, $_POST, 'config', 'php_path');
|
|
|
|
$this->checkSetting($configCache, $_POST, 'system', 'basepath');
|
|
$this->checkSetting($configCache, $_POST, 'system', 'url');
|
|
|
|
$this->checkSetting($configCache, $_POST, 'database', 'hostname', Core\Installer::DEFAULT_HOST);
|
|
$this->checkSetting($configCache, $_POST, 'database', 'username', '');
|
|
$this->checkSetting($configCache, $_POST, 'database', 'password', '');
|
|
$this->checkSetting($configCache, $_POST, 'database', 'database', '');
|
|
|
|
// If we cannot connect to the database, return to the previous step
|
|
if (!$this->installer->checkDB(DI::dba())) {
|
|
$this->currentWizardStep = self::DATABASE_CONFIG;
|
|
}
|
|
|
|
break;
|
|
|
|
case self::FINISHED:
|
|
$this->checkSetting($configCache, $_POST, 'config', 'php_path');
|
|
|
|
$this->checkSetting($configCache, $_POST, 'system', 'basepath');
|
|
$this->checkSetting($configCache, $_POST, 'system', 'url');
|
|
|
|
$this->checkSetting($configCache, $_POST, 'database', 'hostname', Core\Installer::DEFAULT_HOST);
|
|
$this->checkSetting($configCache, $_POST, 'database', 'username', '');
|
|
$this->checkSetting($configCache, $_POST, 'database', 'password', '');
|
|
$this->checkSetting($configCache, $_POST, 'database', 'database', '');
|
|
|
|
$this->checkSetting($configCache, $_POST, 'system', 'default_timezone', Core\Installer::DEFAULT_TZ);
|
|
$this->checkSetting($configCache, $_POST, 'system', 'language', Core\Installer::DEFAULT_LANG);
|
|
$this->checkSetting($configCache, $_POST, 'config', 'admin_email', '');
|
|
|
|
// If we cannot connect to the database, return to the Database config wizard
|
|
if (!$this->installer->checkDB(DI::dba())) {
|
|
$this->currentWizardStep = self::DATABASE_CONFIG;
|
|
return;
|
|
}
|
|
|
|
if (!$this->installer->createConfig($configCache)) {
|
|
return;
|
|
}
|
|
|
|
$this->installer->installDatabase();
|
|
|
|
// install allowed themes to register theme hooks
|
|
// this is same as "Reload active theme" in /admin/themes
|
|
$allowed_themes = Theme::getAllowedList();
|
|
$allowed_themes = array_unique($allowed_themes);
|
|
foreach ($allowed_themes as $theme) {
|
|
Theme::uninstall($theme);
|
|
Theme::install($theme);
|
|
}
|
|
Theme::setAllowedList($allowed_themes);
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
protected function content(array $request = []): string
|
|
{
|
|
$configCache = $this->app->getConfigCache();
|
|
|
|
$output = '';
|
|
|
|
$install_title = $this->t('Friendica Communications Server - Setup');
|
|
|
|
switch ($this->currentWizardStep) {
|
|
case self::SYSTEM_CHECK:
|
|
$php_path = $configCache->get('config', 'php_path');
|
|
|
|
$status = $this->installer->checkEnvironment($this->baseUrl, $php_path);
|
|
|
|
$tpl = Renderer::getMarkupTemplate('install/01_checks.tpl');
|
|
$output .= Renderer::replaceMacros($tpl, [
|
|
'$title' => $install_title,
|
|
'$pass' => $this->t('System check'),
|
|
'$required' => $this->t('Required'),
|
|
'$requirement_not_satisfied' => $this->t('Requirement not satisfied'),
|
|
'$optional_requirement_not_satisfied' => $this->t('Optional requirement not satisfied'),
|
|
'$ok' => $this->t('OK'),
|
|
'$checks' => $this->installer->getChecks(),
|
|
'$passed' => $status,
|
|
'$see_install' => $this->t('Please see the file "doc/INSTALL.md".'),
|
|
'$next' => $this->t('Next'),
|
|
'$reload' => $this->t('Check again'),
|
|
'$php_path' => $php_path,
|
|
]);
|
|
break;
|
|
|
|
case self::BASE_CONFIG:
|
|
$baseUrl = $configCache->get('system', 'url') ?
|
|
new Uri($configCache->get('system', 'url')) :
|
|
$this->baseUrl;
|
|
|
|
$tpl = Renderer::getMarkupTemplate('install/02_base_config.tpl');
|
|
$output .= Renderer::replaceMacros($tpl, [
|
|
'$title' => $install_title,
|
|
'$pass' => $this->t('Base settings'),
|
|
'$basepath' => ['system-basepath',
|
|
$this->t("Base path to installation"),
|
|
$configCache->get('system', 'basepath'),
|
|
$this->t("If the system cannot detect the correct path to your installation, enter the correct path here. This setting should only be set if you are using a restricted system and symbolic links to your webroot."),
|
|
$this->t('Required')],
|
|
'$system_url' => ['system-url',
|
|
$this->t('The Friendica system URL'),
|
|
(string)$baseUrl,
|
|
$this->t("Overwrite this field in case the system URL determination isn't right, otherwise leave it as is."),
|
|
$this->t('Required')],
|
|
'$php_path' => $configCache->get('config', 'php_path'),
|
|
'$submit' => $this->t('Submit'),
|
|
]);
|
|
break;
|
|
|
|
case self::DATABASE_CONFIG:
|
|
$tpl = Renderer::getMarkupTemplate('install/03_database_config.tpl');
|
|
$output .= Renderer::replaceMacros($tpl, [
|
|
'$title' => $install_title,
|
|
'$pass' => $this->t('Database connection'),
|
|
'$info_01' => $this->t('In order to install Friendica we need to know how to connect to your database.'),
|
|
'$info_02' => $this->t('Please contact your hosting provider or site administrator if you have questions about these settings.'),
|
|
'$info_03' => $this->t('The database you specify below should already exist. If it does not, please create it before continuing.'),
|
|
'$required' => $this->t('Required'),
|
|
'$requirement_not_satisfied' => $this->t('Requirement not satisfied'),
|
|
'$checks' => $this->installer->getChecks(),
|
|
'$basepath' => $configCache->get('system', 'basepath'),
|
|
'$system_url' => $configCache->get('system', 'url'),
|
|
'$dbhost' => ['database-hostname',
|
|
$this->t('Database Server Name'),
|
|
$configCache->get('database', 'hostname'),
|
|
'',
|
|
$this->t('Required')],
|
|
'$dbuser' => ['database-username',
|
|
$this->t('Database Login Name'),
|
|
$configCache->get('database', 'username'),
|
|
'',
|
|
$this->t('Required'),
|
|
'autofocus'],
|
|
'$dbpass' => ['database-password',
|
|
$this->t('Database Login Password'),
|
|
$configCache->get('database', 'password'),
|
|
$this->t("For security reasons the password must not be empty"),
|
|
$this->t('Required')],
|
|
'$dbdata' => ['database-database',
|
|
$this->t('Database Name'),
|
|
$configCache->get('database', 'database'),
|
|
'',
|
|
$this->t('Required')],
|
|
'$lbl_10' => $this->t('Please select a default timezone for your website'),
|
|
'$php_path' => $configCache->get('config', 'php_path'),
|
|
'$submit' => $this->t('Submit')
|
|
]);
|
|
break;
|
|
|
|
case self::SITE_SETTINGS:
|
|
/* Installed langs */
|
|
$lang_choices = $this->l10n->getAvailableLanguages();
|
|
|
|
$tpl = Renderer::getMarkupTemplate('install/04_site_settings.tpl');
|
|
$output .= Renderer::replaceMacros($tpl, [
|
|
'$title' => $install_title,
|
|
'$required' => $this->t('Required'),
|
|
'$checks' => $this->installer->getChecks(),
|
|
'$pass' => $this->t('Site settings'),
|
|
'$basepath' => $configCache->get('system', 'basepath'),
|
|
'$system_url' => $configCache->get('system', 'url'),
|
|
'$dbhost' => $configCache->get('database', 'hostname'),
|
|
'$dbuser' => $configCache->get('database', 'username'),
|
|
'$dbpass' => $configCache->get('database', 'password'),
|
|
'$dbdata' => $configCache->get('database', 'database'),
|
|
'$adminmail' => ['config-admin_email',
|
|
$this->t('Site administrator email address'),
|
|
$configCache->get('config', 'admin_email'),
|
|
$this->t('Your account email address must match this in order to use the web admin panel.'),
|
|
$this->t('Required'), 'autofocus', 'email'],
|
|
'$timezone' => Temporal::getTimezoneField('system-default_timezone',
|
|
$this->t('Please select a default timezone for your website'),
|
|
$configCache->get('system', 'default_timezone'),
|
|
''),
|
|
'$language' => ['system-language',
|
|
$this->t('System Language:'),
|
|
$configCache->get('system', 'language'),
|
|
$this->t('Set the default language for your Friendica installation interface and to send emails.'),
|
|
$lang_choices],
|
|
'$php_path' => $configCache->get('config', 'php_path'),
|
|
'$submit' => $this->t('Submit')
|
|
]);
|
|
break;
|
|
|
|
case self::FINISHED:
|
|
$db_return_text = "";
|
|
|
|
if (count($this->installer->getChecks()) == 0) {
|
|
$txt = '<p style="font-size: 130%;">';
|
|
$txt .= $this->t('Your Friendica site database has been installed.') . '<br />';
|
|
$db_return_text .= $txt;
|
|
}
|
|
|
|
$tpl = Renderer::getMarkupTemplate('install/05_finished.tpl');
|
|
$output .= Renderer::replaceMacros($tpl, [
|
|
'$title' => $install_title,
|
|
'$required' => $this->t('Required'),
|
|
'$requirement_not_satisfied' => $this->t('Requirement not satisfied'),
|
|
'$checks' => $this->installer->getChecks(),
|
|
'$pass' => $this->t('Installation finished'),
|
|
'$text' => $db_return_text . $this->whatNext(),
|
|
]);
|
|
|
|
break;
|
|
}
|
|
|
|
return $output;
|
|
}
|
|
|
|
/**
|
|
* Creates the text for the next steps
|
|
*
|
|
* @return string The text for the next steps
|
|
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
|
*/
|
|
private function whatNext(): string
|
|
{
|
|
$baseurl = (string)$this->baseUrl;
|
|
return
|
|
$this->t('<h1>What next</h1>')
|
|
. "<p>" . $this->t('IMPORTANT: You will need to [manually] setup a scheduled task for the worker.')
|
|
. $this->t('Please see the file "doc/INSTALL.md".')
|
|
. "</p><p>"
|
|
. $this->t('Go to your new Friendica node <a href="%s/register">registration page</a> and register as new user. Remember to use the same email you have entered as administrator email. This will allow you to enter the site admin panel.', $baseurl)
|
|
. "</p>";
|
|
}
|
|
|
|
/**
|
|
* Checks the $_POST settings and updates the config Cache for it
|
|
*
|
|
* @param \Friendica\Core\Config\ValueObject\Cache $configCache The current config cache
|
|
* @param array $post The $_POST data
|
|
* @param string $cat The category of the setting
|
|
* @param string $key The key of the setting
|
|
* @param null|string $default The default value
|
|
* @return void
|
|
*/
|
|
private function checkSetting(Cache $configCache, array $post, string $cat, string $key, ?string $default = null)
|
|
{
|
|
$value = null;
|
|
|
|
if (isset($post[sprintf('%s-%s', $cat, $key)])) {
|
|
$value = trim($post[sprintf('%s-%s', $cat, $key)]);
|
|
}
|
|
|
|
if (isset($value)) {
|
|
$configCache->set($cat, $key, $value, Cache::SOURCE_ENV);
|
|
return;
|
|
}
|
|
|
|
if (isset($default)) {
|
|
$configCache->set($cat, $key, $default, Cache::SOURCE_ENV);
|
|
}
|
|
}
|
|
}
|