[INSTALL] Minor reformatting and modernization. Shouldn't change functionality significatively.

This commit is contained in:
Diogo Cordeiro 2019-07-15 01:40:31 +01:00
parent 7d262ad50b
commit 893bafa14b
3 changed files with 380 additions and 365 deletions

View File

@ -1,76 +1,88 @@
<?php <?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social 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.
//
// GNU social 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 GNU social. If not, see <http://www.gnu.org/licenses/>.
/** /**
* StatusNet - the distributed open-source microblogging tool * Installation lib
* Copyright (C) 2009-2010, StatusNet, Inc.
* *
* This program is free software: you can redistribute it and/or modify * @package Installation
* it under the terms of the GNU Affero General Public License as published by * @author Adrian Lang <mail@adrianlang.de>
* the Free Software Foundation, either version 3 of the License, or * @author Brenda Wallace <shiny@cpan.org>
* (at your option) any later version. * @author Brett Taylor <brett@webfroot.co.nz>
* * @author Brion Vibber <brion@pobox.com>
* This program is distributed in the hope that it will be useful, * @author CiaranG <ciaran@ciarang.com>
* but WITHOUT ANY WARRANTY; without even the implied warranty of * @author Craig Andrews <candrews@integralblue.com>
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * @author Eric Helgeson <helfire@Erics-MBP.local>
* GNU Affero General Public License for more details. * @author Evan Prodromou <evan@status.net>
* * @author Mikael Nordfeldth <mmn@hethane.se>
* You should have received a copy of the GNU Affero General Public License * @author Robin Millette <millette@controlyourself.ca>
* along with this program. If not, see <http://www.gnu.org/licenses/>. * @author Sarven Capadisli <csarven@status.net>
* * @author Tom Adams <tom@holizz.com>
* @category Installation * @author Zach Copley <zach@status.net>
* @package Installation * @author Diogo Cordeiro <diogo@fc.up.pt>
* * @copyright 2019 Free Software Foundation, Inc http://www.fsf.org
* @author Adrian Lang <mail@adrianlang.de> * @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
* @author Brenda Wallace <shiny@cpan.org>
* @author Brett Taylor <brett@webfroot.co.nz>
* @author Brion Vibber <brion@pobox.com>
* @author CiaranG <ciaran@ciarang.com>
* @author Craig Andrews <candrews@integralblue.com>
* @author Eric Helgeson <helfire@Erics-MBP.local>
* @author Evan Prodromou <evan@status.net>
* @author Mikael Nordfeldth <mmn@hethane.se>
* @author Robin Millette <millette@controlyourself.ca>
* @author Sarven Capadisli <csarven@status.net>
* @author Tom Adams <tom@holizz.com>
* @author Zach Copley <zach@status.net>
* @copyright 2009-2010 StatusNet, Inc http://status.net
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
* @license GNU Affero General Public License http://www.gnu.org/licenses/
* @version 1.0.x
* @link http://status.net
*/ */
abstract class Installer abstract class Installer
{ {
/** Web site info */ /** Web site info */
public $sitename, $server, $path, $fancy, $siteProfile, $ssl; public $sitename;
public $server;
public $path;
public $fancy;
public $siteProfile;
public $ssl;
/** DB info */ /** DB info */
public $host, $database, $dbtype, $username, $password, $db; public $host;
public $database;
public $dbtype;
public $username;
public $password;
public $db;
/** Storage info */ /** Storage info */
public $avatarDir, $fileDir; public $avatarDir;
public $fileDir;
/** Administrator info */ /** Administrator info */
public $adminNick, $adminPass, $adminEmail; public $adminNick;
public $adminPass;
public $adminEmail;
/** Should we skip writing the configuration file? */ /** Should we skip writing the configuration file? */
public $skipConfig = false; public $skipConfig = false;
public static $dbModules = array( public static $dbModules = [
'mysql' => array( 'mysql' => [
'name' => 'MariaDB 10.3+', 'name' => 'MariaDB 10.3+',
'check_module' => 'mysqli', 'check_module' => 'mysqli',
'scheme' => 'mysqli', // DSN prefix for PEAR::DB 'scheme' => 'mysqli', // DSN prefix for PEAR::DB
), ],
/* 'pgsql' => array( /*'pgsql' => [
'name' => 'PostgreSQL', 'name' => 'PostgreSQL',
'check_module' => 'pgsql', 'check_module' => 'pgsql',
'scheme' => 'pgsql', // DSN prefix for PEAR::DB 'scheme' => 'pgsql', // DSN prefix for PEAR::DB
),*/ ]*/
); ];
/** /**
* Attempt to include a PHP file and report if it worked, while * Attempt to include a PHP file and report if it worked, while
* suppressing the annoying warning messages on failure. * suppressing the annoying warning messages on failure.
* @param string $filename
* @return bool
*/ */
private function haveIncludeFile($filename) { private function haveIncludeFile(string $filename): bool
{
$old = error_reporting(error_reporting() & ~E_WARNING); $old = error_reporting(error_reporting() & ~E_WARNING);
$ok = include_once($filename); $ok = include_once($filename);
error_reporting($old); error_reporting($old);
@ -80,13 +92,13 @@ abstract class Installer
/** /**
* Check if all is ready for installation * Check if all is ready for installation
* *
* @return void * @return bool
*/ */
function checkPrereqs() public function checkPrereqs(): bool
{ {
$pass = true; $pass = true;
$config = INSTALLDIR.'/config.php'; $config = INSTALLDIR . '/config.php';
if (!$this->skipConfig && file_exists($config)) { if (!$this->skipConfig && file_exists($config)) {
if (!is_writable($config) || filesize($config) > 0) { if (!is_writable($config) || filesize($config) > 0) {
if (filesize($config) == 0) { if (filesize($config) == 0) {
@ -103,20 +115,19 @@ abstract class Installer
$pass = false; $pass = false;
} }
$reqs = array('gd', 'curl', 'intl', 'json', $reqs = ['bcmath', 'curl', 'dom', 'gd', 'intl', 'json', 'mbstring', 'openssl', 'simplexml', 'xml', 'xmlwriter'];
'xmlwriter', 'mbstring', 'xml', 'dom', 'simplexml');
foreach ($reqs as $req) { foreach ($reqs as $req) {
if (!$this->checkExtension($req)) { // Checks if a php extension is both installed and loaded
if (!extension_loaded($req)) {
$this->warning(sprintf('Cannot load required extension: <code>%s</code>', $req)); $this->warning(sprintf('Cannot load required extension: <code>%s</code>', $req));
$pass = false; $pass = false;
} }
} }
// Make sure we have at least one database module available // Make sure we have at least one database module available
$missingExtensions = array(); $missingExtensions = [];
foreach (self::$dbModules as $type => $info) { foreach (self::$dbModules as $type => $info) {
if (!$this->checkExtension($info['check_module'])) { if (!extension_loaded($info['check_module'])) {
$missingExtensions[] = $info['check_module']; $missingExtensions[] = $info['check_module'];
} }
} }
@ -129,8 +140,10 @@ abstract class Installer
// @fixme this check seems to be insufficient with Windows ACLs // @fixme this check seems to be insufficient with Windows ACLs
if (!$this->skipConfig && !is_writable(INSTALLDIR)) { if (!$this->skipConfig && !is_writable(INSTALLDIR)) {
$this->warning(sprintf('Cannot write config file to: <code>%s</code></p>', INSTALLDIR), $this->warning(
sprintf('On your server, try this command: <code>chmod a+w %s</code>', INSTALLDIR)); sprintf('Cannot write config file to: <code>%s</code></p>', INSTALLDIR),
sprintf('On your server, try this command: <code>chmod a+w %s</code>', INSTALLDIR)
);
$pass = false; $pass = false;
} }
@ -140,22 +153,29 @@ abstract class Installer
define('GNUSOCIAL', true); define('GNUSOCIAL', true);
define('STATUSNET', true); define('STATUSNET', true);
require_once INSTALLDIR . '/lib/language.php'; require_once INSTALLDIR . '/lib/language.php';
$_server=$this->server; $_path=$this->path; // We won't be using those so it's safe to do this small hack $_server = $this->server;
require_once INSTALLDIR.DIRECTORY_SEPARATOR.'lib'.DIRECTORY_SEPARATOR.'util.php'; $_path = $this->path; // We won't be using those so it's safe to do this small hack
require_once INSTALLDIR.DIRECTORY_SEPARATOR.'lib'.DIRECTORY_SEPARATOR.'default.php'; require_once INSTALLDIR . DIRECTORY_SEPARATOR . 'lib' . DIRECTORY_SEPARATOR . 'util.php';
$fileSubdirs = [empty($this->avatarDir) ? $default['avatar']['dir'] : $this->avatarDir, require_once INSTALLDIR . DIRECTORY_SEPARATOR . 'lib' . DIRECTORY_SEPARATOR . 'default.php';
empty($this->fileDir) ? $default['attachments']['dir'] : $this->fileDir]; $fileSubdirs = [
empty($this->avatarDir) ? $default['avatar']['dir'] : $this->avatarDir,
empty($this->fileDir) ? $default['attachments']['dir'] : $this->fileDir
];
unset($default); unset($default);
foreach ($fileSubdirs as $fileFullPath) { foreach ($fileSubdirs as $fileFullPath) {
if (!file_exists($fileFullPath)) { if (!file_exists($fileFullPath)) {
$pass = $pass && mkdir($fileFullPath); $pass = $pass && mkdir($fileFullPath);
} elseif (!is_dir($fileFullPath)) { } elseif (!is_dir($fileFullPath)) {
$this->warning(sprintf('GNU social expected a directory but found something else on this path: %s', $fileFullPath), $this->warning(
'Either make sure it goes to a directory or remove it and a directory will be created.'); sprintf('GNU social expected a directory but found something else on this path: %s', $fileFullPath),
'Either make sure it goes to a directory or remove it and a directory will be created.'
);
$pass = false; $pass = false;
} elseif (!is_writable($fileFullPath)) { } elseif (!is_writable($fileFullPath)) {
$this->warning(sprintf('Cannot write to %s directory: <code>%s</code>', $fileSubdir, $fileFullPath), $this->warning(
sprintf('On your server, try this command: <code>chmod a+w %s</code>', $fileFullPath)); sprintf('Cannot write to directory: <code>%s</code>', $fileFullPath),
sprintf('On your server, try this command: <code>chmod a+w %s</code>', $fileFullPath)
);
$pass = false; $pass = false;
} }
} }
@ -164,36 +184,12 @@ abstract class Installer
} }
/** /**
* Checks if a php extension is both installed and loaded * Basic validation on the database parameters
*
* @param string $name of extension to check
*
* @return boolean whether extension is installed and loaded
*/
function checkExtension($name)
{
if (extension_loaded($name)) {
return true;
} elseif (function_exists('dl') && ini_get('enable_dl') && !ini_get('safe_mode')) {
// dl will throw a fatal error if it's disabled or we're in safe mode.
// More fun, it may not even exist under some SAPIs in 5.3.0 or later...
$soname = $name . '.' . PHP_SHLIB_SUFFIX;
if (PHP_SHLIB_SUFFIX == 'dll') {
$soname = "php_" . $soname;
}
return @dl($soname);
} else {
return false;
}
}
/**
* Basic validation on the database paramters
* Side effects: error output if not valid * Side effects: error output if not valid
* *
* @return boolean success * @return bool success
*/ */
function validateDb() public function validateDb(): bool
{ {
$fail = false; $fail = false;
@ -221,12 +217,12 @@ abstract class Installer
} }
/** /**
* Basic validation on the administrator user paramters * Basic validation on the administrator user parameters
* Side effects: error output if not valid * Side effects: error output if not valid
* *
* @return boolean success * @return bool success
*/ */
function validateAdmin() public function validateAdmin(): bool
{ {
$fail = false; $fail = false;
@ -236,15 +232,16 @@ abstract class Installer
} }
if ($this->adminNick && !preg_match('/^[0-9a-z]{1,64}$/', $this->adminNick)) { if ($this->adminNick && !preg_match('/^[0-9a-z]{1,64}$/', $this->adminNick)) {
$this->updateStatus('The user nickname "' . htmlspecialchars($this->adminNick) . $this->updateStatus('The user nickname "' . htmlspecialchars($this->adminNick) .
'" is invalid; should be plain letters and numbers no longer than 64 characters.', true); '" is invalid; should be plain letters and numbers no longer than 64 characters.', true);
$fail = true; $fail = true;
} }
// @fixme hardcoded list; should use Nickname::isValid() // @fixme hardcoded list; should use Nickname::isValid()
// if/when it's safe to have loaded the infrastructure here // if/when it's safe to have loaded the infrastructure here
$blacklist = array('main', 'panel', 'twitter', 'settings', 'rsd.xml', 'favorited', 'featured', 'favoritedrss', 'featuredrss', 'rss', 'getfile', 'api', 'groups', 'group', 'peopletag', 'tag', 'user', 'message', 'conversation', 'notice', 'attachment', 'search', 'index.php', 'doc', 'opensearch', 'robots.txt', 'xd_receiver.html', 'facebook', 'activity'); $blacklist = ['main', 'panel', 'twitter', 'settings', 'rsd.xml', 'favorited', 'featured', 'favoritedrss', 'featuredrss', 'rss', 'getfile', 'api', 'groups', 'group', 'peopletag', 'tag', 'user', 'message', 'conversation', 'notice', 'attachment', 'search', 'index.php', 'doc', 'opensearch', 'robots.txt', 'xd_receiver.html', 'facebook', 'activity'];
if (in_array($this->adminNick, $blacklist)) { if (in_array($this->adminNick, $blacklist)) {
$this->updateStatus('The user nickname "' . htmlspecialchars($this->adminNick) . $this->updateStatus('The user nickname "' . htmlspecialchars($this->adminNick) .
'" is reserved.', true); '" is reserved.', true);
$fail = true; $fail = true;
} }
@ -259,11 +256,11 @@ abstract class Installer
/** /**
* Make sure a site profile was selected * Make sure a site profile was selected
* *
* @return type boolean success * @return bool success
*/ */
function validateSiteProfile() public function validateSiteProfile(): bool
{ {
if (empty($this->siteProfile)) { if (empty($this->siteProfile)) {
$this->updateStatus("No site profile selected.", true); $this->updateStatus("No site profile selected.", true);
return false; return false;
} }
@ -277,8 +274,9 @@ abstract class Installer
* *
* @fixme escape things in the connection string in case we have a funny pass etc * @fixme escape things in the connection string in case we have a funny pass etc
* @return mixed array of database connection params on success, false on failure * @return mixed array of database connection params on success, false on failure
* @throws Exception
*/ */
function setupDatabase() public function setupDatabase()
{ {
if ($this->db) { if ($this->db) {
throw new Exception("Bad order of operations: DB already set up."); throw new Exception("Bad order of operations: DB already set up.");
@ -302,15 +300,17 @@ abstract class Installer
} }
// ensure database encoding is UTF8 // ensure database encoding is UTF8
$conn->query('SET NAMES utf8mb4');
if ($this->dbtype == 'mysql') { if ($this->dbtype == 'mysql') {
// @fixme utf8m4 support for mysql 5.5? $server_encoding = $conn->getRow("SHOW VARIABLES LIKE 'character_set_server'")[1];
// Force the comms charset to utf8 for sanity if ($server_encoding != 'utf8mb4') {
// This doesn't currently work. :P $this->updateStatus("GNU social requires UTF8 character encoding. Your database is " . htmlentities($server_encoding));
//$conn->executes('set names utf8'); return false;
} else if ($this->dbtype == 'pgsql') { }
$record = $conn->getRow('SHOW server_encoding'); } elseif ($this->dbtype == 'pgsql') {
if ($record->server_encoding != 'UTF8') { $server_encoding = $conn->getRow('SHOW server_encoding')[0];
$this->updateStatus("GNU social requires UTF8 character encoding. Your database is ". htmlentities($record->server_encoding)); if ($server_encoding != 'UTF8') {
$this->updateStatus("GNU social requires UTF8 character encoding. Your database is " . htmlentities($server_encoding));
return false; return false;
} }
} }
@ -321,29 +321,29 @@ abstract class Installer
return false; return false;
} }
foreach (array('sms_carrier' => 'SMS carrier', foreach (['sms_carrier' => 'SMS carrier',
'notice_source' => 'notice source', 'notice_source' => 'notice source',
'foreign_services' => 'foreign service') 'foreign_services' => 'foreign service']
as $scr => $name) { as $scr => $name) {
$this->updateStatus(sprintf("Adding %s data to database...", $name)); $this->updateStatus(sprintf("Adding %s data to database...", $name));
$res = $this->runDbScript($scr.'.sql', $conn); $res = $this->runDbScript($scr . '.sql', $conn);
if ($res === false) { if ($res === false) {
$this->updateStatus(sprintf("Can't run %s script.", $name), true); $this->updateStatus(sprintf("Can't run %s script.", $name), true);
return false; return false;
} }
} }
$db = array('type' => $this->dbtype, 'database' => $dsn); $db = ['type' => $this->dbtype, 'database' => $dsn];
return $db; return $db;
} }
/** /**
* Open a connection to the database. * Open a connection to the database.
* *
* @param <type> $dsn * @param string $dsn
* @return <type> * @return DB|DB_Error
*/ */
function connectDatabase($dsn) public function connectDatabase(string $dsn)
{ {
global $_DB; global $_DB;
return $_DB->connect($dsn); return $_DB->connect($dsn);
@ -353,8 +353,9 @@ abstract class Installer
* Create core tables on the given database connection. * Create core tables on the given database connection.
* *
* @param DB_common $conn * @param DB_common $conn
* @return bool
*/ */
function createCoreTables(DB_common $conn) public function createCoreTables(DB_common $conn): bool
{ {
$schema = Schema::get($conn); $schema = Schema::get($conn);
$tableDefs = $this->getCoreSchema(); $tableDefs = $this->getCoreSchema();
@ -372,9 +373,9 @@ abstract class Installer
* *
* @return array of table names => table def arrays * @return array of table names => table def arrays
*/ */
function getCoreSchema() public function getCoreSchema(): array
{ {
$schema = array(); $schema = [];
include INSTALLDIR . '/db/core.php'; include INSTALLDIR . '/db/core.php';
return $schema; return $schema;
} }
@ -386,7 +387,7 @@ abstract class Installer
* @param mixed $val * @param mixed $val
* @return string * @return string
*/ */
function phpVal($val) public function phpVal($val): string
{ {
return var_export($val, true); return var_export($val, true);
} }
@ -395,63 +396,63 @@ abstract class Installer
* Return an array of parseable PHP literal for the given values. * Return an array of parseable PHP literal for the given values.
* These will include quotes for strings, etc. * These will include quotes for strings, etc.
* *
* @param mixed $val * @param mixed $map
* @return array * @return array
*/ */
function phpVals($map) public function phpVals($map): array
{ {
return array_map(array($this, 'phpVal'), $map); return array_map([$this, 'phpVal'], $map);
} }
/** /**
* Write a stock configuration file. * Write a stock configuration file.
* *
* @return boolean success * @return bool success
* *
* @fixme escape variables in output in case we have funny chars, apostrophes etc * @fixme escape variables in output in case we have funny chars, apostrophes etc
*/ */
function writeConf() public function writeConf(): bool
{ {
$vals = $this->phpVals(array( $vals = $this->phpVals([
'sitename' => $this->sitename, 'sitename' => $this->sitename,
'server' => $this->server, 'server' => $this->server,
'path' => $this->path, 'path' => $this->path,
'ssl' => in_array($this->ssl, array('never', 'always')) 'ssl' => in_array($this->ssl, ['never', 'always'])
? $this->ssl ? $this->ssl
: 'never', : 'never',
'db_database' => $this->db['database'], 'db_database' => $this->db['database'],
'db_type' => $this->db['type'] 'db_type' => $this->db['type']
)); ]);
// assemble configuration file in a string // assemble configuration file in a string
$cfg = "<?php\n". $cfg = "<?php\n" .
"if (!defined('GNUSOCIAL')) { exit(1); }\n\n". "if (!defined('GNUSOCIAL')) { exit(1); }\n\n" .
// site name // site name
"\$config['site']['name'] = {$vals['sitename']};\n\n". "\$config['site']['name'] = {$vals['sitename']};\n\n" .
// site location // site location
"\$config['site']['server'] = {$vals['server']};\n". "\$config['site']['server'] = {$vals['server']};\n" .
"\$config['site']['path'] = {$vals['path']}; \n\n". "\$config['site']['path'] = {$vals['path']}; \n\n" .
"\$config['site']['ssl'] = {$vals['ssl']}; \n\n". "\$config['site']['ssl'] = {$vals['ssl']}; \n\n" .
// checks if fancy URLs are enabled // checks if fancy URLs are enabled
($this->fancy ? "\$config['site']['fancy'] = true;\n\n":''). ($this->fancy ? "\$config['site']['fancy'] = true;\n\n" : '') .
// database // database
"\$config['db']['database'] = {$vals['db_database']};\n\n". "\$config['db']['database'] = {$vals['db_database']};\n\n" .
($this->db['type'] == 'pgsql' ? "\$config['db']['quote_identifiers'] = true;\n\n":''). ($this->db['type'] == 'pgsql' ? "\$config['db']['quote_identifiers'] = true;\n\n" : '') .
"\$config['db']['type'] = {$vals['db_type']};\n\n". "\$config['db']['type'] = {$vals['db_type']};\n\n" .
"// Uncomment below for better performance. Just remember you must run\n". "// Uncomment below for better performance. Just remember you must run\n" .
"// php scripts/checkschema.php whenever your enabled plugins change!\n". "// php scripts/checkschema.php whenever your enabled plugins change!\n" .
"//\$config['db']['schemacheck'] = 'script';\n\n"; "//\$config['db']['schemacheck'] = 'script';\n\n";
// Normalize line endings for Windows servers // Normalize line endings for Windows servers
$cfg = str_replace("\n", PHP_EOL, $cfg); $cfg = str_replace("\n", PHP_EOL, $cfg);
// write configuration file out to install directory // write configuration file out to install directory
$res = file_put_contents(INSTALLDIR.'/config.php', $cfg); $res = file_put_contents(INSTALLDIR . '/config.php', $cfg);
return $res; return $res;
} }
@ -465,16 +466,16 @@ abstract class Installer
* *
* @return int res number of bytes written * @return int res number of bytes written
*/ */
function writeSiteProfile() public function writeSiteProfile(): int
{ {
$vals = $this->phpVals(array( $vals = $this->phpVals([
'site_profile' => $this->siteProfile, 'site_profile' => $this->siteProfile,
'nickname' => $this->adminNick 'nickname' => $this->adminNick
)); ]);
$cfg = $cfg =
// site profile // site profile
"\$config['site']['profile'] = {$vals['site_profile']};\n"; "\$config['site']['profile'] = {$vals['site_profile']};\n";
if ($this->siteProfile == "singleuser") { if ($this->siteProfile == "singleuser") {
$cfg .= "\$config['singleuser']['nickname'] = {$vals['nickname']};\n\n"; $cfg .= "\$config['singleuser']['nickname'] = {$vals['nickname']};\n\n";
@ -486,7 +487,7 @@ abstract class Installer
$cfg = str_replace("\n", PHP_EOL, $cfg); $cfg = str_replace("\n", PHP_EOL, $cfg);
// write configuration file out to install directory // write configuration file out to install directory
$res = file_put_contents(INSTALLDIR.'/config.php', $cfg, FILE_APPEND); $res = file_put_contents(INSTALLDIR . '/config.php', $cfg, FILE_APPEND);
return $res; return $res;
} }
@ -494,12 +495,12 @@ abstract class Installer
/** /**
* Install schema into the database * Install schema into the database
* *
* @param string $filename location of database schema file * @param string $filename location of database schema file
* @param DB_common $conn connection to database * @param DB_common $conn connection to database
* *
* @return boolean - indicating success or failure * @return bool - indicating success or failure
*/ */
function runDbScript($filename, DB_common $conn) public function runDbScript(string $filename, DB_common $conn): bool
{ {
$sql = trim(file_get_contents(INSTALLDIR . '/db/' . $filename)); $sql = trim(file_get_contents(INSTALLDIR . '/db/' . $filename));
$stmts = explode(';', $sql); $stmts = explode(';', $sql);
@ -509,7 +510,7 @@ abstract class Installer
continue; continue;
} }
try { try {
$res = $conn->simpleQuery($stmt); $res = $conn->query($stmt);
} catch (Exception $e) { } catch (Exception $e) {
$error = $e->getMessage(); $error = $e->getMessage();
$this->updateStatus("ERROR ($error) for SQL '$stmt'"); $this->updateStatus("ERROR ($error) for SQL '$stmt'");
@ -524,16 +525,16 @@ abstract class Installer
* Side effect: may load portions of GNU social framework. * Side effect: may load portions of GNU social framework.
* Side effect: outputs program info * Side effect: outputs program info
*/ */
function registerInitialUser() public function registerInitialUser(): bool
{ {
// initalize hostname from install arguments, so it can be used to find // initalize hostname from install arguments, so it can be used to find
// the /etc config file from the commandline installer // the /etc config file from the commandline installer
$server = $this->server; $server = $this->server;
require_once INSTALLDIR . '/lib/common.php'; require_once INSTALLDIR . '/lib/common.php';
$data = array('nickname' => $this->adminNick, $data = ['nickname' => $this->adminNick,
'password' => $this->adminPass, 'password' => $this->adminPass,
'fullname' => $this->adminNick); 'fullname' => $this->adminNick];
if ($this->adminEmail) { if ($this->adminEmail) {
$data['email'] = $this->adminEmail; $data['email'] = $this->adminEmail;
} }
@ -558,9 +559,9 @@ abstract class Installer
* *
* Prerequisites: validation of input data. * Prerequisites: validation of input data.
* *
* @return boolean success * @return bool success
*/ */
function doInstall() public function doInstall(): bool
{ {
global $config; global $config;
@ -595,8 +596,8 @@ abstract class Installer
} }
if (!$this->skipConfig) { if (!$this->skipConfig) {
// Make sure we can write to the file twice // Make sure we can write to the file twice
$oldUmask = umask(000); $oldUmask = umask(000);
$this->updateStatus("Writing config file..."); $this->updateStatus("Writing config file...");
$res = $this->writeConf(); $res = $this->writeConf();
@ -631,18 +632,18 @@ abstract class Installer
return false; return false;
} }
// Restore original umask // Restore original umask
umask($oldUmask); umask($oldUmask);
// Set permissions back to something decent // Set permissions back to something decent
chmod(INSTALLDIR.'/config.php', 0644); chmod(INSTALLDIR . '/config.php', 0644);
} }
$scheme = $this->ssl === 'always' ? 'https' : 'http'; $scheme = $this->ssl === 'always' ? 'https' : 'http';
$link = "{$scheme}://{$this->server}/{$this->path}"; $link = "{$scheme}://{$this->server}/{$this->path}";
$this->updateStatus("GNU social has been installed at $link"); $this->updateStatus("GNU social has been installed at $link");
$this->updateStatus( $this->updateStatus(
'<strong>DONE!</strong> You can visit your <a href="'.htmlspecialchars($link).'">new GNU social site</a> (log in as "'.htmlspecialchars($this->adminNick).'"). If this is your first GNU social install, make your experience the best possible by visiting our resource site to join the <a href="https://gnu.io/social/resources/">mailing list or IRC</a>. <a href="'.htmlspecialchars($link).'/doc/faq">FAQ is found here</a>.' '<strong>DONE!</strong> You can visit your <a href="' . htmlspecialchars($link) . '">new GNU social site</a> (log in as "' . htmlspecialchars($this->adminNick) . '"). If this is your first GNU social install, make your experience the best possible by visiting our resource site to join the <a href="https://gnu.io/social/resources/">mailing list or IRC</a>. <a href="' . htmlspecialchars($link) . '/doc/faq">FAQ is found here</a>.'
); );
return true; return true;
@ -653,13 +654,12 @@ abstract class Installer
* @param string $message HTML ok, but should be plaintext-able * @param string $message HTML ok, but should be plaintext-able
* @param string $submessage HTML ok, but should be plaintext-able * @param string $submessage HTML ok, but should be plaintext-able
*/ */
abstract function warning($message, $submessage=''); abstract public function warning(string $message, string $submessage = '');
/** /**
* Output an install-time progress message * Output an install-time progress message
* @param string $message HTML ok, but should be plaintext-able * @param string $status HTML ok, but should be plaintext-able
* @param boolean $error true if this should be marked as an error condition * @param bool $error true if this should be marked as an error condition
*/ */
abstract function updateStatus($status, $error=false); abstract public function updateStatus(string $status, bool $error = false);
} }

View File

@ -1,57 +1,56 @@
<?php <?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social 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.
//
// GNU social 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 GNU social. If not, see <http://www.gnu.org/licenses/>.
/** /**
* StatusNet - the distributed open-source microblogging tool * Web Installer
* Copyright (C) 2009-2010, StatusNet, Inc.
* *
* This program is free software: you can redistribute it and/or modify * @package Installation
* it under the terms of the GNU Affero General Public License as published by * @author Adrian Lang <mail@adrianlang.de>
* the Free Software Foundation, either version 3 of the License, or * @author Brenda Wallace <shiny@cpan.org>
* (at your option) any later version. * @author Brett Taylor <brett@webfroot.co.nz>
* * @author Brion Vibber <brion@pobox.com>
* This program is distributed in the hope that it will be useful, * @author CiaranG <ciaran@ciarang.com>
* but WITHOUT ANY WARRANTY; without even the implied warranty of * @author Craig Andrews <candrews@integralblue.com>
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * @author Eric Helgeson <helfire@Erics-MBP.local>
* GNU Affero General Public License for more details. * @author Evan Prodromou <evan@status.net>
* * @author Mikael Nordfeldth <mmn@hethane.se>
* You should have received a copy of the GNU Affero General Public License * @author Robin Millette <millette@controlyourself.ca>
* along with this program. If not, see <http://www.gnu.org/licenses/>. * @author Sarven Capadisli <csarven@status.net>
* * @author Tom Adams <tom@holizz.com>
* @category Installation * @author Zach Copley <zach@status.net>
* @package Installation * @author Diogo Cordeiro <diogo@fc.up.pt>
* * @copyright 2019 Free Software Foundation, Inc http://www.fsf.org
* @author Adrian Lang <mail@adrianlang.de> * @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
* @author Brenda Wallace <shiny@cpan.org>
* @author Brett Taylor <brett@webfroot.co.nz>
* @author Brion Vibber <brion@pobox.com>
* @author CiaranG <ciaran@ciarang.com>
* @author Craig Andrews <candrews@integralblue.com>
* @author Eric Helgeson <helfire@Erics-MBP.local>
* @author Evan Prodromou <evan@status.net>
* @author Mikael Nordfeldth <mmn@hethane.se>
* @author Robin Millette <millette@controlyourself.ca>
* @author Sarven Capadisli <csarven@status.net>
* @author Tom Adams <tom@holizz.com>
* @author Zach Copley <zach@status.net>
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
* @license GNU Affero General Public License http://www.gnu.org/licenses/
* @version 0.9.x
* @link http://status.net
*/ */
define('INSTALLDIR', __DIR__); define('INSTALLDIR', dirname(__DIR__));
require dirname(INSTALLDIR) . '/lib/installer.php'; require INSTALLDIR . '/lib/installer.php';
/** /**
* Helper class for building form * Helper class for building form
*/ */
class Posted { class Posted
{
/** /**
* HTML-friendly escaped string for the POST param of given name, or empty. * HTML-friendly escaped string for the POST param of given name, or empty.
* @param string $name * @param string $name
* @return string * @return string
*/ */
function value($name) public function value(string $name): string
{ {
return htmlspecialchars($this->string($name)); return htmlspecialchars($this->string($name));
} }
@ -63,7 +62,7 @@ class Posted {
* @param string $name * @param string $name
* @return string * @return string
*/ */
function string($name) public function string(string $name): string
{ {
return strval($this->raw($name)); return strval($this->raw($name));
} }
@ -76,7 +75,7 @@ class Posted {
* @param string $name * @param string $name
* @return mixed * @return mixed
*/ */
function raw($name) public function raw(string $name)
{ {
if (isset($_POST[$name])) { if (isset($_POST[$name])) {
return $this->dequote($_POST[$name]); return $this->dequote($_POST[$name]);
@ -91,13 +90,13 @@ class Posted {
* @param mixed $val * @param mixed $val
* @return mixed * @return mixed
*/ */
function dequote($val) public function dequote($val)
{ {
if (get_magic_quotes_gpc()) { if (get_magic_quotes_gpc()) {
if (is_string($val)) { if (is_string($val)) {
return stripslashes($val); return stripslashes($val);
} else if (is_array($val)) { } elseif (is_array($val)) {
return array_map(array($this, 'dequote'), $val); return array_map([$this, 'dequote'], $val);
} }
} }
return $val; return $val;
@ -115,7 +114,7 @@ class WebInstaller extends Installer
* *
* @return void * @return void
*/ */
function main() public function main()
{ {
if (!$this->checkPrereqs()) { if (!$this->checkPrereqs()) {
$this->warning(_('Please fix the above stated problems and refresh this page to continue installing.')); $this->warning(_('Please fix the above stated problems and refresh this page to continue installing.'));
@ -131,8 +130,10 @@ class WebInstaller extends Installer
/** /**
* Web implementation of warning output * Web implementation of warning output
* @param string $message
* @param string $submessage
*/ */
function warning($message, $submessage='') public function warning(string $message, string $submessage = '')
{ {
print "<p class=\"error\">$message</p>\n"; print "<p class=\"error\">$message</p>\n";
if ($submessage != '') { if ($submessage != '') {
@ -142,43 +143,48 @@ class WebInstaller extends Installer
/** /**
* Web implementation of status output * Web implementation of status output
* @param string $status
* @param bool $error
*/ */
function updateStatus($status, $error=false) public function updateStatus(string $status, bool $error = false)
{ {
echo '<li' . ($error ? ' class="error"': '' ) . ">$status</li>"; echo '<li' . ($error ? ' class="error"' : '') . ">$status</li>";
} }
/** /**
* Show the web form! * Show the web form!
*/ */
function showForm() public function showForm()
{ {
global $dbModules; global $dbModules;
$post = new Posted(); $post = new Posted();
$dbRadios = ''; $dbRadios = '';
$dbtype = $post->raw('dbtype'); $dbtype = $post->raw('dbtype');
foreach (self::$dbModules as $type => $info) { foreach (self::$dbModules as $type => $info) {
if ($this->checkExtension($info['check_module'])) { if (extension_loaded($info['check_module'])) {
if ($dbtype == null || $dbtype == $type) { if ($dbtype == null || $dbtype == $type) {
$checked = 'checked="checked" '; $checked = 'checked="checked" ';
$dbtype = $type; // if we didn't have one checked, hit the first $dbtype = $type; // if we didn't have one checked, hit the first
} else { } else {
$checked = ''; $checked = '';
} }
$dbRadios .= sprintf('<input type="radio" name="dbtype" id="dbtype-%1$s" value="%1$s" %2$s/>%3$s<br />', $dbRadios .= sprintf(
htmlspecialchars($type), $checked, '<input type="radio" name="dbtype" id="dbtype-%1$s" value="%1$s" %2$s/>%3$s<br>',
htmlspecialchars($info['name'])); htmlspecialchars($type),
$checked,
htmlspecialchars($info['name'])
);
} }
} }
$ssl = array('always'=>null, 'never'=>null); $ssl = ['always' => null, 'never' => null];
if (!empty($_SERVER['HTTPS'])) { if (!empty($_SERVER['HTTPS'])) {
$ssl['always'] = 'checked="checked"'; $ssl['always'] = 'checked="checked"';
} else { } else {
$ssl['never'] = 'checked="checked"'; $ssl['never'] = 'checked="checked"';
} }
echo<<<E_O_T echo <<<E_O_T
<form method="post" action="install.php" class="form_settings" id="form_install"> <form method="post" action="install.php" class="form_settings" id="form_install">
<fieldset> <fieldset>
<fieldset id="settings_site"> <fieldset id="settings_site">
@ -186,19 +192,19 @@ class WebInstaller extends Installer
<ul class="form_data"> <ul class="form_data">
<li> <li>
<label for="sitename">Site name</label> <label for="sitename">Site name</label>
<input type="text" id="sitename" name="sitename" value="{$post->value('sitename')}" /> <input type="text" id="sitename" name="sitename" value="{$post->value('sitename')}">
<p class="form_guide">The name of your site</p> <p class="form_guide">The name of your site</p>
</li> </li>
<li> <li>
<label for="fancy-enable">Fancy URLs</label> <label for="fancy-enable">Fancy URLs</label>
<input type="radio" name="fancy" id="fancy-enable" value="enable" checked='checked' /> enable<br /> <input type="radio" name="fancy" id="fancy-enable" value="enable" checked='checked'> enable<br>
<input type="radio" name="fancy" id="fancy-disable" value="" /> disable<br /> <input type="radio" name="fancy" id="fancy-disable" value=""> disable<br>
<p class="form_guide" id='fancy-form_guide'>Enable fancy (pretty) URLs. Auto-detection failed, it depends on Javascript.</p> <p class="form_guide" id='fancy-form_guide'>Enable fancy (pretty) URLs. Auto-detection failed, it depends on Javascript.</p>
</li> </li>
<li> <li>
<label for="ssl">Server SSL</label> <label for="ssl">Server SSL</label>
<input type="radio" name="ssl" id="ssl-always" value="always" {$ssl['always']} /> enable<br /> <input type="radio" name="ssl" id="ssl-always" value="always" {$ssl['always']}> enable<br>
<input type="radio" name="ssl" id="ssl-never" value="never" {$ssl['never']} /> disable<br /> <input type="radio" name="ssl" id="ssl-never" value="never" {$ssl['never']}> disable<br>
<p class="form_guide" id="ssl-form_guide">Enabling SSL (https://) requires extra webserver configuration and certificate generation not offered by this installation.</p> <p class="form_guide" id="ssl-form_guide">Enabling SSL (https://) requires extra webserver configuration and certificate generation not offered by this installation.</p>
</li> </li>
</ul> </ul>
@ -209,7 +215,7 @@ class WebInstaller extends Installer
<ul class="form_data"> <ul class="form_data">
<li> <li>
<label for="host">Hostname</label> <label for="host">Hostname</label>
<input type="text" id="host" name="host" value="{$post->value('host')}" /> <input type="text" id="host" name="host" value="{$post->value('host')}">
<p class="form_guide">Database hostname</p> <p class="form_guide">Database hostname</p>
</li> </li>
<li> <li>
@ -219,17 +225,17 @@ class WebInstaller extends Installer
</li> </li>
<li> <li>
<label for="database">Name</label> <label for="database">Name</label>
<input type="text" id="database" name="database" value="{$post->value('database')}" /> <input type="text" id="database" name="database" value="{$post->value('database')}">
<p class="form_guide">Database name</p> <p class="form_guide">Database name</p>
</li> </li>
<li> <li>
<label for="dbusername">DB username</label> <label for="dbusername">DB username</label>
<input type="text" id="dbusername" name="dbusername" value="{$post->value('dbusername')}" /> <input type="text" id="dbusername" name="dbusername" value="{$post->value('dbusername')}">
<p class="form_guide">Database username</p> <p class="form_guide">Database username</p>
</li> </li>
<li> <li>
<label for="dbpassword">DB password</label> <label for="dbpassword">DB password</label>
<input type="password" id="dbpassword" name="dbpassword" value="{$post->value('dbpassword')}" /> <input type="password" id="dbpassword" name="dbpassword" value="{$post->value('dbpassword')}">
<p class="form_guide">Database password (optional)</p> <p class="form_guide">Database password (optional)</p>
</li> </li>
</ul> </ul>
@ -240,21 +246,21 @@ class WebInstaller extends Installer
<ul class="form_data"> <ul class="form_data">
<li> <li>
<label for="admin_nickname">Administrator nickname</label> <label for="admin_nickname">Administrator nickname</label>
<input type="text" id="admin_nickname" name="admin_nickname" value="{$post->value('admin_nickname')}" /> <input type="text" id="admin_nickname" name="admin_nickname" value="{$post->value('admin_nickname')}">
<p class="form_guide">Nickname for the initial user (administrator)</p> <p class="form_guide">Nickname for the initial user (administrator)</p>
</li> </li>
<li> <li>
<label for="admin_password">Administrator password</label> <label for="admin_password">Administrator password</label>
<input type="password" id="admin_password" name="admin_password" value="{$post->value('admin_password')}" /> <input type="password" id="admin_password" name="admin_password" value="{$post->value('admin_password')}">
<p class="form_guide">Password for the initial user (administrator)</p> <p class="form_guide">Password for the initial user (administrator)</p>
</li> </li>
<li> <li>
<label for="admin_password2">Confirm password</label> <label for="admin_password2">Confirm password</label>
<input type="password" id="admin_password2" name="admin_password2" value="{$post->value('admin_password2')}" /> <input type="password" id="admin_password2" name="admin_password2" value="{$post->value('admin_password2')}">
</li> </li>
<li> <li>
<label for="admin_email">Administrator e-mail</label> <label for="admin_email">Administrator e-mail</label>
<input id="admin_email" name="admin_email" value="{$post->value('admin_email')}" /> <input id="admin_email" name="admin_email" value="{$post->value('admin_email')}">
<p class="form_guide">Optional email address for the initial user (administrator)</p> <p class="form_guide">Optional email address for the initial user (administrator)</p>
</li> </li>
</ul> </ul>
@ -274,7 +280,7 @@ class WebInstaller extends Installer
</li> </li>
</ul> </ul>
</fieldset> </fieldset>
<input type="submit" name="submit" class="submit" value="Submit" /> <input type="submit" name="submit" class="submit" value="Submit">
</fieldset> </fieldset>
</form> </form>
@ -285,7 +291,7 @@ E_O_T;
* Handle a POST submission... if we have valid input, start the install! * Handle a POST submission... if we have valid input, start the install!
* Otherwise shows the form along with any error messages. * Otherwise shows the form along with any error messages.
*/ */
function handlePost() public function handlePost()
{ {
echo <<<STR echo <<<STR
<dl class="system_notice"> <dl class="system_notice">
@ -311,23 +317,23 @@ STR;
* Read and validate input data. * Read and validate input data.
* May output side effects. * May output side effects.
* *
* @return boolean success * @return bool success
*/ */
function prepare() public function prepare(): bool
{ {
$post = new Posted(); $post = new Posted();
$this->host = $post->string('host'); $this->host = $post->string('host');
$this->dbtype = $post->string('dbtype'); $this->dbtype = $post->string('dbtype');
$this->database = $post->string('database'); $this->database = $post->string('database');
$this->username = $post->string('dbusername'); $this->username = $post->string('dbusername');
$this->password = $post->string('dbpassword'); $this->password = $post->string('dbpassword');
$this->sitename = $post->string('sitename'); $this->sitename = $post->string('sitename');
$this->fancy = (bool)$post->string('fancy'); $this->fancy = (bool)$post->string('fancy');
$this->adminNick = strtolower($post->string('admin_nickname')); $this->adminNick = strtolower($post->string('admin_nickname'));
$this->adminPass = $post->string('admin_password'); $this->adminPass = $post->string('admin_password');
$adminPass2 = $post->string('admin_password2'); $adminPass2 = $post->string('admin_password2');
$this->adminEmail = $post->string('admin_email'); $this->adminEmail = $post->string('admin_email');
$this->siteProfile = $post->string('site_profile'); $this->siteProfile = $post->string('site_profile');
@ -350,7 +356,7 @@ STR;
$fail = true; $fail = true;
} }
if (!in_array($this->ssl, array('never', 'always'))) { if (!in_array($this->ssl, ['never', 'always'])) {
$this->updateStatus("Bad value for server SSL enabling."); $this->updateStatus("Bad value for server SSL enabling.");
$fail = true; $fail = true;
} }
@ -361,57 +367,53 @@ STR;
return !$fail; return !$fail;
} }
} }
?> ?>
<?php echo"<?"; ?> xml version="1.0" encoding="UTF-8" <?php echo "?>"; ?> <!DOCTYPE html>
<!DOCTYPE html <html lang="en">
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" <head>
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <title>Install GNU social</title>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en_US" lang="en_US"> <link rel="shortcut icon" href="favicon.ico">
<head> <link rel="stylesheet" type="text/css" href="theme/base/css/display.css" media="screen, projection, tv">
<title>Install GNU social</title> <link rel="stylesheet" type="text/css" href="theme/neo/css/display.css" media="screen, projection, tv">
<link rel="shortcut icon" href="favicon.ico"/> <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" type="text/css" href="theme/base/css/display.css" media="screen, projection, tv"/> <script src="js/extlib/jquery.js"></script>
<link rel="stylesheet" type="text/css" href="theme/neo/css/display.css" media="screen, projection, tv"/> <script src="js/install.js"></script>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> </head>
<script src="js/extlib/jquery.js"></script> <body id="install">
<script src="js/install.js"></script> <div id="wrap">
</head> <div id="header">
<body id="install"> <address id="site_contact" class="h-card">
<div id="wrap"> <a class="u-url p-name home bookmark org" href=".">
<div id="header"> <img class="logo u-photo" src="theme/neo/logo.png" alt="GNU social"/>
<address id="site_contact" class="h-card"> GNU social
<a class="u-url p-name home bookmark org" href="."> </a>
<img class="logo u-photo" src="theme/neo/logo.png" alt="GNU social"/> </address>
GNU social <div id="site_nav_global_primary"></div>
</a> </div>
</address> <div id="core">
<div id="site_nav_global_primary"></div> <div id="aside_primary_wrapper">
</div> <div id="content_wrapper">
<div id="core"> <div id="site_nav_local_views_wrapper">
<div id="aside_primary_wrapper"> <div id="site_nav_local_views"></div>
<div id="content_wrapper">
<div id="site_nav_local_views_wrapper">
<div id="site_nav_local_views"></div>
<div id="content"> <div id="content">
<div id="content_inner"> <div id="content_inner">
<h1>Install GNU social</h1> <h1>Install GNU social</h1>
<?php <?php
$installer = new WebInstaller(); $installer = new WebInstaller();
$installer->main(); $installer->main();
?> ?>
</div> </div>
</div>
<div id="aside_primary" class="aside"></div>
</div> </div>
<div id="aside_primary" class="aside"></div>
</div>
</div>
</div>
</div> </div>
<div id="footer"></div>
</div> </div>
</body> </div>
<div id="footer"></div>
</div>
</body>
</html> </html>

View File

@ -1,37 +1,36 @@
#!/usr/bin/env php #!/usr/bin/env php
<?php <?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social 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.
//
// GNU social 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 GNU social. If not, see <http://www.gnu.org/licenses/>.
/** /**
* StatusNet - the distributed open-source microblogging tool * CLI Installer
* Copyright (C) 2010, StatusNet, Inc.
* *
* This program is free software: you can redistribute it and/or modify * @package Installation
* it under the terms of the GNU Affero General Public License as published by * @author Brion Vibber <brion@pobox.com>
* the Free Software Foundation, either version 3 of the License, or * @author Mikael Nordfeldth <mmn@hethane.se>
* (at your option) any later version. * @author Diogo Cordeiro <diogo@fc.up.pt>
* * @copyright 2019 Free Software Foundation, Inc http://www.fsf.org
* This program is distributed in the hope that it will be useful, * @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
* 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 <http://www.gnu.org/licenses/>.
*
* @category Installation
* @package Installation
*
* @author Brion Vibber <brion@status.net>
* @author Mikael Nordfeldth <mmn@hethane.se>
* @license GNU Affero General Public License http://www.gnu.org/licenses/
* @version 1.1.x
* @link http://status.net
*/ */
if (php_sapi_name() !== 'cli') { if (php_sapi_name() !== 'cli') {
exit(1); exit(1);
} }
define('INSTALLDIR', dirname(dirname(__FILE__))); define('INSTALLDIR', dirname(__DIR__));
set_include_path(get_include_path() . PATH_SEPARATOR . INSTALLDIR . '/extlib'); set_include_path(get_include_path() . PATH_SEPARATOR . INSTALLDIR . '/extlib');
require_once INSTALLDIR . '/lib/installer.php'; require_once INSTALLDIR . '/lib/installer.php';
@ -43,16 +42,16 @@ class CliInstaller extends Installer
/** /**
* Go for it! * Go for it!
* @return boolean success * @return bool success
*/ */
function main() public function main(): bool
{ {
if ($this->prepare()) { if ($this->prepare()) {
if (!$this->checkPrereqs()) { if (!$this->checkPrereqs()) {
return false; return false;
} }
return $this->handle(); return $this->handle();
} else { } else {
$this->showHelp(); $this->showHelp();
return false; return false;
} }
@ -60,23 +59,23 @@ class CliInstaller extends Installer
/** /**
* Get our input parameters... * Get our input parameters...
* @return boolean success * @return bool success
*/ */
function prepare() public function prepare(): bool
{ {
$shortoptions = 'qvh'; $shortoptions = 'qvh';
$longoptions = array('quiet', 'verbose', 'help', 'skip-config'); $longoptions = ['quiet', 'verbose', 'help', 'skip-config'];
$map = array( $map = [
'-s' => 'server', '-s' => 'server',
'--server' => 'server', '--server' => 'server',
'-p' => 'path', '-p' => 'path',
'--path' => 'path', '--path' => 'path',
'--sitename' => 'sitename', '--sitename' => 'sitename',
'--fancy' => 'fancy', '--fancy' => 'fancy',
'--ssl' => 'ssl', '--ssl' => 'ssl',
'--dbtype' => 'dbtype', '--dbtype' => 'dbtype',
'--host' => 'host', '--host' => 'host',
'--database' => 'database', '--database' => 'database',
'--username' => 'username', '--username' => 'username',
'--password' => 'password', '--password' => 'password',
@ -86,7 +85,7 @@ class CliInstaller extends Installer
'--admin-email' => 'adminEmail', '--admin-email' => 'adminEmail',
'--site-profile' => 'siteProfile' '--site-profile' => 'siteProfile'
); ];
foreach ($map as $arg => $target) { foreach ($map as $arg => $target) {
if (substr($arg, 0, 2) == '--') { if (substr($arg, 0, 2) == '--') {
$longoptions[] = substr($arg, 2) . '='; $longoptions[] = substr($arg, 2) . '=';
@ -116,13 +115,13 @@ class CliInstaller extends Installer
if ($arg == '--fancy') { if ($arg == '--fancy') {
$this->$var = ($option[1] != 'false') && ($option[1] != 'no'); $this->$var = ($option[1] != 'false') && ($option[1] != 'no');
} }
} else if ($arg == '--skip-config') { } elseif ($arg == '--skip-config') {
$this->skipConfig = true; $this->skipConfig = true;
} else if ($arg == 'q' || $arg == '--quiet') { } elseif ($arg == 'q' || $arg == '--quiet') {
$this->verbose = false; $this->verbose = false;
} else if ($arg == 'v' || $arg == '--verbose') { } elseif ($arg == 'v' || $arg == '--verbose') {
$this->verbose = true; $this->verbose = true;
} else if ($arg == 'h' || $arg == '--help') { } elseif ($arg == 'h' || $arg == '--help') {
// will go back to show help // will go back to show help
return false; return false;
} }
@ -146,15 +145,15 @@ class CliInstaller extends Installer
return !$fail; return !$fail;
} }
function handle() public function handle()
{ {
return $this->doInstall(); return $this->doInstall();
} }
function showHelp() public function showHelp()
{ {
echo <<<END_HELP echo <<<END_HELP
install_cli.php - StatusNet command-line installer install_cli.php - GNU social command-line installer
-s --server=<name> Use <name> as server name (required) -s --server=<name> Use <name> as server name (required)
-p --path=<path> Use <path> as path name -p --path=<path> Use <path> as path name
@ -189,7 +188,11 @@ install_cli.php - StatusNet command-line installer
END_HELP; END_HELP;
} }
function warning($message, $submessage='') /**
* @param string $message
* @param string $submessage
*/
public function warning(string $message, string $submessage = '')
{ {
print $this->html2text($message) . "\n"; print $this->html2text($message) . "\n";
if ($submessage != '') { if ($submessage != '') {
@ -198,7 +201,11 @@ END_HELP;
print "\n"; print "\n";
} }
function updateStatus($status, $error=false) /**
* @param string $status
* @param bool $error
*/
public function updateStatus(string $status, bool $error = false)
{ {
if ($this->verbose || $error) { if ($this->verbose || $error) {
if ($error) { if ($error) {
@ -209,12 +216,18 @@ END_HELP;
} }
} }
private function html2text($html) /**
* @param string $html
* @return string
*/
private function html2text(string $html): string
{ {
// break out any links for text legibility // break out any links for text legibility
$breakout = preg_replace('/<a[^>+]\bhref="(.*)"[^>]*>(.*)<\/a>/', $breakout = preg_replace(
'\2 &lt;\1&gt;', '/<a[^>+]\bhref="(.*)"[^>]*>(.*)<\/a>/',
$html); '\2 &lt;\1&gt;',
$html
);
return html_entity_decode(strip_tags($breakout), ENT_QUOTES, 'UTF-8'); return html_entity_decode(strip_tags($breakout), ENT_QUOTES, 'UTF-8');
} }
} }