2014-02-08 18:40:22 +01:00
< ? php
/**
* PHP Server Monitor
* Monitor your servers and websites .
*
* This file is part of PHP Server Monitor .
* PHP Server Monitor is free software : you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* PHP Server Monitor 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 General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with PHP Server Monitor . If not , see < http :// www . gnu . org / licenses />.
*
* @ package phpservermon
* @ author Pepijn Over < pep @ neanderthal - technology . com >
* @ copyright Copyright ( c ) 2008 - 2014 Pepijn Over < pep @ neanderthal - technology . com >
* @ license http :// www . gnu . org / licenses / gpl . txt GNU GPL v3
* @ version Release : @ package_version @
2014-02-10 23:48:43 +01:00
* @ link http :// www . phpservermonitor . org /
2014-02-08 18:40:22 +01:00
* @ since phpservermon 2.1 . 0
**/
2014-03-21 13:48:26 +01:00
namespace psm\Module\Install\Controller ;
2014-03-15 00:35:35 +01:00
use psm\Module\AbstractController ;
2014-02-08 18:40:22 +01:00
use psm\Service\Database ;
2014-03-15 00:35:35 +01:00
class InstallController extends AbstractController {
2014-02-08 18:40:22 +01:00
/**
* Full path to config file
* @ var string $path_config
*/
protected $path_config ;
/**
* Full path to old config file ( 2.0 )
* @ var string $path_config_old
*/
protected $path_config_old ;
2014-08-01 16:40:20 +02:00
function __construct ( Database $db , \Twig_Environment $twig ) {
parent :: __construct ( $db , $twig );
2014-02-08 18:40:22 +01:00
2014-03-15 00:35:35 +01:00
$this -> setMinUserLevelRequired ( PSM_USER_ANONYMOUS );
2014-03-14 15:24:03 +01:00
$this -> addMenu ( false );
2014-02-08 18:40:22 +01:00
$this -> path_config = PSM_PATH_SRC . '../config.php' ;
$this -> path_config_old = PSM_PATH_SRC . '../config.inc.php' ;
$this -> setActions ( array (
'index' , 'config' , 'install'
), 'index' );
2014-03-14 15:24:03 +01:00
2014-08-01 16:40:20 +02:00
$this -> twig -> addGlobal ( 'subtitle' , psm_get_lang ( 'system,' , 'install' ));
2014-02-08 18:40:22 +01:00
}
/**
2014-03-14 15:24:03 +01:00
* Say hi to our new user
2014-02-08 18:40:22 +01:00
*/
protected function executeIndex () {
// build prerequisites
$errors = 0 ;
$phpv = phpversion ();
2014-04-12 11:58:52 +02:00
if ( version_compare ( $phpv , '5.3.7' , '<' )) {
2014-02-08 18:40:22 +01:00
$errors ++ ;
2014-04-12 11:58:52 +02:00
$this -> addMessage ( 'PHP 5.3.7+ is required to run PHP Server Monitor.' , 'error' );
2014-02-08 18:40:22 +01:00
} else {
2014-03-14 15:24:03 +01:00
$this -> addMessage ( 'PHP version: ' . $phpv , 'success' );
2014-02-08 18:40:22 +01:00
}
if ( ! function_exists ( 'curl_init' )) {
2014-03-14 15:24:03 +01:00
$this -> addMessage ( 'PHP is installed without the cURL module. Please install cURL.' , 'warning' );
2014-02-08 18:40:22 +01:00
} else {
2014-03-14 15:24:03 +01:00
$this -> addMessage ( 'PHP cURL module found' , 'success' );
2014-02-08 18:40:22 +01:00
}
2014-02-11 16:15:12 +01:00
if ( ! in_array ( 'mysql' , \PDO :: getAvailableDrivers ())) {
2014-02-08 18:40:22 +01:00
$errors ++ ;
2014-03-14 15:24:03 +01:00
$this -> addMessage ( 'The PDO MySQL driver needs to be installed.' , 'error' );
2014-02-08 18:40:22 +01:00
}
2014-04-01 12:39:58 +02:00
if ( ! ini_get ( 'date.timezone' )) {
$this -> addMessage ( 'You should set a timezone in your php.ini file (e.g. \'date.timezone = UTC\'). See <a href="http://www.php.net/manual/en/timezones.php" target="_blank">this page</a> for more info.' , 'warning' );
}
2014-02-08 18:40:22 +01:00
if ( $errors > 0 ) {
2014-03-14 15:24:03 +01:00
$this -> addMessage ( $errors . ' error(s) have been encountered. Please fix them and refresh this page.' , 'error' );
2014-02-08 18:40:22 +01:00
}
2014-08-01 16:40:20 +02:00
return $this -> twig -> render ( 'module/install/index.tpl.html' , array (
'messages' => $this -> getMessages ()
));
2014-02-08 18:40:22 +01:00
}
/**
* Help the user create a new config file
*/
protected function executeConfig () {
2014-08-01 16:40:20 +02:00
$tpl_name = 'module/install/config_new.tpl.html' ;
2014-03-14 15:24:03 +01:00
$tpl_data = array ();
2014-02-08 18:40:22 +01:00
2014-03-18 20:26:01 +01:00
if ( ! defined ( 'PSM_DB_PREFIX' )) {
2014-03-14 15:24:03 +01:00
// first detect "old" config file (2.0)
if ( file_exists ( $this -> path_config_old )) {
// oldtimer huh
$this -> addMessage ( 'Configuration file for v2.0 found.' , 'success' );
$this -> addMessage (
'The location of the config file has been changed since v2.0.<br/>' .
'We will attempt to create a new config file for you.'
, 'warning' );
$values = $this -> parseConfig20 ();
} else {
// fresh install
$values = $_POST ;
2014-02-08 18:40:22 +01:00
}
2014-03-14 15:24:03 +01:00
$config = array (
'host' => 'localhost' ,
'name' => '' ,
'user' => '' ,
'pass' => '' ,
'prefix' => 'psm_' ,
2014-02-08 18:40:22 +01:00
);
2014-03-14 15:24:03 +01:00
$changed = false ;
foreach ( $config as $ckey => & $cvalue ) {
if ( isset ( $values [ $ckey ])) {
$changed = true ;
$cvalue = $values [ $ckey ];
}
}
// add config to template data for prefilling the form
$tpl_data = $config ;
if ( $changed ) {
// test db connection
$this -> db = new \psm\Service\Database (
$config [ 'host' ],
$config [ 'user' ],
$config [ 'pass' ],
$config [ 'name' ]
);
if ( $this -> db -> status ()) {
$this -> addMessage ( 'Connection to MySQL successful.' , 'success' );
$config_php = $this -> writeConfigFile ( $config );
if ( $config_php === true ) {
$this -> addMessage ( 'Configuration file written successfully.' , 'success' );
} else {
$this -> addMessage ( 'Config file is not writable, we cannot save it for you.' , 'error' );
2014-08-01 16:40:20 +02:00
$tpl_data [ 'include_config_new_copy' ] = true ;
2014-03-14 15:24:03 +01:00
$tpl_data [ 'php_config' ] = $config_php ;
}
} else {
$this -> addMessage ( 'Unable to connect to MySQL. Please check your information.' , 'error' );
}
}
}
2014-03-18 20:26:01 +01:00
if ( defined ( 'PSM_DB_PREFIX' )) {
2014-02-11 16:15:12 +01:00
if ( $this -> db -> status ()) {
2014-03-14 15:24:03 +01:00
if ( $this -> isUpgrade ()) {
// upgrade
2014-04-06 16:52:58 +02:00
if ( version_compare ( $this -> getPreviousVersion (), '3.0.0' , '<' )) {
2014-04-05 09:31:41 +02:00
// upgrade from before 3.0, does not have passwords yet.. create new user first
$this -> addMessage ( 'Your current version does not have an authentication system, but since v3.0 access to the monitor is restricted by user accounts. Please set up a new account to be able to login after the upgrade, and which you can use to change the passwords for your other accounts.' , 'info' );
2014-08-01 16:40:20 +02:00
$tpl_name = 'module/install/config_new_user.tpl.html' ;
2014-03-14 15:24:03 +01:00
} else {
2014-08-01 16:40:20 +02:00
$tpl_name = 'module/install/config_upgrade.tpl.html' ;
2014-03-14 15:24:03 +01:00
$tpl_data [ 'version' ] = PSM_VERSION ;
}
2014-02-08 18:40:22 +01:00
} else {
2014-03-14 15:24:03 +01:00
// fresh install ahead
2014-08-01 16:40:20 +02:00
$tpl_name = 'module/install/config_new_user.tpl.html' ;
2014-03-14 15:24:03 +01:00
$tpl_data [ 'username' ] = ( isset ( $_POST [ 'username' ])) ? $_POST [ 'username' ] : '' ;
$tpl_data [ 'email' ] = ( isset ( $_POST [ 'email' ])) ? $_POST [ 'email' ] : '' ;
2014-02-08 18:40:22 +01:00
}
} else {
2014-03-14 15:24:03 +01:00
$this -> addMessage ( 'Configuration file found, but unable to connect to MySQL. Please check your information.' , 'error' );
2014-02-08 18:40:22 +01:00
}
}
2014-08-01 16:40:20 +02:00
$tpl_data [ 'messages' ] = $this -> getMessages ();
return $this -> twig -> render ( $tpl_name , $tpl_data );
2014-02-08 18:40:22 +01:00
}
/**
2014-03-14 15:24:03 +01:00
* Execute the install and upgrade process to a newer version
2014-02-08 18:40:22 +01:00
*/
2014-03-14 15:24:03 +01:00
protected function executeInstall () {
2014-03-18 20:26:01 +01:00
if ( ! defined ( 'PSM_DB_PREFIX' ) || ! $this -> db -> status ()) {
2014-03-14 15:24:03 +01:00
return $this -> executeConfig ();
}
2014-04-16 22:36:17 +02:00
$add_user = false ;
2014-03-14 15:24:03 +01:00
// check if user submitted username + password in previous step
// this would only be the case for new installs, and install from
2014-04-05 09:31:41 +02:00
// before 3.0
2014-03-14 15:24:03 +01:00
$new_user = array (
'user_name' => psm_POST ( 'username' ),
'name' => psm_POST ( 'username' ),
'password' => psm_POST ( 'password' ),
'password_repeat' => psm_POST ( 'password_repeat' ),
'email' => psm_POST ( 'email' , '' ),
2014-04-16 22:36:17 +02:00
'mobile' => '' ,
2014-03-14 15:24:03 +01:00
'level' => PSM_USER_ADMIN ,
2014-07-31 16:35:01 +02:00
'pushover_key' => '' ,
'pushover_device' => '' ,
2014-02-08 18:40:22 +01:00
);
2014-03-14 15:24:03 +01:00
$validator = new \psm\Util\User\UserValidator ( $this -> user );
2014-02-08 18:40:22 +01:00
2014-03-14 15:24:03 +01:00
$logger = array ( $this , 'addMessage' );
$installer = new \psm\Util\Install\Installer ( $this -> db , $logger );
2014-02-08 18:40:22 +01:00
2014-03-14 15:24:03 +01:00
if ( $this -> isUpgrade ()) {
$this -> addMessage ( 'Upgrade process started.' , 'info' );
$version_from = $this -> getPreviousVersion ();
if ( $version_from === false ) {
$this -> addMessage ( 'Unable to locate your previous version. Please run a fresh install.' , 'error' );
} else {
if ( version_compare ( $version_from , PSM_VERSION , '=' )) {
$this -> addMessage ( 'Your installation is already at the latest version.' , 'success' );
} elseif ( version_compare ( $version_from , PSM_VERSION , '>' )) {
$this -> addMessage ( 'This installer does not support downgrading, sorry.' , 'error' );
} else {
$this -> addMessage ( 'Upgrading from ' . $version_from . ' to ' . PSM_VERSION , 'info' );
$installer -> upgrade ( $version_from , PSM_VERSION );
}
2014-04-05 09:31:41 +02:00
if ( version_compare ( $version_from , '3.0.0' , '<' )) {
2014-03-14 15:24:03 +01:00
$add_user = true ;
}
}
} else {
// validate the lot
try {
$validator -> email ( $new_user [ 'email' ]);
$validator -> password ( $new_user [ 'password' ], $new_user [ 'password_repeat' ]);
} catch ( \InvalidArgumentException $e ) {
$this -> addMessage ( psm_get_lang ( 'users' , 'error_' . $e -> getMessage ()), 'error' );
return $this -> executeConfig ();
}
$this -> addMessage ( 'Installation process started.' , 'success' );
$installer -> install ();
// add user
$add_user = true ;
2014-02-08 18:40:22 +01:00
}
2014-03-14 15:24:03 +01:00
if ( $add_user ) {
unset ( $new_user [ 'password_repeat' ]);
$user_id = $this -> db -> save ( PSM_DB_PREFIX . 'users' , $new_user );
if ( intval ( $user_id ) > 0 ) {
2014-03-14 19:26:25 +01:00
$this -> user -> changePassword ( $user_id , $new_user [ 'password' ]);
$this -> addMessage ( 'User account has been created successfully.' , 'success' );
2014-03-14 15:24:03 +01:00
} else {
2014-03-14 19:26:25 +01:00
$this -> addMessage ( 'There was an error adding your user account.' , 'error' );
2014-03-14 15:24:03 +01:00
}
2014-02-08 18:40:22 +01:00
}
2014-08-01 16:40:20 +02:00
return $this -> twig -> render ( 'module/install/success.tpl.html' , array (
'messages' => $this -> getMessages ()
));
2014-02-08 18:40:22 +01:00
}
/**
* Write config file with db variables
* @ param array $db_vars prefix , user , pass , name , host
* @ return boolean | string TRUE on success , string with config otherwise
*/
protected function writeConfigFile ( $db_vars ) {
2014-03-18 20:26:01 +01:00
$config = " <?php " . PHP_EOL ;
2014-02-08 18:40:22 +01:00
foreach ( $db_vars as $key => $value ) {
$line = " define('PSM_DB_ { key}', ' { value}'); " . PHP_EOL ;
$line = str_replace (
array ( '{key}' , '{value}' ),
array ( strtoupper ( $key ), $value ),
$line
);
$config .= $line ;
}
if ( is_writeable ( $this -> path_config )) {
file_put_contents ( $this -> path_config , $config );
return true ;
} else {
return $config ;
}
}
/**
2014-03-14 15:24:03 +01:00
* Parse the 2.0 config file for prefilling
* @ return array
2014-02-08 18:40:22 +01:00
*/
2014-03-14 15:24:03 +01:00
protected function parseConfig20 () {
$config_old = file_get_contents ( $this -> path_config_old );
$vars = array (
'prefix' => '' ,
'user' => '' ,
'pass' => '' ,
'name' => '' ,
'host' => '' ,
);
$pattern = " /define \ ('SM_DB_ { key}', '(.*?)'/u " ;
foreach ( $vars as $key => $value ) {
$pattern_key = str_replace ( '{key}' , strtoupper ( $key ), $pattern );
preg_match ( $pattern_key , $config_old , $value_matches );
$vars [ $key ] = ( isset ( $value_matches [ 1 ])) ? $value_matches [ 1 ] : '' ;
2014-02-08 18:40:22 +01:00
}
2014-03-14 15:24:03 +01:00
return $vars ;
}
/**
* Is it an upgrade or install ?
*/
protected function isUpgrade () {
if ( ! $this -> db -> status ()) {
return false ;
}
2014-04-05 15:18:36 +02:00
return $this -> db -> ifTableExists ( PSM_DB_PREFIX . 'config' );
2014-03-14 15:24:03 +01:00
}
2014-02-08 18:40:22 +01:00
2014-03-14 15:24:03 +01:00
/**
* Get the previous version from the config table
* @ return boolean | string FALSE on failure , string otherwise
*/
protected function getPreviousVersion () {
if ( ! $this -> isUpgrade ()) {
return false ;
}
$version_conf = $this -> db -> selectRow ( PSM_DB_PREFIX . 'config' , array ( 'key' => 'version' ), array ( 'value' ));
if ( empty ( $version_conf )) {
return false ;
} else {
$version_from = $version_conf [ 'value' ];
if ( strpos ( $version_from , '.' ) === false ) {
// yeah, my bad.. previous version did not follow proper naming scheme
$version_from = rtrim ( chunk_split ( $version_from , 1 , '.' ), '.' );
}
return $version_from ;
2014-02-08 18:40:22 +01:00
}
}
}