/lib/installwizard/installWizard.php
PHP | 376 lines | 257 code | 63 blank | 56 comment | 82 complexity | 13132e98c3675fc5dcdc29ddc73bebbd MD5 | raw file
Possible License(s): BSD-3-Clause, JSON, GPL-3.0, LGPL-3.0, LGPL-2.1, GPL-2.0
- <?php
- /**
- * Installation wizard
- *
- * @package InstallWizard
- * @author Laurent Jouanneau
- * @copyright 2010-2015 Laurent Jouanneau
- * @link http://jelix.org
- * @licence GNU General Public Licence see LICENCE file or http://www.gnu.org/licenses/gpl.html
- */
- require(__DIR__.'/installWizardPage.php');
- /**
- * main class of the wizard
- *
- */
- class installWizard {
- protected $config;
- protected $configPath;
- protected $lang = 'en';
- protected $pages = array();
- protected $customPath = '';
- protected $tempPath = '';
- protected $stepName = "";
- protected $locales = array();
- /**
- * @var \Jelix\Castor\Config
- */
- protected $tplConfig;
- /**
- * @param string $config an ini file for the installation
- * should contain this parameter:
- * -
- */
- function __construct($configFile) {
- $this->configPath = $configFile;
- session_start();
- date_default_timezone_set("Europe/Paris");
- }
- /**
- * read the configuration file
- */
- protected function readConfiguration() {
- $conf = parse_ini_file($this->configPath, true, INI_SCANNER_TYPED);
- if (!$conf)
- throw new Exception('Impossible to read the configuration file');
- $this->config = $conf;
-
- if (isset($this->config['supportedLang'])) {
- $this->config['supportedLang'] = preg_split('/ *, */',$this->config['supportedLang']);
- }
- else
- $this->config['supportedLang'] = array('en');
- }
- /**
- * read and prepare all paths of pages, of temp dir etc.
- */
- protected function initPath() {
- $list = preg_split('/ *, */',$this->config['pagesPath']);
- $basepath = dirname($this->configPath).'/';
- foreach($list as $k=>$path){
- if(trim($path) == '') continue;
- $p = realpath($basepath.$path);
- if ($p== '' || !file_exists($p))
- throw new Exception ('The path, '.$path.' given in the configuration doesn\'t exist !');
- if (substr($p,-1) !='/')
- $p.='/';
- if ($handle = opendir($p)) {
- while (false !== ($f = readdir($handle))) {
- if ($f[0] != '.' && is_dir($p.$f) && isset($this->config[$f.'.step'])) {
- $this->pages[$f] = $p.$f.'/';
- }
- }
- closedir($handle);
- }
- }
- if (isset($this->config['customPath']) && $this->config['customPath'] != '') {
- $this->customPath = realpath($basepath.$this->config['customPath']);
- if ($this->customPath)
- $this->customPath .= '/';
- }
- if (isset($this->config['tempPath']) && $this->config['tempPath'] != '') {
- $this->tempPath = realpath($basepath.$this->config['tempPath']);
- if (!$this->tempPath)
- throw new Exception("no temp directory");
- if (!is_writable($this->tempPath))
- throw new Exception("The temp directory ".$this->config['tempPath']." is not writable. Change the rights on this directory to allow the web server to write in it.");
- $this->tempPath .= '/';
- }
- else
- throw new Exception("no temp directory");
- }
- /**
- * filled a __previous variable into data of each step.
- * @return string the name of the last step
- */
- protected function initPrevious($step='', $previousStep='') {
- if ($step == '') {
- if (isset($this->config['start']))
- $step = $this->config['start'];
- else
- return '';
- }
- if (!isset($this->pages[$step]) || !isset($this->config[$step.'.step'])) {
- return '';
- }
- if (isset($this->config[$step.'.step']['__previous'])) {
- return '';
- }
-
- if (isset($this->config[$step.'.step']['noprevious']) && $this->config[$step.'.step']['noprevious'])
- $this->config[$step.'.step']['__previous'] = '';
- else
- $this->config[$step.'.step']['__previous'] = $previousStep;
-
- if (!isset($this->config[$step.'.step']['next'])) {
- return $step;
- }
- $last = '';
- if (is_array($this->config[$step.'.step']['next'])) {
- foreach($this->config[$step.'.step']['next'] as $next) {
- $rv = $this->initPrevious($next, $step);
- if ($rv != '')
- $last = $rv;
- }
- }
- else
- $last = $this->initPrevious($this->config[$step.'.step']['next'], $step);
- return $last;
- }
- /**
- * setup the language by analysing the lang of the browser
- */
- protected function guessLanguage($lang = '') {
- if($lang == '' && isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])){
- $languages = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']);
- foreach($languages as $bl){
- // pour les user-agents qui livrent un code internationnal
- if(preg_match("/^([a-zA-Z]{2})(?:[-_]([a-zA-Z]{2}))?(;q=[0-9]\\.[0-9])?$/",$bl,$match)){
- $lang = strtolower($match[1]);
- break;
- }
- }
- }elseif(preg_match("/^([a-zA-Z]{2})(?:[-_]([a-zA-Z]{2}))?$/",$lang,$match)){
- $lang = strtolower($match[1]);
- }
- if($lang == '' || !in_array($lang, $this->config['supportedLang'])){
- $lang = 'en';
- }
- return $lang;
- }
- /**
- * retrieve the name of the current step
- * @return string the name
- */
- protected function getStepName() {
- if (isset($_REQUEST['step'])) {
- $stepname = $_REQUEST['step'];
- }
- elseif (isset($this->config['start'])) {
- $stepname = $this->config['start'];
- }
- else {
- throw new Exception('No step start in the configuration');
- }
- if (!isset($this->pages[$stepname])) {
- throw new Exception('Unknow step');
- }
- return $stepname;
- }
- /**
- * return the name of the next step after the current page
- * @param installWizardPage $page the current page
- * @param integer $result the return code of the process method of the current page
- * @return string the name
- */
- protected function getNextStep($page, $result=0) {
- if (is_array($page->config['next'])) {
- if (is_numeric($result))
- $nextStep = $page->config['next'][$result];
- else
- $nextStep = $page->config['next'][0];
- }
- else
- $nextStep = $page->config['next'];
- return $nextStep;
- }
- function run ($isAlreadyDone = false) {
- try {
- $this->readConfiguration();
- $this->initPath();
- $laststep = $this->initPrevious();
- $this->lang = $this->guessLanguage();
- if ($isAlreadyDone && !isset($_SESSION['__install__wizard'])) {
- if (isset($this->config['onalreadydone']))
- $laststep = $this->config['onalreadydone'];
- if ($laststep != '' && isset($this->pages[$laststep])) {
- $this->stepName = $laststep;
- }
- else {
- throw new Exception("Application is installed. The script cannot be runned.");
- }
- }
- else {
- if (!isset($_SESSION['__install__wizard']) && !$isAlreadyDone)
- $_SESSION['__install__wizard'] = true;
- $this->stepName = $this->getStepName();
- }
- $this->tplConfig = new \Jelix\Castor\Config($this->tempPath);
- $this->tplConfig->setLang($this->lang);
- $this->tplConfig->localesGetter = array($this, 'getLocale');
- $page = $this->loadPage();
- if (isset($_POST['doprocess']) && $_POST['doprocess'] == "1") {
- //if ($isAlreadyDone)
- // $result = true;
- //else
- $result = $page->process();
- if ($result !== false) {
- header("location: ?step=".$this->getNextStep($page, $result));
- exit(0);
- }
- }
- $tpl = new \Jelix\Castor\Castor($this->tplConfig);
- $tpl->assign($page->config);
- $tpl->assign($page->getErrors());
- $tpl->assign('appname', isset($this->config['appname'])?$this->config['appname']:'');
- $continue = $page->show($tpl);
- $content = $tpl->fetch($this->stepName.'.tpl', 'html');
- $this->showMainTemplate($page, $content, $continue);
- if ($laststep == $this->stepName) {
- session_destroy();
- }
- } catch (Exception $e) {
- $error = $e->getMessage();
- header("HTTP/1.1 500 Application error");
- if ($this->customPath && file_exists($this->customPath.'error.php'))
- require($this->customPath.'error.php');
- else
- require(__DIR__.'/error.php');
- exit(1);
- }
- }
-
-
- protected function loadPage() {
- $stepname = $this->stepName;
- // load the class which run the step
- require($this->pages[$stepname].$stepname.'.page.php');
- $class = $stepname.'WizPage';
- if (!class_exists($stepname.'WizPage'))
- throw new Exception ('No class for the given step');
- // load the locales
- $this->loadLocales($stepname, $stepname);
- // load the template
- $tplfile = $this->getRealPath($stepname, $stepname.'.tpl');
- if ($tplfile === false)
- throw new Exception ("No template file for the given step");
- $this->tplConfig->templatePath = dirname($tplfile).'/';
- $page = new $class($this->config[$stepname.'.step'], $this->locales);
- return $page;
- }
-
- protected function showMainTemplate($page, $content, $continue) {
- $filename = "wiz_layout.tpl";
- $path = $this->getRealPath('', $filename);
- $this->tplConfig->templatePath = dirname($path).'/';
- $this->loadLocales('', 'wiz_layout');
- $conf = $this->config[$this->stepName.'.step'];
- $tpl = new \Jelix\Castor\Castor($this->tplConfig);
- $tpl->assign('title', $page->getLocale($page->title));
- if (isset($conf['messageHeader']))
- $tpl->assign('messageHeader', $conf['messageHeader']);
- else
- $tpl->assign('messageHeader', '');
- if (isset($conf['messageFooter']))
- $tpl->assign('messageFooter', $conf['messageFooter']);
- else
- $tpl->assign('messageFooter', '');
- $tpl->assign ('MAIN', $content);
- $tpl->assign (array_merge(array('enctype'=>''),$conf));
- $tpl->assign ('stepname', $this->stepName);
- $tpl->assign ('lang', $this->lang);
- $tpl->assign('next', ($continue && isset($conf['next'])));
- $tpl->assign('previous', isset($conf['__previous'])?$conf['__previous']:'');
- $tpl->assign('appname', isset($this->config['appname'])?$this->config['appname']:'Application');
-
- $tpl->display($filename, 'html');
- }
- protected function getRealPath($stepname, $fileName) {
- if ($this->customPath) {
- if (file_exists($this->customPath.$fileName))
- return $this->customPath.$fileName;
- }
- if ($stepname)
- $path = $this->pages[$stepname];
- else
- $path = __DIR__."/";
- if (file_exists($path.$fileName))
- return $path.$fileName;
- return false;
- }
- protected function loadLocales($stepname, $prefix) {
- $localeFile = $this->getRealPath($stepname, $prefix.'.'.$this->lang.'.php');
- if ($localeFile === false && $this->lang != 'en')
- $localeFile = $this->getRealPath($stepname, $prefix.'.en.php');
- if ($localeFile === false)
- throw new Exception ("No lang file for the given step");
- require($localeFile); // load a php array $locales
- $this->locales = $locales;
- }
-
- /**
- * function for the template engine, to retrieve a localized string
- * @param string $name the key of the localized string
- * @return string the localized string or the given key if it doesn't exists
- */
- public function getLocale($name) {
- if (isset($this->locales[$name]))
- return $this->locales[$name];
- else return $name;
- }
-
- }