Merge pull request #7006 from nupplaphil/feature/install_enhancement

Adding basepath/url settings to the installer
This commit is contained in:
Hypolite Petovan 2019-04-14 09:20:19 -04:00 committed by GitHub
commit e0911efc87
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 573 additions and 298 deletions

View File

@ -144,9 +144,7 @@ if (!$foreground) {
file_put_contents($pidfile, $pid);
// We lose the database connection upon forking
/// @todo refactoring during https://github.com/friendica/friendica/issues/6720
$basePath = \Friendica\Util\BasePath::create(dirname(__DIR__), $_SERVER);
Factory\DBFactory::init($basePath, $a->getConfigCache(), $a->getProfiler(), $_SERVER);
Factory\DBFactory::init($a->getConfigCache(), $a->getProfiler(), $_SERVER);
}
Config::set('system', 'worker_daemon_mode', true);

View File

@ -1,41 +1,42 @@
<?php
// Local configuration
/* If automatic system installation fails:
*
* Copy this file to local.config.php
*
* Why local.config.php? Because it contains sensitive information which could
* give somebody complete control of your database. Apache's default
* configuration will interpret any .php file as a script and won't show the values
*
* Then set the following for your MySQL installation
*/
return [
'database' => [
'hostname' => 'localhost',
'username' => 'friendica',
'password' => 'friendica',
'database' => 'friendica',
'charset' => 'utf8mb4',
],
// ****************************************************************
// The configuration below will be overruled by the admin panel.
// Changes made below will only have an effect if the database does
// not contain any configuration for the friendica system.
// ****************************************************************
'config' => [
'admin_email' => 'admin@friendica.local',
'sitename' => 'Friendica Social Network',
'register_policy' => \Friendica\Module\Register::OPEN,
'register_text' => '',
],
'system' => [
'default_timezone' => 'UTC',
'language' => 'en',
],
];
<?php
// Local configuration
/* If automatic system installation fails:
*
* Copy this file to local.config.php
*
* Why local.config.php? Because it contains sensitive information which could
* give somebody complete control of your database. Apache's default
* configuration will interpret any .php file as a script and won't show the values
*
* Then set the following for your MySQL installation
*/
return [
'database' => [
'hostname' => 'localhost',
'username' => 'friendica',
'password' => 'friendica',
'database' => 'friendica',
'charset' => 'utf8mb4',
],
// ****************************************************************
// The configuration below will be overruled by the admin panel.
// Changes made below will only have an effect if the database does
// not contain any configuration for the friendica system.
// ****************************************************************
'config' => [
'admin_email' => 'admin@friendica.local',
'sitename' => 'Friendica Social Network',
'register_policy' => \Friendica\Module\Register::OPEN,
'register_text' => '',
],
'system' => [
'default_timezone' => 'UTC',
'language' => 'en',
'basepath' => '/vagrant',
],
];

View File

@ -138,6 +138,16 @@ class App
return $this->config->getCache();
}
/**
* Returns the current config of this node
*
* @return Configuration
*/
public function getConfig()
{
return $this->config;
}
/**
* The basepath of this app
*

View File

@ -15,6 +15,9 @@ use Friendica\Network\HTTPException\InternalServerErrorException;
*/
class BaseObject
{
/**
* @var App
*/
private static $app = null;
/**

View File

@ -7,6 +7,8 @@ use Friendica\BaseObject;
use Friendica\Core\Config;
use Friendica\Core\Installer;
use Friendica\Core\Theme;
use Friendica\Util\BasePath;
use Friendica\Util\BaseURL;
use Friendica\Util\Config\ConfigFileLoader;
use RuntimeException;
@ -30,17 +32,17 @@ Options
-v Show more debug information.
-a All setup checks are required (except .htaccess)
-f|--file <config> prepared config file (e.g. "config/local.config.php" itself) which will override every other config option - except the environment variables)
-s|--savedb Save the DB credentials to the file (if environment variables is used)
-H|--dbhost <host> The host of the mysql/mariadb database (env MYSQL_HOST)
-p|--dbport <port> The port of the mysql/mariadb database (env MYSQL_PORT)
-d|--dbdata <database> The name of the mysql/mariadb database (env MYSQL_DATABASE)
-U|--dbuser <username> The username of the mysql/mariadb database login (env MYSQL_USER or MYSQL_USERNAME)
-P|--dbpass <password> The password of the mysql/mariadb database login (env MYSQL_PASSWORD)
-u|--urlpath <url_path> The URL path of Friendica - f.e. '/friendica' (env FRIENDICA_URL_PATH)
-b|--phppath <php_path> The path of the PHP binary (env FRIENDICA_PHP_PATH)
-A|--admin <mail> The admin email address of Friendica (env FRIENDICA_ADMIN_MAIL)
-T|--tz <timezone> The timezone of Friendica (env FRIENDICA_TZ)
-L|--lang <language> The language of Friendica (env FRIENDICA_LANG)
-s|--savedb Save the DB credentials to the file (if environment variables is used)
-H|--dbhost <host> The host of the mysql/mariadb database (env MYSQL_HOST)
-p|--dbport <port> The port of the mysql/mariadb database (env MYSQL_PORT)
-d|--dbdata <database> The name of the mysql/mariadb database (env MYSQL_DATABASE)
-U|--dbuser <username> The username of the mysql/mariadb database login (env MYSQL_USER or MYSQL_USERNAME)
-P|--dbpass <password> The password of the mysql/mariadb database login (env MYSQL_PASSWORD)
-U|--url <url> The full base URL of Friendica - f.e. 'https://friendica.local/sub' (env FRIENDICA_URL)
-B|--phppath <php_path> The path of the PHP binary (env FRIENDICA_PHP_PATH)
-b|--basepath <base_path> The basepath of Friendica (env FRIENDICA_BASE_PATH)
-t|--tz <timezone> The timezone of Friendica (env FRIENDICA_TZ)
-L|--lang <language> The language of Friendica (env FRIENDICA_LANG)
Environment variables
MYSQL_HOST The host of the mysql/mariadb database (mandatory if mysql and environment is used)
@ -48,8 +50,9 @@ Environment variables
MYSQL_USERNAME|MYSQL_USER The username of the mysql/mariadb database login (MYSQL_USERNAME is for mysql, MYSQL_USER for mariadb)
MYSQL_PASSWORD The password of the mysql/mariadb database login
MYSQL_DATABASE The name of the mysql/mariadb database
FRIENDICA_URL_PATH The URL path of Friendica (f.e. '/friendica')
FRIENDICA_PHP_PATH The path of the PHP binary
FRIENDICA_URL The full base URL of Friendica - f.e. 'https://friendica.local/sub'
FRIENDICA_PHP_PATH The path of the PHP binary - leave empty for auto detection
FRIENDICA_BASE_PATH The basepath of Friendica - leave empty for auto detection
FRIENDICA_ADMIN_MAIL The admin email address of Friendica (this email will be used for admin access)
FRIENDICA_TZ The timezone of Friendica
FRIENDICA_LANG The langauge of Friendica
@ -76,6 +79,7 @@ HELP;
$installer = new Installer();
$configCache = $a->getConfigCache();
$installer->setUpCache($configCache, BasePath::create($a->getBasePath(), $_SERVER));
$this->out(" Complete!\n\n");
@ -99,7 +103,7 @@ HELP;
// Copy config file
$this->out("Copying config file...\n");
if (!copy($a->getBasePath() . DIRECTORY_SEPARATOR . $config_file, $a->getBasePath() . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'local.config.php')) {
throw new RuntimeException("ERROR: Saving config file failed. Please copy '$config_file' to '" . $a->getBasePath() . "'" . DIRECTORY_SEPARATOR . "config" . DIRECTORY_SEPARATOR . "local.config.php' manually.\n");
throw new RuntimeException("ERROR: Saving config file failed. Please copy '$config_file' to '" . $a->getBasePath() . "'" . DIRECTORY_SEPARATOR . "config" . DIRECTORY_SEPARATOR . "local.config.php' manually.\n");
}
}
@ -113,7 +117,6 @@ HELP;
$save_db = $this->getOption(['s', 'savedb'], false);
//$db_host = $this->getOption(['H', 'dbhost'], ($save_db) ? (getenv('MYSQL_HOST') ? getenv('MYSQL_HOST') : Installer::DEFAULT_HOST) : '');
$db_host = $this->getOption(['H', 'dbhost'], ($save_db) ? (getenv('MYSQL_HOST')) : Installer::DEFAULT_HOST);
$db_port = $this->getOption(['p', 'dbport'], ($save_db) ? getenv('MYSQL_PORT') : null);
$configCache->set('database', 'hostname', $db_host . (!empty($db_port) ? ':' . $db_port : ''));
@ -126,10 +129,14 @@ HELP;
$configCache->set('database', 'password',
$this->getOption(['P', 'dbpass'],
($save_db) ? getenv('MYSQL_PASSWORD') : ''));
$php_path = $this->getOption(['b', 'phppath'], !empty('FRIENDICA_PHP_PATH') ? getenv('FRIENDICA_PHP_PATH') : null);
if (!empty($php_path)) {
$configCache->set('config', 'php_path', $php_path);
} else {
$configCache->set('config', 'php_path', $installer->getPHPPath());
}
$configCache->set('config', 'admin_email',
$this->getOption(['A', 'admin'],
!empty(getenv('FRIENDICA_ADMIN_MAIL')) ? getenv('FRIENDICA_ADMIN_MAIL') : ''));
@ -140,16 +147,22 @@ HELP;
$this->getOption(['L', 'lang'],
!empty(getenv('FRIENDICA_LANG')) ? getenv('FRIENDICA_LANG') : Installer::DEFAULT_LANG));
if (empty($php_path)) {
$configCache->set('config', 'php_path', $installer->getPHPPath());
$basepath = $this->getOption(['b', 'basepath'], !empty(getenv('FRIENDICA_BASE_PATH')) ? getenv('FRIENDICA_BASE_PATH') : null);
if (!empty($basepath)) {
$configCache->set('system', 'basepath', $basepath);
}
$installer->createConfig(
$a,
$configCache,
$a->getBasePath()
);
$url = $this->getOption(['U', 'url'], !empty(getenv('FRIENDICA_URL')) ? getenv('FRIENDICA_URL') : null);
if (empty($url)) {
$this->out('The Friendica URL has to be set during CLI installation.');
return 1;
} else {
$baseUrl = new BaseURL($a->getConfig(), []);
$baseUrl->saveByURL($url);
}
$installer->createConfig($configCache);
}
$this->out(" Complete!\n\n");
@ -159,7 +172,7 @@ HELP;
$installer->resetChecks();
if (!$installer->checkDB($a->getBasePath(), $configCache, $a->getProfiler())) {
if (!$installer->checkDB($configCache, $a->getProfiler())) {
$errorMessage = $this->extractErrors($installer->getChecks());
throw new RuntimeException($errorMessage);
}
@ -220,10 +233,7 @@ HELP;
$checked = false;
}
$php_path = null;
if ($configCache->has('config', 'php_path')) {
$php_path = $configCache->get('config', 'php_path');
}
$php_path = $configCache->get('config', 'php_path');
if (!$installer->checkPHP($php_path, true)) {
$checked = false;

View File

@ -6,7 +6,6 @@ namespace Friendica\Core;
use DOMDocument;
use Exception;
use Friendica\App;
use Friendica\Core\Config\Cache\IConfigCache;
use Friendica\Database\DBA;
use Friendica\Database\DBStructure;
@ -131,15 +130,15 @@ class Installer
* - Creates `config/local.config.php`
* - Installs Database Structure
*
* @param App $app The Friendica App
* @param IConfigCache $configCache The config cache with all config relevant information
* @param string $basepath The basepath of Friendica
*
* @return bool true if the config was created, otherwise false
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
public function createConfig(App $app, IConfigCache $configCache, $basepath)
public function createConfig(IConfigCache $configCache)
{
$basepath = $configCache->get('system', 'basepath');
$tpl = Renderer::getMarkupTemplate('local.config.tpl');
$txt = Renderer::replaceMacros($tpl, [
'$dbhost' => $configCache->get('database', 'hostname'),
@ -147,13 +146,17 @@ class Installer
'$dbpass' => $configCache->get('database', 'password'),
'$dbdata' => $configCache->get('database', 'database'),
'$phpath' => $this->getPHPPath(),
'$phpath' => $configCache->get('config', 'php_path'),
'$adminmail' => $configCache->get('config', 'admin_email'),
'$hostname' => $configCache->get('config', 'hostname'),
'$urlpath' => $configCache->get('system', 'urlpath'),
'$baseurl' => $configCache->get('system', 'url'),
'$sslpolicy' => $configCache->get('system', 'ssl_policy'),
'$basepath' => $basepath,
'$timezone' => $configCache->get('system', 'default_timezone'),
'$language' => $configCache->get('system', 'language'),
'$urlpath' => $app->getURLPath(),
]);
], false);
$result = file_put_contents($basepath . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'local.config.php', $txt);
@ -243,8 +246,9 @@ class Installer
$help .= L10n::t("If you don't have a command line version of PHP installed on your server, you will not be able to run the background processing. See <a href='https://github.com/friendica/friendica/blob/master/doc/Install.md#set-up-the-worker'>'Setup the worker'</a>") . EOL;
$help .= EOL . EOL;
$tpl = Renderer::getMarkupTemplate('field_input.tpl');
/// @todo Separate backend Installer class and presentation layer/view
$help .= Renderer::replaceMacros($tpl, [
'$field' => ['phpath', L10n::t('PHP executable path'), $phppath, L10n::t('Enter full path to php executable. You can leave this blank to continue the installation.')],
'$field' => ['config-php_path', L10n::t('PHP executable path'), $phppath, L10n::t('Enter full path to php executable. You can leave this blank to continue the installation.')],
]);
$phppath = "";
}
@ -588,21 +592,20 @@ class Installer
/**
* Checking the Database connection and if it is available for the current installation
*
* @param string $basePath The basepath of this call
* @param IConfigCache $configCache The configuration cache
* @param Profiler $profiler The profiler of this app
*
* @return bool true if the check was successful, otherwise false
* @throws Exception
*/
public function checkDB($basePath, IConfigCache $configCache, Profiler $profiler)
public function checkDB(IConfigCache $configCache, Profiler $profiler)
{
$dbhost = $configCache->get('database', 'hostname');
$dbuser = $configCache->get('database', 'username');
$dbpass = $configCache->get('database', 'password');
$dbdata = $configCache->get('database', 'database');
if (!DBA::connect($basePath, $configCache, $profiler, new VoidLogger(), $dbhost, $dbuser, $dbpass, $dbdata)) {
if (!DBA::connect($configCache, $profiler, new VoidLogger(), $dbhost, $dbuser, $dbpass, $dbdata)) {
$this->addCheck(L10n::t('Could not connect to database.'), false, true, '');
return false;
@ -618,4 +621,18 @@ class Installer
return true;
}
/**
* Setup the default cache for a new installation
*
* @param IConfigCache $configCache The configuration cache
* @param string $basePath The determined basepath
*
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
public function setUpCache(IConfigCache $configCache, $basePath)
{
$configCache->set('config', 'php_path' , $this->getPHPPath());
$configCache->set('system', 'basepath' , $basePath);
}
}

View File

@ -15,17 +15,17 @@ use Friendica\Render\ITemplateEngine;
*/
class Renderer extends BaseObject
{
/**
/**
* @brief An array of registered template engines ('name'=>'class name')
*/
public static $template_engines = [];
public static $template_engines = [];
/**
/**
* @brief An array of instanced template engines ('name'=>'instance')
*/
public static $template_engine_instance = [];
/**
/**
* @brief An array for all theme-controllable parameters
*
* Mostly unimplemented yet. Only options 'template_engine' and
@ -39,45 +39,48 @@ class Renderer extends BaseObject
'stylesheet' => '',
'template_engine' => 'smarty3',
];
private static $ldelim = [
private static $ldelim = [
'internal' => '',
'smarty3' => '{{'
];
private static $rdelim = [
'internal' => '',
'smarty3' => '}}'
];
];
/**
* @brief This is our template processor
*
* @param string|FriendicaSmarty $s The string requiring macro substitution or an instance of FriendicaSmarty
* @param array $vars key value pairs (search => replace)
* @param string|FriendicaSmarty $s The string requiring macro substitution or an instance of FriendicaSmarty
* @param array $vars key value pairs (search => replace)
* @param bool $overwriteURL Overwrite the base url with the system wide set base url
*
* @return string substituted string
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
public static function replaceMacros($s, $vars)
{
$stamp1 = microtime(true);
$a = self::getApp();
public static function replaceMacros($s, $vars, $overwriteURL = true)
{
$stamp1 = microtime(true);
$a = self::getApp();
// pass $baseurl to all templates
$vars['$baseurl'] = System::baseUrl();
$t = self::getTemplateEngine();
// pass $baseurl to all templates
if ($overwriteURL) {
$vars['$baseurl'] = System::baseUrl();
}
$t = self::getTemplateEngine();
try {
$output = $t->replaceMacros($s, $vars);
} catch (Exception $e) {
echo "<pre><b>" . __FUNCTION__ . "</b>: " . $e->getMessage() . "</pre>";
exit();
}
try {
$output = $t->replaceMacros($s, $vars);
} catch (Exception $e) {
echo "<pre><b>" . __FUNCTION__ . "</b>: " . $e->getMessage() . "</pre>";
exit();
}
$a->getProfiler()->saveTimestamp($stamp1, "rendering", System::callstack());
return $output;
}
return $output;
}
/**
* @brief Load a given template $s
@ -88,35 +91,35 @@ class Renderer extends BaseObject
* @return string template.
* @throws Exception
*/
public static function getMarkupTemplate($s, $root = '')
{
$stamp1 = microtime(true);
$a = self::getApp();
$t = self::getTemplateEngine();
public static function getMarkupTemplate($s, $root = '')
{
$stamp1 = microtime(true);
$a = self::getApp();
$t = self::getTemplateEngine();
try {
$template = $t->getTemplateFile($s, $root);
} catch (Exception $e) {
echo "<pre><b>" . __FUNCTION__ . "</b>: " . $e->getMessage() . "</pre>";
exit();
}
try {
$template = $t->getTemplateFile($s, $root);
} catch (Exception $e) {
echo "<pre><b>" . __FUNCTION__ . "</b>: " . $e->getMessage() . "</pre>";
exit();
}
$a->getProfiler()->saveTimestamp($stamp1, "file", System::callstack());
$a->getProfiler()->saveTimestamp($stamp1, "file", System::callstack());
return $template;
}
return $template;
}
/**
/**
* @brief Register template engine class
*
* @param string $class
*/
public static function registerTemplateEngine($class)
{
$v = get_class_vars($class);
if (!empty($v['name']))
{
$v = get_class_vars($class);
if (!empty($v['name']))
{
$name = $v['name'];
self::$template_engines[$name] = $class;
} else {
@ -150,9 +153,9 @@ class Renderer extends BaseObject
echo "template engine <tt>$template_engine</tt> is not registered!\n";
exit();
}
/**
}
/**
* @brief Returns the active template engine.
*
* @return string the active template engine
@ -172,7 +175,7 @@ class Renderer extends BaseObject
self::$theme['template_engine'] = $engine;
}
/**
/**
* Gets the right delimiter for a template engine
*
* Currently:

View File

@ -44,10 +44,6 @@ class DBA
* @var LoggerInterface
*/
private static $logger;
/**
* @var string
*/
private static $basePath;
private static $server_info = '';
private static $connection;
private static $driver;
@ -63,14 +59,13 @@ class DBA
private static $db_name = '';
private static $db_charset = '';
public static function connect($basePath, IConfigCache $configCache, Profiler $profiler, LoggerInterface $logger, $serveraddr, $user, $pass, $db, $charset = null)
public static function connect(IConfigCache $configCache, Profiler $profiler, LoggerInterface $logger, $serveraddr, $user, $pass, $db, $charset = null)
{
if (!is_null(self::$connection) && self::connected()) {
return true;
}
// We are storing these values for being able to perform a reconnect
self::$basePath = $basePath;
self::$configCache = $configCache;
self::$profiler = $profiler;
self::$logger = $logger;
@ -189,7 +184,7 @@ class DBA
public static function reconnect() {
self::disconnect();
$ret = self::connect(self::$basePath, self::$configCache, self::$profiler, self::$logger, self::$db_serveraddr, self::$db_user, self::$db_pass, self::$db_name, self::$db_charset);
$ret = self::connect(self::$configCache, self::$profiler, self::$logger, self::$db_serveraddr, self::$db_user, self::$db_pass, self::$db_name, self::$db_charset);
return $ret;
}
@ -1079,7 +1074,7 @@ class DBA
* This process must only be started once, since the value is cached.
*/
private static function buildRelationData() {
$definition = DBStructure::definition(self::$basePath);
$definition = DBStructure::definition(self::$configCache->get('system', 'basepath'));
foreach ($definition AS $table => $structure) {
foreach ($structure['fields'] AS $field => $field_struct) {

View File

@ -12,16 +12,13 @@ class DBFactory
/**
* Initialize the DBA connection
*
* @param string $basePath The basepath of the application
* @param Cache\IConfigCache $configCache The configuration cache
* @param Profiler $profiler The profiler
* @param array $server The $_SERVER variables
*
* @throws \Exception if connection went bad
*
* @todo refactor basedir during https://github.com/friendica/friendica/issues/6720
*/
public static function init($basePath, Cache\IConfigCache $configCache, Profiler $profiler, array $server)
public static function init(Cache\IConfigCache $configCache, Profiler $profiler, array $server)
{
if (Database\DBA::connected()) {
return;
@ -52,9 +49,9 @@ class DBFactory
$db_data = $server['MYSQL_DATABASE'];
}
if (Database\DBA::connect($basePath, $configCache, $profiler, new VoidLogger(), $db_host, $db_user, $db_pass, $db_data, $charset)) {
if (Database\DBA::connect($configCache, $profiler, new VoidLogger(), $db_host, $db_user, $db_pass, $db_data, $charset)) {
// Loads DB_UPDATE_VERSION constant
Database\DBStructure::definition($basePath, false);
Database\DBStructure::definition($configCache->get('system', 'basepath'), false);
}
unset($db_host, $db_user, $db_pass, $db_data, $charset);

View File

@ -3,7 +3,6 @@
namespace Friendica\Factory;
use Friendica\App;
use Friendica\Database\DBA;
use Friendica\Factory;
use Friendica\Util\BasePath;
use Friendica\Util\BaseURL;
@ -30,12 +29,11 @@ class DependencyFactory
$configLoader = new Config\ConfigFileLoader($basePath, $mode);
$configCache = Factory\ConfigFactory::createCache($configLoader);
$profiler = Factory\ProfilerFactory::create($configCache);
Factory\DBFactory::init($basePath, $configCache, $profiler, $_SERVER);
Factory\DBFactory::init($configCache, $profiler, $_SERVER);
$config = Factory\ConfigFactory::createConfig($configCache);
// needed to call PConfig::init()
Factory\ConfigFactory::createPConfig($configCache);
$logger = Factory\LoggerFactory::create($channel, $config, $profiler);
DBA::setLogger($logger);
Factory\LoggerFactory::createDev($channel, $config, $profiler);
$baseURL = new BaseURL($config, $_SERVER);

View File

@ -8,6 +8,8 @@ use Friendica\Core;
use Friendica\Core\Config\Cache\IConfigCache;
use Friendica\Core\L10n;
use Friendica\Core\Renderer;
use Friendica\Util\BasePath;
use Friendica\Util\BaseURL;
use Friendica\Util\Strings;
use Friendica\Util\Temporal;
@ -18,17 +20,21 @@ class Install extends BaseModule
*/
const SYSTEM_CHECK = 1;
/**
* Step two - Database configuration
* Step two - Base information
*/
const DATABASE_CONFIG = 2;
const BASE_CONFIG = 2;
/**
* Step three - Adapat site settings
* Step three - Database configuration
*/
const SITE_SETTINGS = 3;
const DATABASE_CONFIG = 3;
/**
* Step four - All steps finished
* Step four - Adapt site settings
*/
const FINISHED = 4;
const SITE_SETTINGS = 4;
/**
* Step five - All steps finished
*/
const FINISHED = 5;
/**
* @var int The current step of the wizard
@ -55,11 +61,16 @@ class Install extends BaseModule
Core\System::httpExit(204);
}
self::$installer = new Core\Installer();
// get basic installation information and save them to the config cache
$configCache = $a->getConfigCache();
self::$installer->setUpCache($configCache, BasePath::create($a->getBasePath(), $_SERVER));
// 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'] = $a->getBaseURL() . '/view/install/style.css';
self::$installer = new Core\Installer();
self::$currentWizardStep = defaults($_POST, 'pass', self::SYSTEM_CHECK);
}
@ -70,20 +81,34 @@ class Install extends BaseModule
switch (self::$currentWizardStep) {
case self::SYSTEM_CHECK:
case self::BASE_CONFIG:
self::checkSetting($configCache, $_POST, 'config', 'php_path');
break;
case self::DATABASE_CONFIG:
self::checkSetting($configCache, $_POST, 'config', 'php_path');
self::checkSetting($configCache, $_POST, 'config', 'hostname');
self::checkSetting($configCache, $_POST, 'system', 'ssl_policy');
self::checkSetting($configCache, $_POST, 'system', 'basepath');
self::checkSetting($configCache, $_POST, 'system', 'urlpath');
break;
case self::SITE_SETTINGS:
self::checkSetting($configCache, $_POST, 'config', 'php_path');
self::checkSetting($configCache, $_POST, 'config', 'hostname');
self::checkSetting($configCache, $_POST, 'system', 'ssl_policy');
self::checkSetting($configCache, $_POST, 'system', 'basepath');
self::checkSetting($configCache, $_POST, 'system', 'urlpath');
self::checkSetting($configCache, $_POST, 'database', 'hostname', Core\Installer::DEFAULT_HOST);
self::checkSetting($configCache, $_POST, 'database', 'username', '');
self::checkSetting($configCache, $_POST, 'database', 'password', '');
self::checkSetting($configCache, $_POST, 'database', 'database', '');
// If we cannot connect to the database, return to the previous step
if (!self::$installer->checkDB($a->getBasePath(), $configCache, $a->getProfiler())) {
if (!self::$installer->checkDB($configCache, $a->getProfiler())) {
self::$currentWizardStep = self::DATABASE_CONFIG;
}
@ -92,6 +117,11 @@ class Install extends BaseModule
case self::FINISHED:
self::checkSetting($configCache, $_POST, 'config', 'php_path');
self::checkSetting($configCache, $_POST, 'config', 'hostname');
self::checkSetting($configCache, $_POST, 'system', 'ssl_policy');
self::checkSetting($configCache, $_POST, 'system', 'basepath');
self::checkSetting($configCache, $_POST, 'system', 'urlpath');
self::checkSetting($configCache, $_POST, 'database', 'hostname', Core\Installer::DEFAULT_HOST);
self::checkSetting($configCache, $_POST, 'database', 'username', '');
self::checkSetting($configCache, $_POST, 'database', 'password', '');
@ -102,16 +132,16 @@ class Install extends BaseModule
self::checkSetting($configCache, $_POST, 'config', 'admin_email', '');
// If we cannot connect to the database, return to the Database config wizard
if (!self::$installer->checkDB($a->getBasePath(), $configCache, $a->getProfiler())) {
if (!self::$installer->checkDB($configCache, $a->getProfiler())) {
self::$currentWizardStep = self::DATABASE_CONFIG;
return;
}
if (!self::$installer->createConfig($a, $configCache, $a->getBasePath())) {
if (!self::$installer->createConfig($configCache)) {
return;
}
self::$installer->installDatabase($a->getBasePath());
self::$installer->installDatabase($configCache->get('system', 'basepath'));
break;
}
@ -134,52 +164,93 @@ class Install extends BaseModule
$tpl = Renderer::getMarkupTemplate('install_checks.tpl');
$output .= Renderer::replaceMacros($tpl, [
'$title' => $install_title,
'$pass' => L10n::t('System check'),
'$checks' => self::$installer->getChecks(),
'$passed' => $status,
'$see_install' => L10n::t('Please see the file "INSTALL.txt".'),
'$next' => L10n::t('Next'),
'$reload' => L10n::t('Check again'),
'$php_path' => $php_path,
'$baseurl' => $a->getBaseURL()
'$title' => $install_title,
'$pass' => L10n::t('System check'),
'$checks' => self::$installer->getChecks(),
'$passed' => $status,
'$see_install' => L10n::t('Please see the file "INSTALL.txt".'),
'$next' => L10n::t('Next'),
'$reload' => L10n::t('Check again'),
'$php_path' => $php_path,
'$baseurl' => $a->getBaseURL()
]);
break;
case self::BASE_CONFIG:
$ssl_choices = [
BaseUrl::SSL_POLICY_NONE => L10n::t("No SSL policy, links will track page SSL state"),
BaseUrl::SSL_POLICY_FULL => L10n::t("Force all links to use SSL"),
BaseUrl::SSL_POLICY_SELFSIGN => L10n::t("Self-signed certificate, use SSL for local links only \x28discouraged\x29")
];
$tpl = Renderer::getMarkupTemplate('install_base.tpl');
$output .= Renderer::replaceMacros($tpl, [
'$title' => $install_title,
'$pass' => L10n::t('Base settings'),
'$ssl_policy' => ['system-ssl_policy',
L10n::t("SSL link policy"),
$configCache->get('system', 'ssl_policy'),
L10n::t("Determines whether generated links should be forced to use SSL"),
$ssl_choices],
'$hostname' => ['config-hostname',
L10n::t('Host name'),
$configCache->get('config', 'hostname'),
L10n::t('Overwrite this field in case the determinated hostname isn\'t right, otherweise leave it as is.'),
'required'],
'$basepath' => ['system-basepath',
L10n::t("Base path to installation"),
$configCache->get('system', 'basepath'),
L10n::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."),
'required'],
'$urlpath' => ['system-urlpath',
L10n::t('Sub path of the URL'),
$configCache->get('system', 'urlpath'),
L10n::t('Overwrite this field in case the sub path determination isn\'t right, otherwise leave it as is. Leaving this field blank means the installation is at the base URL without sub path.'),
''],
'$baseurl' => $a->getBaseURL(),
'$php_path' => $configCache->get('config', 'php_path'),
'$submit' => L10n::t('Submit'),
]);
break;
case self::DATABASE_CONFIG:
$tpl = Renderer::getMarkupTemplate('install_db.tpl');
$output .= Renderer::replaceMacros($tpl, [
'$title' => $install_title,
'$pass' => L10n::t('Database connection'),
'$info_01' => L10n::t('In order to install Friendica we need to know how to connect to your database.'),
'$info_02' => L10n::t('Please contact your hosting provider or site administrator if you have questions about these settings.'),
'$info_03' => L10n::t('The database you specify below should already exist. If it does not, please create it before continuing.'),
'checks' => self::$installer->getChecks(),
'$dbhost' => ['database-hostname',
L10n::t('Database Server Name'),
$configCache->get('database', 'hostname'),
'',
'required'],
'$dbuser' => ['database-username',
L10n::t('Database Login Name'),
$configCache->get('database', 'username'),
'',
'required',
'autofocus'],
'$dbpass' => ['database-password',
L10n::t('Database Login Password'),
$configCache->get('database', 'password'),
L10n::t("For security reasons the password must not be empty"),
'required'],
'$dbdata' => ['database-database',
L10n::t('Database Name'),
$configCache->get('database', 'database'),
'',
'required'],
'$lbl_10' => L10n::t('Please select a default timezone for your website'),
'$baseurl' => $a->getBaseURL(),
'$php_path' => $configCache->get('config', 'php_path'),
'$submit' => L10n::t('Submit')
'$title' => $install_title,
'$pass' => L10n::t('Database connection'),
'$info_01' => L10n::t('In order to install Friendica we need to know how to connect to your database.'),
'$info_02' => L10n::t('Please contact your hosting provider or site administrator if you have questions about these settings.'),
'$info_03' => L10n::t('The database you specify below should already exist. If it does not, please create it before continuing.'),
'checks' => self::$installer->getChecks(),
'$hostname' => $configCache->get('config', 'hostname'),
'$ssl_policy' => $configCache->get('system', 'ssl_policy'),
'$basepath' => $configCache->get('system', 'basepath'),
'$urlpath' => $configCache->get('system', 'urlpath'),
'$dbhost' => ['database-hostname',
L10n::t('Database Server Name'),
$configCache->get('database', 'hostname'),
'',
'required'],
'$dbuser' => ['database-username',
L10n::t('Database Login Name'),
$configCache->get('database', 'username'),
'',
'required',
'autofocus'],
'$dbpass' => ['database-password',
L10n::t('Database Login Password'),
$configCache->get('database', 'password'),
L10n::t("For security reasons the password must not be empty"),
'required'],
'$dbdata' => ['database-database',
L10n::t('Database Name'),
$configCache->get('database', 'database'),
'',
'required'],
'$lbl_10' => L10n::t('Please select a default timezone for your website'),
'$baseurl' => $a->getBaseURL(),
'$php_path' => $configCache->get('config', 'php_path'),
'$submit' => L10n::t('Submit')
]);
break;
@ -189,30 +260,34 @@ class Install extends BaseModule
$tpl = Renderer::getMarkupTemplate('install_settings.tpl');
$output .= Renderer::replaceMacros($tpl, [
'$title' => $install_title,
'$checks' => self::$installer->getChecks(),
'$pass' => L10n::t('Site settings'),
'$dbhost' => $configCache->get('database', 'hostname'),
'$dbuser' => $configCache->get('database', 'username'),
'$dbpass' => $configCache->get('database', 'password'),
'$dbdata' => $configCache->get('database', 'database'),
'$phpath' => $configCache->get('config', 'php_path'),
'$adminmail' => ['config-admin_email',
L10n::t('Site administrator email address'),
$configCache->get('config', 'admin_email'),
L10n::t('Your account email address must match this in order to use the web admin panel.'),
'required', 'autofocus', 'email'],
'$timezone' => Temporal::getTimezoneField('system-default_timezone',
L10n::t('Please select a default timezone for your website'),
$configCache->get('system', 'default_timezone'),
''),
'$language' => ['system-language',
L10n::t('System Language:'),
$configCache->get('system', 'language'),
L10n::t('Set the default language for your Friendica installation interface and to send emails.'),
$lang_choices],
'$baseurl' => $a->getBaseURL(),
'$submit' => L10n::t('Submit')
'$title' => $install_title,
'$checks' => self::$installer->getChecks(),
'$pass' => L10n::t('Site settings'),
'$hostname' => $configCache->get('config', 'hostname'),
'$ssl_policy' => $configCache->get('system', 'ssl_policy'),
'$basepath' => $configCache->get('system', 'basepath'),
'$urlpath' => $configCache->get('system', 'urlpath'),
'$dbhost' => $configCache->get('database', 'hostname'),
'$dbuser' => $configCache->get('database', 'username'),
'$dbpass' => $configCache->get('database', 'password'),
'$dbdata' => $configCache->get('database', 'database'),
'$adminmail' => ['config-admin_email',
L10n::t('Site administrator email address'),
$configCache->get('config', 'admin_email'),
L10n::t('Your account email address must match this in order to use the web admin panel.'),
'required', 'autofocus', 'email'],
'$timezone' => Temporal::getTimezoneField('system-default_timezone',
L10n::t('Please select a default timezone for your website'),
$configCache->get('system', 'default_timezone'),
''),
'$language' => ['system-language',
L10n::t('System Language:'),
$configCache->get('system', 'language'),
L10n::t('Set the default language for your Friendica installation interface and to send emails.'),
$lang_choices],
'$baseurl' => $a->getBaseURL(),
'$php_path' => $configCache->get('config', 'php_path'),
'$submit' => L10n::t('Submit')
]);
break;

View File

@ -285,7 +285,7 @@ class BaseURL
if (empty($this->url)) {
$this->determineBaseUrl();
if (!empty($url)) {
if (!empty($this->url)) {
$this->config->set('system', 'url', $this->url);
}
}

View File

@ -50,7 +50,6 @@ abstract class DatabaseTest extends MockedTest
$profiler = \Mockery::mock(Profiler::class);
DBA::connect(
$basePath,
$config,
$profiler,
new VoidLogger(),

View File

@ -39,10 +39,9 @@ trait AppMockTrait
* Mock the App
*
* @param vfsStreamDirectory $root The root directory
* @param Config\Cache\ConfigCache $configCache
* @param bool $raw If true, no config mocking will be done
*/
public function mockApp(vfsStreamDirectory $root, $configCache = null, $raw = false)
public function mockApp(vfsStreamDirectory $root, $raw = false)
{
$this->configMock = \Mockery::mock(Config\Cache\IConfigCache::class);
$this->mode = \Mockery::mock(App\Mode::class);
@ -50,7 +49,7 @@ trait AppMockTrait
// Disable the adapter
$configAdapterMock->shouldReceive('isConnected')->andReturn(false);
$config = new Config\Configuration((isset($configCache) ? $configCache : $this->configMock), $configAdapterMock);
$config = new Config\Configuration($this->configMock, $configAdapterMock);
// Initialize empty Config
Config::init($config);
@ -69,7 +68,10 @@ trait AppMockTrait
$this->app
->shouldReceive('getConfigCache')
->andReturn((isset($configCache) ? $configCache : $this->configMock));
->andReturn($this->configMock);
$this->app
->shouldReceive('getConfig')
->andReturn($config);
$this->app
->shouldReceive('getTemplateEngine')
->andReturn(new FriendicaSmartyEngine());
@ -82,7 +84,7 @@ trait AppMockTrait
$this->app
->shouldReceive('getBaseUrl')
->andReturnUsing(function () {
return $this->app->getConfigCache()->get('system', 'url');
return $this->configMock->get('system', 'url');
});
BaseObject::setApp($this->app);

View File

@ -15,9 +15,9 @@ trait RendererMockTrait
/**
* Mocking the method 'Renderer::getMarkupTemplate()'
*
* @param string $templateName The name of the template which should get
* @param string $return the return value of the mock (should be defined to have it later for followUp use)
* @param null|int $times How often the method will get used
* @param string $templateName The name of the template which should get
* @param string $return the return value of the mock (should be defined to have it later for followUp use)
* @param null|int $times How often the method will get used
*/
public function mockGetMarkupTemplate($templateName, $return = '', $times = null)
{
@ -35,12 +35,13 @@ trait RendererMockTrait
/**
* Mocking the method 'Renderer::replaceMacros()'
*
* @param string $template The template to use (normally, it is the mock result of 'mockGetMarkupTemplate()'
* @param array|\Closure|null $args The arguments to pass to the macro
* @param string $return the return value of the mock
* @param null|int $times How often the method will get used
* @param string $template The template to use (normally, it is the mock result of 'mockGetMarkupTemplate()'
* @param array|\Closure|null $args The arguments to pass to the macro
* @param bool $overwriteURL if the URL should get overwritten
* @param string $return the return value of the mock
* @param null|int $times How often the method will get used
*/
public function mockReplaceMacros($template, $args = null, $return = '', $times = null)
public function mockReplaceMacros($template, $args = null, $overwriteURL = true, $return = '', $times = null)
{
if (!isset($this->rendererMock)) {
$this->rendererMock = \Mockery::mock('alias:' . Renderer::class);
@ -50,10 +51,18 @@ trait RendererMockTrait
$args = [];
}
$this->rendererMock
->shouldReceive('replaceMacros')
->with($template, $args)
->times($times)
->andReturn($return);
if ($overwriteURL) {
$this->rendererMock
->shouldReceive('replaceMacros')
->with($template, $args)
->times($times)
->andReturn($return);
} else {
$this->rendererMock
->shouldReceive('replaceMacros')
->with($template, $args, false)
->times($times)
->andReturn($return);
}
}
}

View File

@ -55,7 +55,7 @@ class ApiTest extends DatabaseTest
$configLoader = new ConfigFileLoader($basePath, $mode);
$configCache = Factory\ConfigFactory::createCache($configLoader);
$profiler = Factory\ProfilerFactory::create($configCache);
Factory\DBFactory::init($basePath, $configCache, $profiler, $_SERVER);
Factory\DBFactory::init($configCache, $profiler, $_SERVER);
$config = Factory\ConfigFactory::createConfig($configCache);
Factory\ConfigFactory::createPConfig($configCache);
$logger = Factory\LoggerFactory::create('test', $config, $profiler);

View File

@ -10,6 +10,7 @@ use Friendica\Test\Util\DBAMockTrait;
use Friendica\Test\Util\DBStructureMockTrait;
use Friendica\Test\Util\L10nMockTrait;
use Friendica\Test\Util\RendererMockTrait;
use Friendica\Util\BaseURL;
use Friendica\Util\Logger\VoidLogger;
use org\bovigo\vfs\vfsStream;
use org\bovigo\vfs\vfsStreamFile;
@ -56,7 +57,7 @@ class AutomaticInstallationConsoleTest extends ConsoleTest
$this->configCache->set('config', 'php_path', trim(shell_exec('which php')));
$this->configCache->set('system', 'theme', 'smarty3');
$this->mockApp($this->root, null, true);
$this->mockApp($this->root, true);
$this->configMock->shouldReceive('set')->andReturnUsing(function ($cat, $key, $value) {
if ($key !== 'basepath') {
@ -97,10 +98,14 @@ class AutomaticInstallationConsoleTest extends ConsoleTest
],
'config' => [
'php_path' => '',
'hostname' => 'friendica.local',
'admin_email' => '',
],
'system' => [
'basepath' => '',
'urlpath' => '',
'url' => 'http://friendica.local',
'ssl_policy' => 0,
'default_timezone' => '',
'language' => '',
],
@ -117,10 +122,14 @@ class AutomaticInstallationConsoleTest extends ConsoleTest
],
'config' => [
'php_path' => '',
'hostname' => 'friendica.local',
'admin_email' => 'admin@philipp.info',
],
'system' => [
'urlpath' => 'test/it',
'url' => 'http://friendica.local/test/it',
'basepath' => '',
'ssl_policy' => '2',
'default_timezone' => 'en',
'language' => 'Europe/Berlin',
],
@ -137,10 +146,14 @@ class AutomaticInstallationConsoleTest extends ConsoleTest
],
'config' => [
'php_path' => '',
'hostname' => 'friendica.local',
'admin_email' => 'admin@philipp.info',
],
'system' => [
'urlpath' => 'test/it',
'url' => 'https://friendica.local/test/it',
'basepath' => '',
'ssl_policy' => '1',
'default_timezone' => 'en',
'language' => 'Europe/Berlin',
],
@ -236,6 +249,30 @@ Checking database...
Could not connect to database.:
FIN;
$this->assertEquals($finished, $txt);
}
private function assertStuckURL($txt)
{
$finished = <<<FIN
Initializing setup...
Complete!
Checking environment...
NOTICE: Not checking .htaccess/URL-Rewrite during CLI installation.
Complete!
Creating config file...
The Friendica URL has to be set during CLI installation.
FIN;
$this->assertEquals($finished, $txt);
@ -269,8 +306,9 @@ FIN;
* @param boolean $saveDb True, if the db credentials should get saved to the file
* @param boolean $default True, if we use the default values
* @param boolean $defaultDb True, if we use the default value for the DB
* @param boolean $realBasepath True, if we use the real basepath of the installation, not the mocked one
*/
public function assertConfig($assertion = null, $saveDb = false, $default = true, $defaultDb = true)
public function assertConfig($assertion = null, $saveDb = false, $default = true, $defaultDb = true, $realBasepath = false)
{
if (!empty($assertion['database']['hostname'])) {
$assertion['database']['hostname'] .= (!empty($assertion['database']['port']) ? ':' . $assertion['database']['port'] : '');
@ -283,34 +321,52 @@ FIN;
$this->assertConfigEntry('config', 'admin_email', $assertion);
$this->assertConfigEntry('config', 'php_path', trim(shell_exec('which php')));
$this->assertConfigEntry('config', 'hostname', $assertion);
$this->assertConfigEntry('system', 'default_timezone', $assertion, ($default) ? Installer::DEFAULT_TZ : null);
$this->assertConfigEntry('system', 'language', $assertion, ($default) ? Installer::DEFAULT_LANG : null);
$this->assertConfigEntry('system', 'url', $assertion);
$this->assertConfigEntry('system', 'urlpath', $assertion);
$this->assertConfigEntry('system', 'ssl_policy', $assertion, ($default) ? BaseURL::DEFAULT_SSL_SCHEME : null);
$this->assertConfigEntry('system', 'basepath', ($realBasepath) ? $this->root->url() : $assertion);
}
/**
* Test the automatic installation without any parameter/setting
* Should stuck because of missing hostname
*/
public function testEmpty()
{
$this->app->shouldReceive('getURLPath')->andReturn('')->atLeast()->once();
$console = new AutomaticInstallation($this->consoleArgv);
$txt = $this->dumpExecute($console);
$this->assertStuckURL($txt);
}
/**
* Test the automatic installation without any parameter/setting
* except URL
*/
public function testEmptyWithURL()
{
$this->mockConnect(true, 1);
$this->mockConnected(true, 1);
$this->mockExistsTable('user', false, 1);
$this->mockUpdate([$this->root->url(), false, true, true], null, 1);
$this->mockGetMarkupTemplate('local.config.tpl', 'testTemplate', 1);
$this->mockReplaceMacros('testTemplate', \Mockery::any(), '', 1);
$this->mockReplaceMacros('testTemplate', \Mockery::any(), false, '', 1);
$console = new AutomaticInstallation($this->consoleArgv);
$console->setOption('url', 'http://friendica.local');
$txt = $this->dumpExecute($console);
$this->assertFinished($txt, true, false);
$this->assertTrue($this->root->hasChild('config' . DIRECTORY_SEPARATOR . 'local.config.php'));
$this->assertConfig();
$this->assertConfig(['config' => ['hostname' => 'friendica.local'], 'system' => ['url' => 'http://friendica.local', 'ssl_policy' => 0, 'urlPath' => '']], false, true, true, true);
}
/**
@ -356,12 +412,16 @@ return [
'config' => [
'admin_email' => '{$conf('config', 'admin_email')}',
'hostname' => '{$conf('config', 'hostname')}',
'sitename' => 'Friendica Social Network',
'register_policy' => \Friendica\Module\Register::OPEN,
'register_text' => '',
],
'system' => [
'basepath' => '{$conf('system', 'basepath')}',
'urlpath' => '{$conf('system', 'urlpath')}',
'url' => '{$conf('system', 'url')}',
'ssl_policy' => '{$conf('system', 'ssl_policy')}',
'default_timezone' => '{$conf('system', 'default_timezone')}',
'language' => '{$conf('system', 'language')}',
],
@ -392,15 +452,13 @@ CONF;
*/
public function testWithEnvironmentAndSave(array $data)
{
$this->app->shouldReceive('getURLPath')->andReturn('')->atLeast()->once();
$this->mockConnect(true, 1);
$this->mockConnected(true, 1);
$this->mockExistsTable('user', false, 1);
$this->mockUpdate([$this->root->url(), false, true, true], null, 1);
$this->mockGetMarkupTemplate('local.config.tpl', 'testTemplate', 1);
$this->mockReplaceMacros('testTemplate', \Mockery::any(), '', 1);
$this->mockReplaceMacros('testTemplate', \Mockery::any(), false, '', 1);
$this->assertTrue(putenv('MYSQL_HOST=' . $data['database']['hostname']));
$this->assertTrue(putenv('MYSQL_PORT=' . $data['database']['port']));
@ -408,7 +466,9 @@ CONF;
$this->assertTrue(putenv('MYSQL_USERNAME=' . $data['database']['username']));
$this->assertTrue(putenv('MYSQL_PASSWORD=' . $data['database']['password']));
$this->assertTrue(putenv('FRIENDICA_URL_PATH=' . $data['system']['urlpath']));
$this->assertTrue(putenv('FRIENDICA_HOSTNAME=' . $data['config']['hostname']));
$this->assertTrue(putenv('FRIENDICA_BASE_PATH=' . $data['system']['basepath']));
$this->assertTrue(putenv('FRIENDICA_URL=' . $data['system']['url']));
$this->assertTrue(putenv('FRIENDICA_PHP_PATH=' . $data['config']['php_path']));
$this->assertTrue(putenv('FRIENDICA_ADMIN_MAIL=' . $data['config']['admin_email']));
$this->assertTrue(putenv('FRIENDICA_TZ=' . $data['system']['default_timezone']));
@ -420,7 +480,7 @@ CONF;
$txt = $this->dumpExecute($console);
$this->assertFinished($txt, true);
$this->assertConfig($data, true, true, false);
$this->assertConfig($data, true, true, false, true);
}
/**
@ -430,15 +490,13 @@ CONF;
*/
public function testWithEnvironmentWithoutSave(array $data)
{
$this->app->shouldReceive('getURLPath')->andReturn('')->atLeast()->once();
$this->mockConnect(true, 1);
$this->mockConnected(true, 1);
$this->mockExistsTable('user', false, 1);
$this->mockUpdate([$this->root->url(), false, true, true], null, 1);
$this->mockGetMarkupTemplate('local.config.tpl', 'testTemplate', 1);
$this->mockReplaceMacros('testTemplate', \Mockery::any(), '', 1);
$this->mockReplaceMacros('testTemplate', \Mockery::any(), false, '', 1);
$this->assertTrue(putenv('MYSQL_HOST=' . $data['database']['hostname']));
$this->assertTrue(putenv('MYSQL_PORT=' . $data['database']['port']));
@ -446,18 +504,20 @@ CONF;
$this->assertTrue(putenv('MYSQL_USERNAME=' . $data['database']['username']));
$this->assertTrue(putenv('MYSQL_PASSWORD=' . $data['database']['password']));
$this->assertTrue(putenv('FRIENDICA_URL_PATH=' . $data['system']['urlpath']));
$this->assertTrue(putenv('FRIENDICA_PHP_PATH=' . $data['config']['php_path']));
$this->assertTrue(putenv('FRIENDICA_HOSTNAME=' . $data['config']['hostname']));
$this->assertTrue(putenv('FRIENDICA_BASE_PATH=' . $data['system']['basepath']));
$this->assertTrue(putenv('FRIENDICA_URL=' . $data['system']['url']));
$this->assertTrue(putenv('FRIENDICA_PHP_PATH=' . $data['config']['php_path']));
$this->assertTrue(putenv('FRIENDICA_ADMIN_MAIL=' . $data['config']['admin_email']));
$this->assertTrue(putenv('FRIENDICA_TZ=' . $data['system']['default_timezone']));
$this->assertTrue(putenv('FRIENDICA_LANG=' . $data['system']['language']));
$this->assertTrue(putenv('FRIENDICA_TZ=' . $data['system']['default_timezone']));
$this->assertTrue(putenv('FRIENDICA_LANG=' . $data['system']['language']));
$console = new AutomaticInstallation($this->consoleArgv);
$txt = $this->dumpExecute($console);
$this->assertFinished($txt, true);
$this->assertConfig($data, false, true);
$this->assertConfig($data, false, true, false, true);
}
/**
@ -466,15 +526,13 @@ CONF;
*/
public function testWithArguments(array $data)
{
$this->app->shouldReceive('getURLPath')->andReturn('')->atLeast()->once();
$this->mockConnect(true, 1);
$this->mockConnected(true, 1);
$this->mockExistsTable('user', false, 1);
$this->mockUpdate([$this->root->url(), false, true, true], null, 1);
$this->mockGetMarkupTemplate('local.config.tpl', 'testTemplate', 1);
$this->mockReplaceMacros('testTemplate', \Mockery::any(), '', 1);
$this->mockReplaceMacros('testTemplate', \Mockery::any(), false, '', 1);
$console = new AutomaticInstallation($this->consoleArgv);
@ -483,21 +541,22 @@ CONF;
$console->setOption($var, $data[$cat][$key]);
}
};
$option('dbhost' , 'database', 'hostname');
$option('dbport' , 'database', 'port');
$option('dbuser' , 'database', 'username');
$option('dbpass' , 'database', 'password');
$option('dbdata' , 'database', 'database');
$option('urlpath' , 'system' , 'urlpath');
$option('phppath' , 'config' , 'php_path');
$option('admin' , 'config' , 'admin_email');
$option('tz' , 'system' , 'default_timezone');
$option('lang' , 'system' , 'language');
$option('dbhost' , 'database', 'hostname');
$option('dbport' , 'database', 'port');
$option('dbuser' , 'database', 'username');
$option('dbpass' , 'database', 'password');
$option('dbdata' , 'database', 'database');
$option('url' , 'system' , 'url');
$option('phppath' , 'config' , 'php_path');
$option('admin' , 'config' , 'admin_email');
$option('tz' , 'system' , 'default_timezone');
$option('lang' , 'system' , 'language');
$option('basepath' , 'system' , 'basepath');
$txt = $this->dumpExecute($console);
$this->assertFinished($txt, true);
$this->assertConfig($data, true, true, true);
$this->assertConfig($data, true, true, true, true);
}
/**
@ -505,20 +564,20 @@ CONF;
*/
public function testNoDatabaseConnection()
{
$this->app->shouldReceive('getURLPath')->andReturn('')->atLeast()->once();
$this->mockConnect(false, 1);
$this->mockGetMarkupTemplate('local.config.tpl', 'testTemplate', 1);
$this->mockReplaceMacros('testTemplate', \Mockery::any(), '', 1);
$this->mockReplaceMacros('testTemplate', \Mockery::any(), false, '', 1);
$console = new AutomaticInstallation($this->consoleArgv);
$console->setOption('url', 'http://friendica.local');
$txt = $this->dumpExecute($console);
$this->assertStuckDB($txt);
$this->assertTrue($this->root->hasChild('config' . DIRECTORY_SEPARATOR . 'local.config.php'));
$this->assertConfig(null, false, true, false);
$this->assertConfig(['config' => ['hostname' => 'friendica.local'], 'system' => ['url' => 'http://friendica.local', 'ssl_policy' => 0, 'urlpath' => '']], false, true, false, true);
}
public function testGetHelp()
@ -540,17 +599,17 @@ Options
-v Show more debug information.
-a All setup checks are required (except .htaccess)
-f|--file <config> prepared config file (e.g. "config/local.config.php" itself) which will override every other config option - except the environment variables)
-s|--savedb Save the DB credentials to the file (if environment variables is used)
-H|--dbhost <host> The host of the mysql/mariadb database (env MYSQL_HOST)
-p|--dbport <port> The port of the mysql/mariadb database (env MYSQL_PORT)
-d|--dbdata <database> The name of the mysql/mariadb database (env MYSQL_DATABASE)
-U|--dbuser <username> The username of the mysql/mariadb database login (env MYSQL_USER or MYSQL_USERNAME)
-P|--dbpass <password> The password of the mysql/mariadb database login (env MYSQL_PASSWORD)
-u|--urlpath <url_path> The URL path of Friendica - f.e. '/friendica' (env FRIENDICA_URL_PATH)
-b|--phppath <php_path> The path of the PHP binary (env FRIENDICA_PHP_PATH)
-A|--admin <mail> The admin email address of Friendica (env FRIENDICA_ADMIN_MAIL)
-T|--tz <timezone> The timezone of Friendica (env FRIENDICA_TZ)
-L|--lang <language> The language of Friendica (env FRIENDICA_LANG)
-s|--savedb Save the DB credentials to the file (if environment variables is used)
-H|--dbhost <host> The host of the mysql/mariadb database (env MYSQL_HOST)
-p|--dbport <port> The port of the mysql/mariadb database (env MYSQL_PORT)
-d|--dbdata <database> The name of the mysql/mariadb database (env MYSQL_DATABASE)
-U|--dbuser <username> The username of the mysql/mariadb database login (env MYSQL_USER or MYSQL_USERNAME)
-P|--dbpass <password> The password of the mysql/mariadb database login (env MYSQL_PASSWORD)
-U|--url <url> The full base URL of Friendica - f.e. 'https://friendica.local/sub' (env FRIENDICA_URL)
-B|--phppath <php_path> The path of the PHP binary (env FRIENDICA_PHP_PATH)
-b|--basepath <base_path> The basepath of Friendica (env FRIENDICA_BASE_PATH)
-t|--tz <timezone> The timezone of Friendica (env FRIENDICA_TZ)
-L|--lang <language> The language of Friendica (env FRIENDICA_LANG)
Environment variables
MYSQL_HOST The host of the mysql/mariadb database (mandatory if mysql and environment is used)
@ -558,8 +617,9 @@ Environment variables
MYSQL_USERNAME|MYSQL_USER The username of the mysql/mariadb database login (MYSQL_USERNAME is for mysql, MYSQL_USER for mariadb)
MYSQL_PASSWORD The password of the mysql/mariadb database login
MYSQL_DATABASE The name of the mysql/mariadb database
FRIENDICA_URL_PATH The URL path of Friendica (f.e. '/friendica')
FRIENDICA_PHP_PATH The path of the PHP binary
FRIENDICA_URL The full base URL of Friendica - f.e. 'https://friendica.local/sub'
FRIENDICA_PHP_PATH The path of the PHP binary - leave empty for auto detection
FRIENDICA_BASE_PATH The basepath of Friendica - leave empty for auto detection
FRIENDICA_ADMIN_MAIL The admin email address of Friendica (this email will be used for admin access)
FRIENDICA_TZ The timezone of Friendica
FRIENDICA_LANG The langauge of Friendica

View File

@ -3,6 +3,7 @@
// this is in the same namespace as Install for mocking 'function_exists'
namespace Friendica\Core;
use Friendica\Core\Config\Cache\IConfigCache;
use Friendica\Network\CurlResult;
use Friendica\Object\Image;
use Friendica\Test\MockedTest;
@ -392,6 +393,21 @@ class InstallerTest extends MockedTest
false,
$install->getChecks());
}
/**
* Test the setup of the config cache for installation
*/
public function testSetUpCache()
{
$this->mockL10nT();
$install = new Installer();
$configCache = \Mockery::mock(IConfigCache::class);
$configCache->shouldReceive('set')->with('config', 'php_path', \Mockery::any())->once();
$configCache->shouldReceive('set')->with('system', 'basepath', '/test/')->once();
$install->setUpCache($configCache, '/test/');
}
}
/**

View File

@ -20,7 +20,7 @@ class DBATest extends DatabaseTest
$configLoader = new ConfigFileLoader($basePath, $mode);
$configCache = Factory\ConfigFactory::createCache($configLoader);
$profiler = Factory\ProfilerFactory::create($configCache);
Factory\DBFactory::init($basePath, $configCache, $profiler, $_SERVER);
Factory\DBFactory::init($configCache, $profiler, $_SERVER);
$config = Factory\ConfigFactory::createConfig($configCache);
Factory\ConfigFactory::createPConfig($configCache);
$logger = Factory\LoggerFactory::create('test', $config, $profiler);

View File

@ -20,7 +20,7 @@ class DBStructureTest extends DatabaseTest
$configLoader = new ConfigFileLoader($basePath, $mode);
$configCache = Factory\ConfigFactory::createCache($configLoader);
$profiler = Factory\ProfilerFactory::create($configCache);
Factory\DBFactory::init($basePath, $configCache, $profiler, $_SERVER);
Factory\DBFactory::init($configCache, $profiler, $_SERVER);
$config = Factory\ConfigFactory::createConfig($configCache);
Factory\ConfigFactory::createPConfig($configCache);
$logger = Factory\LoggerFactory::create('test', $config, $profiler);

View File

@ -0,0 +1,29 @@
<?php
namespace Friendica\Test\src\Util;
use Friendica\Test\MockedTest;
use Friendica\Util\BasePath;
class BasePathTest extends MockedTest
{
/**
* Test the basepath determination
*/
public function testDetermineBasePath()
{
$serverArr = ['DOCUMENT_ROOT' => '/invalid', 'PWD' => '/invalid2'];
$this->assertEquals('/valid', BasePath::create('/valid', $serverArr));
}
/**
* Test the basepath determination with DOCUMENT_ROOT and PWD
*/
public function testDetermineBasePathWithServer()
{
$serverArr = ['DOCUMENT_ROOT' => '/valid'];
$this->assertEquals('/valid', BasePath::create('', $serverArr));
$serverArr = ['PWD' => '/valid_too'];
$this->assertEquals('/valid_too', BasePath::create('', $serverArr));
}
}

View File

@ -179,18 +179,26 @@ class BaseURLTest extends MockedTest
$configMock->shouldReceive('get')->with('system', 'ssl_policy')->andReturn($input['sslPolicy']);
$configMock->shouldReceive('get')->with('system', 'url')->andReturn($input['url']);
// If we don't have an urlPath as an input, we assert it, we will save it to the DB for the next time
if (!isset($input['urlPath']) && isset($assert['urlPath'])) {
$configMock->shouldReceive('set')->with('system', 'urlpath', $assert['urlPath'])->once();
}
// If we don't have the ssl_policy as an input, we assert it, we will save it to the DB for the next time
if (!isset($input['sslPolicy']) && isset($assert['sslPolicy'])) {
$configMock->shouldReceive('set')->with('system', 'ssl_policy', $assert['sslPolicy'])->once();
}
if (!isset($input['hostname']) && !empty($assert['hostname'])) {
// If we don't have the hostname as an input, we assert it, we will save it to the DB for the next time
if (empty($input['hostname']) && !empty($assert['hostname'])) {
$configMock->shouldReceive('set')->with('config', 'hostname', $assert['hostname'])->once();
}
// If we don't have an URL at first, but we assert it, we will save it to the DB for the next time
if (empty($input['url']) && !empty($assert['url'])) {
$configMock->shouldReceive('set')->with('system', 'url', $assert['url'])->once();
}
$baseUrl = new BaseURL($configMock, $server);
$this->assertEquals($assert['hostname'], $baseUrl->getHostname());

View File

@ -0,0 +1,34 @@
<h1><img src="{{$baseurl}}/images/friendica-32.png"> {{$title}}</h1>
<h2>{{$pass}}</h2>
<p>
{{$info_01}}<br>
{{$info_02}}<br>
{{$info_03}}
</p>
<table>
{{foreach $checks as $check}}
<tr><td>{{$check.title}} </td><td>
{{if ! $check.status}}
<img src="{{$baseurl}}/view/install/red.png" alt="Requirement not satisfied">
{{/if}}
{{/foreach}}
</table>
<form id="install-form" action="{{$baseurl}}/install" method="post">
<input type="hidden" name="config-php_path" value="{{$php_path}}" />
<input type="hidden" name="pass" value="3" />
{{include file="field_select.tpl" field=$ssl_policy}}
<br />
{{include file="field_input.tpl" field=$hostname}}
<br />
{{include file="field_input.tpl" field=$basepath}}
<br />
{{include file="field_input.tpl" field=$urlpath}}
<input id="install-submit" type="submit" name="submit" value="{{$submit}}" />
</form>

View File

@ -19,7 +19,11 @@
<form id="install-form" action="{{$baseurl}}/install" method="post">
<input type="hidden" name="config-php_path" value="{{$php_path}}" />
<input type="hidden" name="pass" value="3" />
<input type="hidden" name="config-hostname" value="{{$hostname}}" />
<input type="hidden" name="system-ssl_policy" value="{{$ssl_policy}}" />
<input type="hidden" name="system-basepath" value="{{$basepath}}" />
<input type="hidden" name="system-urlpath" value="{{$urlpath}}" />
<input type="hidden" name="pass" value="4" />
{{include file="field_input.tpl" field=$dbhost}}
{{include file="field_input.tpl" field=$dbuser}}

View File

@ -7,14 +7,18 @@
<form id="install-form" action="{{$baseurl}}/install" method="post">
<input type="hidden" name="config-php_path" value="{{$php_path}}" />
<input type="hidden" name="config-hostname" value="{{$hostname}}" />
<input type="hidden" name="system-ssl_policy" value="{{$ssl_policy}}" />
<input type="hidden" name="system-basepath" value="{{$basepath}}" />
<input type="hidden" name="system-urlpath" value="{{$urlpath}}" />
<input type="hidden" name="database-hostname" value="{{$dbhost}}" />
<input type="hidden" name="database-username" value="{{$dbuser}}" />
<input type="hidden" name="database-password" value="{{$dbpass}}" />
<input type="hidden" name="database-database" value="{{$dbdata}}" />
<input type="hidden" name="pass" value="4" />
<input type="hidden" name="pass" value="5" />
{{include file="field_input.tpl" field=$adminmail}}
{{$timezone nofilter}}
{{include file="field_input.tpl" field=$adminmail}} <br />
{{$timezone nofilter}} <br />
{{include file="field_select.tpl" field=$language}}
<input id="install-submit" type="submit" name="submit" value="{{$submit}}" />

View File

@ -24,11 +24,14 @@ return [
'php_path' => '{{$phpath}}',
'admin_email' => '{{$adminmail}}',
'sitename' => 'Friendica Social Network',
'hostname' => '{{$hostname}}',
'register_policy' => \Friendica\Module\Register::OPEN,
'max_import_size' => 200000,
],
'system' => [
'urlpath' => '{{$urlpath}}',
'url' => '{{$baseurl}}',
'ssl_policy' => {{$sslpolicy}},
'basepath' => '{{$basepath}}',
'default_timezone' => '{{$timezone}}',
'language' => '{{$language}}',