2018-08-20 16:15:39 -04:00
< ? php
/**
2020-02-09 09:45:36 -05:00
* @ copyright Copyright ( C ) 2020 , Friendica
*
* @ license GNU AGPL version 3 or any later version
*
* This program is free software : you can redistribute it and / or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation , either version 3 of the
* License , or ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU Affero General Public License for more details .
*
* You should have received a copy of the GNU Affero General Public License
* along with this program . If not , see < https :// www . gnu . org / licenses />.
*
2018-08-20 16:15:39 -04:00
*/
2020-02-09 09:45:36 -05:00
2018-08-20 16:15:39 -04:00
namespace Friendica\Core ;
use DOMDocument ;
use Exception ;
2020-01-19 16:23:44 -05:00
use Friendica\Core\Config\Cache ;
2019-07-28 16:06:33 -04:00
use Friendica\Database\Database ;
2018-10-29 13:44:39 -04:00
use Friendica\Database\DBStructure ;
2020-01-19 10:29:55 -05:00
use Friendica\DI ;
2020-03-04 16:07:05 -05:00
use Friendica\Network\HTTPRequest ;
2019-10-17 21:26:15 -04:00
use Friendica\Util\Images ;
2018-11-08 10:22:20 -05:00
use Friendica\Util\Strings ;
2018-08-20 16:15:39 -04:00
/**
* Contains methods for installation purpose of Friendica
*/
2018-10-29 13:44:39 -04:00
class Installer
2018-08-20 16:15:39 -04:00
{
2018-10-29 13:44:39 -04:00
// Default values for the install page
const DEFAULT_LANG = 'en' ;
const DEFAULT_TZ = 'America/Los_Angeles' ;
const DEFAULT_HOST = 'localhost' ;
2018-08-20 16:15:39 -04:00
/**
2018-10-07 20:15:27 -04:00
* @ var array the check outcomes
*/
private $checks ;
2018-10-30 06:30:19 -04:00
/**
* @ var string The path to the PHP binary
*/
private $phppath = null ;
2018-10-07 20:15:27 -04:00
/**
* Returns all checks made
2018-08-20 16:15:39 -04:00
*
2018-10-07 20:15:27 -04:00
* @ return array the checks
*/
public function getChecks ()
{
return $this -> checks ;
}
2018-10-30 06:30:19 -04:00
/**
* Returns the PHP path
*
* @ return string the PHP Path
2019-01-06 16:06:53 -05:00
* @ throws \Friendica\Network\HTTPException\InternalServerErrorException
2018-10-30 06:30:19 -04:00
*/
public function getPHPPath ()
{
// if not set, determine the PHP path
if ( ! isset ( $this -> phppath )) {
$this -> checkPHP ();
$this -> resetChecks ();
}
return $this -> phppath ;
}
2018-10-07 20:15:27 -04:00
/**
* Resets all checks
*/
public function resetChecks ()
{
$this -> checks = [];
}
/**
* Install constructor .
2018-08-20 16:15:39 -04:00
*
*/
2018-10-07 20:15:27 -04:00
public function __construct ()
2018-08-20 16:15:39 -04:00
{
2018-10-07 20:15:27 -04:00
$this -> checks = [];
}
2018-08-20 16:15:39 -04:00
2018-10-07 20:15:27 -04:00
/**
* Checks the current installation environment . There are optional and mandatory checks .
*
2019-01-06 16:06:53 -05:00
* @ param string $baseurl The baseurl of Friendica
* @ param string $phpath Optional path to the PHP binary
2018-10-07 20:15:27 -04:00
*
* @ return bool if the check succeed
2019-01-06 16:06:53 -05:00
* @ throws \Friendica\Network\HTTPException\InternalServerErrorException
2018-10-07 20:15:27 -04:00
*/
2018-10-29 13:44:39 -04:00
public function checkEnvironment ( $baseurl , $phpath = null )
2018-10-07 20:15:27 -04:00
{
$returnVal = true ;
2018-08-20 16:15:39 -04:00
2018-10-07 20:15:27 -04:00
if ( isset ( $phpath )) {
if ( ! $this -> checkPHP ( $phpath )) {
$returnVal = false ;
}
}
2018-08-20 16:15:39 -04:00
2018-10-07 20:15:27 -04:00
if ( ! $this -> checkFunctions ()) {
$returnVal = false ;
}
2018-08-20 16:15:39 -04:00
2018-10-07 20:15:27 -04:00
if ( ! $this -> checkImagick ()) {
$returnVal = false ;
}
2018-08-20 16:15:39 -04:00
2018-10-07 20:15:27 -04:00
if ( ! $this -> checkLocalIni ()) {
$returnVal = false ;
}
2018-08-20 16:15:39 -04:00
2018-10-07 20:15:27 -04:00
if ( ! $this -> checkSmarty3 ()) {
$returnVal = false ;
}
2018-08-20 16:15:39 -04:00
2018-10-07 20:15:27 -04:00
if ( ! $this -> checkKeys ()) {
$returnVal = false ;
}
2018-08-20 16:15:39 -04:00
2018-10-29 09:10:45 -04:00
if ( ! $this -> checkHtAccess ( $baseurl )) {
2018-10-07 20:15:27 -04:00
$returnVal = false ;
}
2018-08-20 16:15:39 -04:00
2018-10-07 20:15:27 -04:00
return $returnVal ;
2018-08-20 16:15:39 -04:00
}
/**
* Executes the installation of Friendica in the given environment .
2018-11-25 01:44:09 -05:00
* - Creates `config/local.config.php`
2018-08-20 16:15:39 -04:00
* - Installs Database Structure
*
2020-01-19 16:23:44 -05:00
* @ param Cache $configCache The config cache with all config relevant information
2018-10-07 20:15:27 -04:00
*
2018-10-29 13:44:39 -04:00
* @ return bool true if the config was created , otherwise false
2019-01-06 16:06:53 -05:00
* @ throws \Friendica\Network\HTTPException\InternalServerErrorException
2018-08-20 16:15:39 -04:00
*/
2020-01-19 16:23:44 -05:00
public function createConfig ( Cache $configCache )
2018-08-20 16:15:39 -04:00
{
2019-03-26 17:04:31 -04:00
$basepath = $configCache -> get ( 'system' , 'basepath' );
2018-11-25 01:44:09 -05:00
$tpl = Renderer :: getMarkupTemplate ( 'local.config.tpl' );
2018-10-31 10:35:50 -04:00
$txt = Renderer :: replaceMacros ( $tpl , [
2019-03-14 05:00:05 -04:00
'$dbhost' => $configCache -> get ( 'database' , 'hostname' ),
'$dbuser' => $configCache -> get ( 'database' , 'username' ),
'$dbpass' => $configCache -> get ( 'database' , 'password' ),
'$dbdata' => $configCache -> get ( 'database' , 'database' ),
2019-03-26 17:04:31 -04:00
'$phpath' => $configCache -> get ( 'config' , 'php_path' ),
2019-03-14 05:00:05 -04:00
'$adminmail' => $configCache -> get ( 'config' , 'admin_email' ),
2019-03-26 17:04:31 -04:00
'$hostname' => $configCache -> get ( 'config' , 'hostname' ),
2019-03-14 05:00:05 -04:00
2019-03-26 17:04:31 -04:00
'$urlpath' => $configCache -> get ( 'system' , 'urlpath' ),
2019-04-14 08:40:26 -04:00
'$baseurl' => $configCache -> get ( 'system' , 'url' ),
2019-03-26 17:04:31 -04:00
'$sslpolicy' => $configCache -> get ( 'system' , 'ssl_policy' ),
'$basepath' => $basepath ,
2019-03-14 05:00:05 -04:00
'$timezone' => $configCache -> get ( 'system' , 'default_timezone' ),
'$language' => $configCache -> get ( 'system' , 'language' ),
2019-06-06 18:36:10 -04:00
]);
2018-08-20 16:15:39 -04:00
2018-11-25 01:44:09 -05:00
$result = file_put_contents ( $basepath . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'local.config.php' , $txt );
2018-08-27 00:15:55 -04:00
2018-08-20 16:15:39 -04:00
if ( ! $result ) {
2020-01-18 14:52:34 -05:00
$this -> addCheck ( DI :: l10n () -> t ( 'The database configuration file "config/local.config.php" could not be written. Please use the enclosed text to create a configuration file in your web server root.' ), false , false , htmlentities ( $txt , ENT_COMPAT , 'UTF-8' ));
2018-08-20 16:15:39 -04:00
}
2018-10-29 13:44:39 -04:00
return $result ;
}
/***
* Installs the DB - Scheme for Friendica
*
2019-02-03 16:46:50 -05:00
* @ param string $basePath The base path of this application
*
2018-10-29 13:44:39 -04:00
* @ return bool true if the installation was successful , otherwise false
2019-01-06 16:06:53 -05:00
* @ throws Exception
2018-10-29 13:44:39 -04:00
*/
2019-02-03 16:46:50 -05:00
public function installDatabase ( $basePath )
2018-10-29 13:44:39 -04:00
{
2019-02-03 16:46:50 -05:00
$result = DBStructure :: update ( $basePath , false , true , true );
2018-10-29 13:44:39 -04:00
if ( $result ) {
2020-01-18 14:52:34 -05:00
$txt = DI :: l10n () -> t ( 'You may need to import the file "database.sql" manually using phpmyadmin or mysql.' ) . EOL ;
$txt .= DI :: l10n () -> t ( 'Please see the file "INSTALL.txt".' );
2018-10-29 13:44:39 -04:00
$this -> addCheck ( $txt , false , true , htmlentities ( $result , ENT_COMPAT , 'UTF-8' ));
return false ;
}
return true ;
2018-08-20 16:15:39 -04:00
}
/**
* Adds new checks to the array $checks
*
* @ param string $title The title of the current check
* @ param bool $status 1 = check passed , 0 = check not passed
* @ param bool $required 1 = check is mandatory , 0 = check is optional
* @ param string $help A help - string for the current check
* @ param string $error_msg Optional . A error message , if the current check failed
*/
2018-10-07 20:15:27 -04:00
private function addCheck ( $title , $status , $required , $help , $error_msg = " " )
2018-08-20 16:15:39 -04:00
{
2018-10-07 20:15:27 -04:00
array_push ( $this -> checks , [
2018-08-20 16:15:39 -04:00
'title' => $title ,
'status' => $status ,
'required' => $required ,
'help' => $help ,
'error_msg' => $error_msg ,
2018-10-07 20:15:27 -04:00
]);
2018-08-20 16:15:39 -04:00
}
/**
* PHP Check
*
* Checks the PHP environment .
*
* - Checks if a PHP binary is available
* - Checks if it is the CLI version
* - Checks if " register_argc_argv " is enabled
2019-01-06 16:06:53 -05:00
*
* @ param string $phppath Optional . The Path to the PHP - Binary
2018-10-07 20:15:27 -04:00
* @ param bool $required Optional . If set to true , the PHP - Binary has to exist ( Default false )
*
* @ return bool false if something required failed
2019-01-06 16:06:53 -05:00
* @ throws \Friendica\Network\HTTPException\InternalServerErrorException
2018-08-20 16:15:39 -04:00
*/
2018-10-07 20:15:27 -04:00
public function checkPHP ( $phppath = null , $required = false )
2018-08-20 16:15:39 -04:00
{
2018-10-30 06:30:19 -04:00
$passed3 = false ;
if ( ! isset ( $phppath )) {
$phppath = 'php' ;
}
$passed = file_exists ( $phppath );
if ( ! $passed ) {
$phppath = trim ( shell_exec ( 'which ' . $phppath ));
2018-10-07 20:15:27 -04:00
$passed = strlen ( $phppath );
2018-08-20 16:15:39 -04:00
}
2018-10-07 20:15:27 -04:00
2018-08-20 16:15:39 -04:00
$help = " " ;
if ( ! $passed ) {
2020-01-18 14:52:34 -05:00
$help .= DI :: l10n () -> t ( 'Could not find a command line version of PHP in the web server PATH.' ) . EOL ;
2020-06-15 13:47:23 -04:00
$help .= DI :: 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/stable/doc/Install.md#set-up-the-worker'>'Setup the worker'</a> " ) . EOL ;
2018-08-20 16:15:39 -04:00
$help .= EOL . EOL ;
2018-10-31 10:44:06 -04:00
$tpl = Renderer :: getMarkupTemplate ( 'field_input.tpl' );
2019-04-14 08:05:48 -04:00
/// @todo Separate backend Installer class and presentation layer/view
2018-10-31 10:35:50 -04:00
$help .= Renderer :: replaceMacros ( $tpl , [
2020-01-18 14:52:34 -05:00
'$field' => [ 'config-php_path' , DI :: l10n () -> t ( 'PHP executable path' ), $phppath , DI :: l10n () -> t ( 'Enter full path to php executable. You can leave this blank to continue the installation.' )],
2018-08-20 16:15:39 -04:00
]);
2018-10-07 20:15:27 -04:00
$phppath = " " ;
2018-08-20 16:15:39 -04:00
}
2020-01-18 14:52:34 -05:00
$this -> addCheck ( DI :: l10n () -> t ( 'Command line PHP' ) . ( $passed ? " (<tt> $phppath </tt>) " : " " ), $passed , false , $help );
2018-08-20 16:15:39 -04:00
if ( $passed ) {
2018-10-07 20:15:27 -04:00
$cmd = " $phppath -v " ;
2018-08-20 16:15:39 -04:00
$result = trim ( shell_exec ( $cmd ));
$passed2 = ( strpos ( $result , " (cli) " ) !== false );
list ( $result ) = explode ( " \n " , $result );
$help = " " ;
if ( ! $passed2 ) {
2020-01-18 14:52:34 -05:00
$help .= DI :: l10n () -> t ( " PHP executable is not the php cli binary \x28 could be cgi-fgci version \x29 " ) . EOL ;
$help .= DI :: l10n () -> t ( 'Found PHP version: ' ) . " <tt> $result </tt> " ;
2018-08-20 16:15:39 -04:00
}
2020-01-18 14:52:34 -05:00
$this -> addCheck ( DI :: l10n () -> t ( 'PHP cli binary' ), $passed2 , true , $help );
2018-10-07 20:15:27 -04:00
} else {
// return if it was required
2018-10-30 06:30:19 -04:00
return ! $required ;
2018-08-20 16:15:39 -04:00
}
if ( $passed2 ) {
2018-11-08 10:22:20 -05:00
$str = Strings :: getRandomName ( 8 );
2018-11-28 23:10:05 -05:00
$cmd = " $phppath bin/testargs.php $str " ;
2018-08-20 16:15:39 -04:00
$result = trim ( shell_exec ( $cmd ));
$passed3 = $result == $str ;
$help = " " ;
if ( ! $passed3 ) {
2020-01-18 14:52:34 -05:00
$help .= DI :: l10n () -> t ( 'The command line version of PHP on your system does not have "register_argc_argv" enabled.' ) . EOL ;
$help .= DI :: l10n () -> t ( 'This is required for message delivery to work.' );
2018-10-07 20:15:27 -04:00
} else {
$this -> phppath = $phppath ;
2018-08-20 16:15:39 -04:00
}
2018-10-07 20:15:27 -04:00
2020-01-18 14:52:34 -05:00
$this -> addCheck ( DI :: l10n () -> t ( 'PHP register_argc_argv' ), $passed3 , true , $help );
2018-08-20 16:15:39 -04:00
}
2018-10-07 20:15:27 -04:00
// passed2 & passed3 are required if first check passed
return $passed2 && $passed3 ;
2018-08-20 16:15:39 -04:00
}
/**
* OpenSSL Check
*
* Checks the OpenSSL Environment
*
* - Checks , if the command " openssl_pkey_new " is available
*
2018-10-07 20:15:27 -04:00
* @ return bool false if something required failed
2018-08-20 16:15:39 -04:00
*/
2018-10-07 20:15:27 -04:00
public function checkKeys ()
2018-08-20 16:15:39 -04:00
{
$help = '' ;
$res = false ;
2018-10-07 20:15:27 -04:00
$status = true ;
2018-08-20 16:15:39 -04:00
if ( function_exists ( 'openssl_pkey_new' )) {
$res = openssl_pkey_new ([
'digest_alg' => 'sha1' ,
'private_key_bits' => 4096 ,
'encrypt_key' => false
]);
}
// Get private key
if ( ! $res ) {
2020-01-18 14:52:34 -05:00
$help .= DI :: l10n () -> t ( 'Error: the "openssl_pkey_new" function on this system is not able to generate encryption keys' ) . EOL ;
$help .= DI :: l10n () -> t ( 'If running under Windows, please see "http://www.php.net/manual/en/openssl.installation.php".' );
2018-10-07 20:15:27 -04:00
$status = false ;
}
2020-01-18 14:52:34 -05:00
$this -> addCheck ( DI :: l10n () -> t ( 'Generate encryption keys' ), $res , true , $help );
2018-10-07 20:15:27 -04:00
return $status ;
}
/**
* PHP basic function check
*
* @ param string $name The name of the function
* @ param string $title The ( localized ) title of the function
* @ param string $help The ( localized ) help of the function
* @ param boolean $required If true , this check is required
*
* @ return bool false , if the check failed
*/
private function checkFunction ( $name , $title , $help , $required )
{
$currHelp = '' ;
$status = true ;
if ( ! function_exists ( $name )) {
$currHelp = $help ;
$status = false ;
2018-08-20 16:15:39 -04:00
}
2018-10-07 20:15:27 -04:00
$this -> addCheck ( $title , $status , $required , $currHelp );
return $status || ( ! $status && ! $required );
2018-08-20 16:15:39 -04:00
}
/**
* PHP functions Check
*
* Checks the following PHP functions
* - libCurl
* - GD Graphics
* - OpenSSL
* - PDO or MySQLi
* - mb_string
* - XML
* - iconv
2019-02-16 16:13:19 -05:00
* - fileinfo
2018-08-20 16:15:39 -04:00
* - POSIX
*
2018-10-07 20:15:27 -04:00
* @ return bool false if something required failed
2018-08-20 16:15:39 -04:00
*/
2018-10-07 20:15:27 -04:00
public function checkFunctions ()
2018-08-20 16:15:39 -04:00
{
2018-10-07 20:15:27 -04:00
$returnVal = true ;
2018-08-20 16:15:39 -04:00
2018-10-07 20:15:27 -04:00
$help = '' ;
$status = true ;
2018-08-20 16:15:39 -04:00
if ( function_exists ( 'apache_get_modules' )) {
2018-10-07 20:15:27 -04:00
if ( ! in_array ( 'mod_rewrite' , apache_get_modules ())) {
2020-01-18 14:52:34 -05:00
$help = DI :: l10n () -> t ( 'Error: Apache webserver mod-rewrite module is required but not installed.' );
2018-10-07 20:15:27 -04:00
$status = false ;
$returnVal = false ;
2018-08-20 16:15:39 -04:00
}
}
2020-01-18 14:52:34 -05:00
$this -> addCheck ( DI :: l10n () -> t ( 'Apache mod_rewrite module' ), $status , true , $help );
2018-08-20 16:15:39 -04:00
2018-10-07 20:15:27 -04:00
$help = '' ;
$status = true ;
2018-08-20 16:15:39 -04:00
if ( ! function_exists ( 'mysqli_connect' ) && ! class_exists ( 'pdo' )) {
2018-10-07 20:15:27 -04:00
$status = false ;
2020-01-18 14:52:34 -05:00
$help = DI :: l10n () -> t ( 'Error: PDO or MySQLi PHP module required but not installed.' );
2018-10-07 20:15:27 -04:00
$returnVal = false ;
} else {
if ( ! function_exists ( 'mysqli_connect' ) && class_exists ( 'pdo' ) && ! in_array ( 'mysql' , \PDO :: getAvailableDrivers ())) {
$status = false ;
2020-01-18 14:52:34 -05:00
$help = DI :: l10n () -> t ( 'Error: The MySQL driver for PDO is not installed.' );
2018-10-07 20:15:27 -04:00
$returnVal = false ;
}
2018-08-20 16:15:39 -04:00
}
2020-01-18 14:52:34 -05:00
$this -> addCheck ( DI :: l10n () -> t ( 'PDO or MySQLi PHP module' ), $status , true , $help );
2018-08-20 16:15:39 -04:00
// check for XML DOM Documents being able to be generated
2018-10-07 20:15:27 -04:00
$help = '' ;
$status = true ;
2018-08-20 16:15:39 -04:00
try {
2019-01-07 12:09:10 -05:00
new DOMDocument ();
2018-08-20 16:15:39 -04:00
} catch ( Exception $e ) {
2020-01-18 14:52:34 -05:00
$help = DI :: l10n () -> t ( 'Error, XML PHP module required but not installed.' );
2018-10-07 20:15:27 -04:00
$status = false ;
$returnVal = false ;
2018-08-20 16:15:39 -04:00
}
2020-01-18 14:52:34 -05:00
$this -> addCheck ( DI :: l10n () -> t ( 'XML PHP module' ), $status , true , $help );
2018-10-07 20:15:27 -04:00
$status = $this -> checkFunction ( 'curl_init' ,
2020-01-18 14:52:34 -05:00
DI :: l10n () -> t ( 'libCurl PHP module' ),
DI :: l10n () -> t ( 'Error: libCURL PHP module required but not installed.' ),
2018-10-07 20:15:27 -04:00
true
);
$returnVal = $returnVal ? $status : false ;
$status = $this -> checkFunction ( 'imagecreatefromjpeg' ,
2020-01-18 14:52:34 -05:00
DI :: l10n () -> t ( 'GD graphics PHP module' ),
DI :: l10n () -> t ( 'Error: GD graphics PHP module with JPEG support required but not installed.' ),
2018-10-07 20:15:27 -04:00
true
);
$returnVal = $returnVal ? $status : false ;
$status = $this -> checkFunction ( 'openssl_public_encrypt' ,
2020-01-18 14:52:34 -05:00
DI :: l10n () -> t ( 'OpenSSL PHP module' ),
DI :: l10n () -> t ( 'Error: openssl PHP module required but not installed.' ),
2018-10-07 20:15:27 -04:00
true
);
$returnVal = $returnVal ? $status : false ;
$status = $this -> checkFunction ( 'mb_strlen' ,
2020-01-18 14:52:34 -05:00
DI :: l10n () -> t ( 'mb_string PHP module' ),
DI :: l10n () -> t ( 'Error: mb_string PHP module required but not installed.' ),
2018-10-07 20:15:27 -04:00
true
);
$returnVal = $returnVal ? $status : false ;
$status = $this -> checkFunction ( 'iconv_strlen' ,
2020-01-18 14:52:34 -05:00
DI :: l10n () -> t ( 'iconv PHP module' ),
DI :: l10n () -> t ( 'Error: iconv PHP module required but not installed.' ),
2018-10-07 20:15:27 -04:00
true
);
$returnVal = $returnVal ? $status : false ;
$status = $this -> checkFunction ( 'posix_kill' ,
2020-01-18 14:52:34 -05:00
DI :: l10n () -> t ( 'POSIX PHP module' ),
DI :: l10n () -> t ( 'Error: POSIX PHP module required but not installed.' ),
2018-10-07 20:15:27 -04:00
true
);
$returnVal = $returnVal ? $status : false ;
2018-12-22 17:04:47 -05:00
$status = $this -> checkFunction ( 'json_encode' ,
2020-01-18 14:52:34 -05:00
DI :: l10n () -> t ( 'JSON PHP module' ),
DI :: l10n () -> t ( 'Error: JSON PHP module required but not installed.' ),
2018-12-22 17:04:47 -05:00
true
);
$returnVal = $returnVal ? $status : false ;
2019-02-16 16:13:19 -05:00
$status = $this -> checkFunction ( 'finfo_open' ,
2020-01-18 14:52:34 -05:00
DI :: l10n () -> t ( 'File Information PHP module' ),
DI :: l10n () -> t ( 'Error: File Information PHP module required but not installed.' ),
2019-02-16 16:13:19 -05:00
true
);
$returnVal = $returnVal ? $status : false ;
2018-10-07 20:15:27 -04:00
return $returnVal ;
2018-08-20 16:15:39 -04:00
}
/**
2018-11-25 01:44:09 -05:00
* " config/local.config.php " - Check
2018-08-20 16:15:39 -04:00
*
2018-11-25 01:44:09 -05:00
* Checks if it ' s possible to create the " config/local.config.php "
2018-08-20 16:15:39 -04:00
*
2018-10-07 20:15:27 -04:00
* @ return bool false if something required failed
2018-08-20 16:15:39 -04:00
*/
2018-10-07 20:15:27 -04:00
public function checkLocalIni ()
2018-08-20 16:15:39 -04:00
{
$status = true ;
$help = " " ;
2018-11-25 01:44:09 -05:00
if (( file_exists ( 'config/local.config.php' ) && ! is_writable ( 'config/local.config.php' )) ||
( ! file_exists ( 'config/local.config.php' ) && ! is_writable ( '.' ))) {
2018-08-20 16:15:39 -04:00
$status = false ;
2020-01-18 14:52:34 -05:00
$help = DI :: l10n () -> t ( 'The web installer needs to be able to create a file called "local.config.php" in the "config" folder of your web server and it is unable to do so.' ) . EOL ;
$help .= DI :: l10n () -> t ( 'This is most often a permission setting, as the web server may not be able to write files in your folder - even if you can.' ) . EOL ;
$help .= DI :: l10n () -> t ( 'At the end of this procedure, we will give you a text to save in a file named local.config.php in your Friendica "config" folder.' ) . EOL ;
$help .= DI :: l10n () -> t ( 'You can alternatively skip this procedure and perform a manual installation. Please see the file "INSTALL.txt" for instructions.' ) . EOL ;
2018-08-20 16:15:39 -04:00
}
2020-01-18 14:52:34 -05:00
$this -> addCheck ( DI :: l10n () -> t ( 'config/local.config.php is writable' ), $status , false , $help );
2018-08-20 16:15:39 -04:00
2018-10-07 20:15:27 -04:00
// Local INI File is not required
return true ;
2018-08-20 16:15:39 -04:00
}
/**
* Smarty3 Template Check
*
* Checks , if the directory of Smarty3 is writable
*
2018-10-07 20:15:27 -04:00
* @ return bool false if something required failed
2018-08-20 16:15:39 -04:00
*/
2018-10-07 20:15:27 -04:00
public function checkSmarty3 ()
2018-08-20 16:15:39 -04:00
{
$status = true ;
$help = " " ;
if ( ! is_writable ( 'view/smarty3' )) {
$status = false ;
2020-01-18 14:52:34 -05:00
$help = DI :: l10n () -> t ( 'Friendica uses the Smarty3 template engine to render its web views. Smarty3 compiles templates to PHP to speed up rendering.' ) . EOL ;
$help .= DI :: l10n () -> t ( 'In order to store these compiled templates, the web server needs to have write access to the directory view/smarty3/ under the Friendica top level folder.' ) . EOL ;
$help .= DI :: l10n () -> t ( " Please ensure that the user that your web server runs as \x28 e.g. www-data \x29 has write access to this folder. " ) . EOL ;
$help .= DI :: l10n () -> t ( " Note: as a security measure, you should give the web server write access to view/smarty3/ only--not the template files \x28 .tpl \x29 that it contains. " ) . EOL ;
2018-08-20 16:15:39 -04:00
}
2020-01-18 14:52:34 -05:00
$this -> addCheck ( DI :: l10n () -> t ( 'view/smarty3 is writable' ), $status , true , $help );
2018-10-07 20:15:27 -04:00
return $status ;
2018-08-20 16:15:39 -04:00
}
/**
* " .htaccess " - Check
*
* Checks , if " url_rewrite " is enabled in the " .htaccess " file
*
2019-01-06 16:06:53 -05:00
* @ param string $baseurl The baseurl of the app
2018-10-07 20:15:27 -04:00
* @ return bool false if something required failed
2019-01-06 16:06:53 -05:00
* @ throws \Friendica\Network\HTTPException\InternalServerErrorException
2018-08-20 16:15:39 -04:00
*/
2018-10-29 09:10:45 -04:00
public function checkHtAccess ( $baseurl )
2018-08-20 16:15:39 -04:00
{
$status = true ;
$help = " " ;
$error_msg = " " ;
if ( function_exists ( 'curl_init' )) {
2020-03-04 16:07:05 -05:00
$fetchResult = HTTPRequest :: fetchUrlFull ( $baseurl . " /install/testrewrite " );
2018-08-20 16:15:39 -04:00
2018-11-08 11:28:29 -05:00
$url = Strings :: normaliseLink ( $baseurl . " /install/testrewrite " );
2018-10-29 09:10:45 -04:00
if ( $fetchResult -> getReturnCode () != 204 ) {
2020-03-04 16:07:05 -05:00
$fetchResult = HTTPRequest :: fetchUrlFull ( $url );
2018-08-20 16:15:39 -04:00
}
2018-10-29 09:10:45 -04:00
if ( $fetchResult -> getReturnCode () != 204 ) {
2018-08-20 16:15:39 -04:00
$status = false ;
2020-01-18 14:52:34 -05:00
$help = DI :: l10n () -> t ( 'Url rewrite in .htaccess is not working. Make sure you copied .htaccess-dist to .htaccess.' );
2018-08-20 16:15:39 -04:00
$error_msg = [];
2020-01-18 14:52:34 -05:00
$error_msg [ 'head' ] = DI :: l10n () -> t ( 'Error message from Curl when fetching' );
2018-10-10 15:20:30 -04:00
$error_msg [ 'url' ] = $fetchResult -> getRedirectUrl ();
$error_msg [ 'msg' ] = $fetchResult -> getError ();
2018-08-20 16:15:39 -04:00
}
2018-10-07 20:15:27 -04:00
2020-01-18 14:52:34 -05:00
$this -> addCheck ( DI :: l10n () -> t ( 'Url rewrite is working' ), $status , true , $help , $error_msg );
2018-08-20 16:15:39 -04:00
} else {
// cannot check modrewrite if libcurl is not installed
/// @TODO Maybe issue warning here?
}
2018-10-07 20:15:27 -04:00
return $status ;
2018-08-20 16:15:39 -04:00
}
/**
* Imagick Check
*
* Checks , if the imagick module is available
*
2018-10-07 20:15:27 -04:00
* @ return bool false if something required failed
2018-08-20 16:15:39 -04:00
*/
2018-10-07 20:15:27 -04:00
public function checkImagick ()
2018-08-20 16:15:39 -04:00
{
$imagick = false ;
$gif = false ;
if ( class_exists ( 'Imagick' )) {
$imagick = true ;
2019-10-17 21:26:15 -04:00
$supported = Images :: supportedTypes ();
2018-08-20 16:15:39 -04:00
if ( array_key_exists ( 'image/gif' , $supported )) {
$gif = true ;
}
}
2018-10-07 20:15:27 -04:00
if ( ! $imagick ) {
2020-01-18 14:52:34 -05:00
$this -> addCheck ( DI :: l10n () -> t ( 'ImageMagick PHP extension is not installed' ), $imagick , false , " " );
2018-08-20 16:15:39 -04:00
} else {
2020-01-18 14:52:34 -05:00
$this -> addCheck ( DI :: l10n () -> t ( 'ImageMagick PHP extension is installed' ), $imagick , false , " " );
2018-08-20 16:15:39 -04:00
if ( $imagick ) {
2020-01-18 14:52:34 -05:00
$this -> addCheck ( DI :: l10n () -> t ( 'ImageMagick supports GIF' ), $gif , false , " " );
2018-08-20 16:15:39 -04:00
}
}
2018-10-07 20:15:27 -04:00
// Imagick is not required
return true ;
2018-08-20 16:15:39 -04:00
}
2018-10-29 13:44:39 -04:00
/**
* Checking the Database connection and if it is available for the current installation
*
2019-08-12 12:13:58 -04:00
* @ param Database $dba
2018-10-29 13:44:39 -04:00
*
* @ return bool true if the check was successful , otherwise false
2019-01-06 16:06:53 -05:00
* @ throws Exception
2018-10-29 13:44:39 -04:00
*/
2019-07-28 16:06:33 -04:00
public function checkDB ( Database $dba )
2018-10-29 13:44:39 -04:00
{
2019-07-28 16:06:33 -04:00
$dba -> reconnect ();
2019-03-14 05:00:05 -04:00
2019-07-28 16:06:33 -04:00
if ( $dba -> isConnected ()) {
2018-10-30 06:30:19 -04:00
if ( DBStructure :: existsTable ( 'user' )) {
2020-01-18 14:52:34 -05:00
$this -> addCheck ( DI :: l10n () -> t ( 'Database already in use.' ), false , true , '' );
2018-10-29 13:44:39 -04:00
return false ;
}
2019-07-09 16:20:39 -04:00
} else {
2020-01-18 14:52:34 -05:00
$this -> addCheck ( DI :: l10n () -> t ( 'Could not connect to database.' ), false , true , '' );
2019-07-09 16:20:39 -04:00
return false ;
2018-10-29 13:44:39 -04:00
}
return true ;
}
2019-03-26 17:04:31 -04:00
/**
* Setup the default cache for a new installation
*
2020-01-19 16:23:44 -05:00
* @ param Cache $configCache The configuration cache
* @ param string $basePath The determined basepath
2019-03-26 17:04:31 -04:00
*
* @ throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
2020-01-19 16:23:44 -05:00
public function setUpCache ( Cache $configCache , $basePath )
2019-03-26 17:04:31 -04:00
{
$configCache -> set ( 'config' , 'php_path' , $this -> getPHPPath ());
$configCache -> set ( 'system' , 'basepath' , $basePath );
}
2018-08-20 16:15:39 -04:00
}