2 /***************************************************************
5 * (c) 2007 Thomas Hempel (thomas@work.de)
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 * A copy is found in the textfile GPL.txt and important notices to the license
17 * from the author is found in LICENSE.txt distributed with these scripts.
20 * This script is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * This copyright notice MUST APPEAR in all copies of the script!
26 ***************************************************************/
28 class tx_install_module_installer
extends tx_install_module_base
{
29 private $moduleKey = 'installer';
32 * Defines the steps for the installation.
34 * Each step consists of a set of methods, checks and options in various states of processing.
35 * Each step can have the following states
37 * - pre: Only checks are allowed here! This checks are executed each time a step is called. If any of
38 * the checks return false, the step can't be be processed.
40 * - main: The main method that is executed in this step. In most cases this will be a formconfig for
43 * - post: Here are all things located that has to be executed before a step can be finished. This is
44 * the right place for processing and checking the input data from the main method.
45 * If any of this checks returns false the main state is called again.
49 private $stepConfig = array (
50 // these steps basically reimplements the old 1-2-3 installer with some small improvements
52 // inital checks / no further processing
55 0 => 'php:checkVersion',
56 1 => 'directories:checkDirs'
61 'module' => 'installer',
62 'method' => 'selectLanguage'
67 // database connection
72 'module' => 'database',
73 'method' => 'databaseConnectionData'
77 'database:connectDatabaseProcess'
81 // select / create database
86 'module' => 'database',
87 'method' => 'selectDatabaseForm'
91 'database:createDatabase'
95 // create / import tables from file
97 'preMode' => 'skipMain',
99 'database:checkForStaticFiles'
104 'module' => 'database',
105 'method' => 'selectStaticFileForm'
109 'database:importTables'
113 // create an admin user
118 'module' => 'database',
119 'method' => 'createAdminForm'
123 'database:createAdmin'
131 'index' => 'msg_step5_done'
139 * Defines which is the last mandatory step
143 private $lastMandatoryStep = 5;
146 * Holds the current step
150 private $step = null;
153 * This is the main method
155 public function main() {
156 // get the current step
157 $this->step
= (empty($this->env
['step'])) ?
0 : intval($this->env
['step']);
160 $stepResult = $this->executeStep($this->step
);
162 // render back button if step is bigger than 1
163 if ($this->step
> 0) {
164 $formConfig = array (
168 'name' => 'form_stepData',
169 'submit' => $this->get_LL('label_prev_step'),
172 'step' => $this->step
-1,
179 $btnBack = $this->pObj
->getViewObject()->render($formConfig);
184 // build-up the output
186 '###STEP###' => sprintf($this->get_LL('label_step'), $this->step
),
187 '###PROGRESS###' => $this->getProgress(),
188 '###MSG_TITLE###' => $this->get_LL('msg_step'.$this->step
.'_title'),
189 '###MSG_DESCRIPTION###' => $this->get_LL('msg_step'.$this->step
.'_description'),
190 '###BTN_BACK###' => $btnBack,
191 '###CONTENT###' => $stepResult,
192 '###PREV_RESULT###' => $this->pObj
->getViewObject()->getLastMessage(true)
195 if (count($this->pObj
->getViewObject()->getErrors('general')) > 0) {
196 $marker['###ERRORS_GENERAL###'] = $this->pObj
->getViewObject()->renderErrors(true);
198 $marker['###ERRORS_GENERAL###'] = '';
203 'content' => $this->pObj
->getViewObject()->render(array (
206 'template' => implode('', file($this->pObj
->getBasicsObject()->getModulePath($this->moduleKey
).'res/tpl_step.html')),
216 * Executes all states of a certain step.
218 private function executeStep() {
219 // let's check if the step is defined, die if not
220 if (!isset($this->stepConfig
[$this->step
])) {
221 $this->addError(sprintf($this->get_LL('msg_error_stepnotdefined'), $this->step
), FATAL
);
225 // process pre state - result is true if this state is not configured
226 if (isset($this->stepConfig
[$this->step
]['pre'])) {
227 $preResult = $this->executeStepState('pre');
232 // exit if pre checks are not sucessfull
233 if ($preResult === false) {
234 // depending on preMode we only skip state main or stop here immediately
235 if (!isset($this->stepConfig
[$this->step
]['preMode']) &&Ê
($this->stepConfig
[$this->step
]['preMode'] != 'skipMain')) {
238 $this->env
['state'] = 'post';
242 // if state is post, execute that state
243 $processResult = true;
244 if ($this->env
['state'] == 'post') {
245 // execute process methods (has to be configured)
246 $processResult = $this->executeStepState('post');
247 $this->env
['state'] = 'pre';
249 // go to next step if process was ok
250 if ($processResult === true) {
252 return $this->executeStep();
256 // execute main state (has to be configured!)
257 $mainResult = $this->executeStepState('main');
259 if ($mainResult === false) {
268 * Executes a certain state in a step. It dispatches all the config to the particular handlers.
269 * For example rendering forms, or calling the methods in that specific module.
271 * @param integer $state: The state that has to be executed
272 * @return The collected results of all given methods (In state pre and post it returns false if any of the methods returns false!)
274 private function executeStepState($state) {
275 $stateConfig = $this->stepConfig
[$this->step
][$state];
277 // check if there is any config for this state in this particular step
278 if (!is_array($stateConfig)) {
279 if ($state == 'pre' ||
$state == 'post') {
280 // state pre and post don't have to be set, if they are not configured we estimate that everything is ok and return true
283 $this->addError(sprintf($this->get_LL('msg_error_stepstatenotdefined'), $state, $this->step
), FATAL
);
288 // prepare result streams
289 $formElements = array('normal' => NULL, 'advanced' => NULL);
292 // cycle through the various methods defined for this state
293 foreach ($stateConfig as $index => $stateMethod) {
294 $stateMethodResult = $this->dispatchStateMethod($stateMethod, $formElements);
296 if ($state == 'main') {
297 if ($stateMethodResult == false) {
300 if (is_string($stateMethodResult)) {
301 $stateResult .= $stateMethodResult;
304 $stateResult = $stateMethodResult;
306 // exit cycle if in pre or post state any state method returned false
307 if ($stateResult === false) {
313 // render form if any fields are set
314 if ($state == 'main' && (is_array($formElements['normal']) ||
is_array($formElements['advanced']))) {
315 $elements = array(array(
316 'type' => 'formelement',
318 'elementType' => 'fieldset',
319 'label' => $this->get_LL('label_normalFields')
323 $elements = array_merge($elements, $formElements['normal']);
325 if (is_array($formElements['advanced'])) {
326 $elements[] = array (
327 'type' => 'formelement',
329 'elementType' => 'fieldset',
330 'label' => $this->get_LL('label_advancedFields'),
331 'class' => 'fieldset-advanced'
334 $elements = array_merge($elements, $formElements['advanced']);
337 $formConfig = array (
341 'name' => 'form_stepData',
342 'submit' => $this->get_LL('label_next_step'),
345 'step' => $this->step
,
349 'elements' => $elements
353 $stateResult = $this->pObj
->getViewObject()->render($formConfig).$stateResult;
360 * Receives a state config and executs the respective method and returns the result
362 * @param mixed $stateMethod: The method to call and the optional the type.
363 * @param array $formElements: An array that collects the form elements for the step (PASS BY REFERENCE)
364 * @return False if somethign went wrong, otherwise the result of the called method
366 private function dispatchStateMethod($stateMethod, &$formElements) {
368 if ($stateMethod['type'] == 'label') {
369 $methodResult = nl2br($this->get_LL($stateMethod['index']));
371 if (is_string($stateMethod)) {
372 $methodResult = $this->pObj
->getBasicsObject()->executeMethod($stateMethod);
374 $methodResult = $this->pObj
->getBasicsObject()->executeMethod(array($stateMethod['module'], $stateMethod['method']));
378 if ($methodResult === false) {
382 switch ($stateMethod['type']) {
384 $formElements = array_merge($formElements, $methodResult);
387 $result = $methodResult;
396 * Returns an XHTML fragment with a progressbar, that shows the progress in the installation process.
400 private function getProgress() {
401 $progressBar = '<div id="progressbar"><div class="mandatory" ';
402 $progressBar .= 'style="width:'.(100 /count($this->stepConfig
) *$this->step
).'%"></div></div>';
411 * Shows the welcome screen.
414 public function welcomeScreen() {
419 * provides a selectbox with all available languages
421 public function selectLanguage() {
422 $languageData = $this->pObj
->getLanguageObject()->includeLLFile('EXT:setup/mod/locallang.xml', false);
423 $this->pObj
->setLocalLang(t3lib_div
::array_merge_recursive_overrule($this->pObj
->getLocalLang(), $languageData));
425 $theLanguages = t3lib_div
::trimExplode('|',TYPO3_languages
);
426 foreach ($theLanguages as $val) {
427 $opt[$val] = $this->pObj
->getBasicsObject()->getLabel('lang_'.$val);
430 $elements['normal'] = array (
432 'type' => 'formelement',
434 'label' => 'label_available_languages',
435 'elementType' => 'selectbox',
448 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE
]['XCLASS']['ext/install/modules/installer/class.tx_install_module_installer.php']) {
449 include_once($TYPO3_CONF_VARS[TYPO3_MODE
]['XCLASS']['ext/install/modules/installer/class.tx_install_module_installer.php']);