installerSettings = (object)array( 'installerroot' => 'installation', 'sqlroot' => 'installation/sql', 'databasesini' => 1, 'readme' => 1, 'extrainfo' => 1, 'password' => 0, ); $config = Factory::getConfiguration(); $installerKey = $config->get('akeeba.advanced.embedded_installer'); $installerDescriptors = Factory::getEngineParamsProvider()->getInstallerList(); if (array_key_exists($installerKey, $installerDescriptors)) { // The selected installer exists, use it $this->installerSettings = (object)$installerDescriptors[$installerKey]; } elseif (array_key_exists('angie', $installerDescriptors)) { // The selected installer doesn't exist, but ANGIE exists; use that instead $this->installerSettings = (object)$installerDescriptors['angie']; } } /** * Runs the preparation for this part. Should set _isPrepared * to true * * @return void */ abstract protected function _prepare(); /** * Runs the finalisation process for this part. Should set * _isFinished to true. * * @return void */ abstract protected function _finalize(); /** * Runs the main functionality loop for this part. Upon calling, * should set the _isRunning to true. When it finished, should set * the _hasRan to true. If an error is encountered, setError should * be used. * * @return void */ abstract protected function _run(); /** * Sets the BREAKFLAG, which instructs this engine part that the current step must break immediately, * in fear of timing out. * * @return void */ protected function setBreakFlag() { $registry = Factory::getConfiguration(); $registry->set('volatile.breakflag', true); } /** * Sets the engine part's internal state, in an easy to use manner * * @param string $state One of init, prepared, running, postrun, finished, error * @param string $errorMessage The reported error message, should the state be set to error * * @return void */ protected function setState($state = 'init', $errorMessage = 'Invalid setState argument') { switch ($state) { case 'init': $this->isPrepared = false; $this->isRunning = false; $this->isFinished = false; $this->hasRan = false; break; case 'prepared': $this->isPrepared = true; $this->isRunning = false; $this->isFinished = false; $this->hasRan = false; break; case 'running': $this->isPrepared = true; $this->isRunning = true; $this->isFinished = false; $this->hasRan = false; break; case 'postrun': $this->isPrepared = true; $this->isRunning = false; $this->isFinished = false; $this->hasRan = true; break; case 'finished': $this->isPrepared = true; $this->isRunning = false; $this->isFinished = true; $this->hasRan = false; break; case 'error': default: $this->setError($errorMessage); break; } } /** * The public interface to an engine part. This method takes care for * calling the correct method in order to perform the initialisation - * run - finalisation cycle of operation and return a proper response array. * * @param int $nesting * * @return array A response array */ public function tick($nesting = 0) { $this->waitTimeMsec = 0; $configuration = Factory::getConfiguration(); $timer = Factory::getTimer(); // Call the right action method, depending on engine part state switch ($this->getState()) { case "init": $this->_prepare(); break; case "prepared": $this->_run(); break; case "running": $this->_run(); break; case "postrun": $this->_finalize(); break; } // If there is still time, we are not finished and there is no break flag set, re-run the tick() // method. $breakFlag = $configuration->get('volatile.breakflag', false); if ( !in_array($this->getState(), array('finished', 'error')) && ($timer->getTimeLeft() > 0) && !$breakFlag && ($nesting < 20) && ($this->nest_logging) ) { // Nesting is only applied if $this->nest_logging == true (currently only Kettenrad has this) $nesting++; if ($this->nest_logging) { Factory::getLog()->log(LogLevel::DEBUG, "*** Batching successive steps (nesting level $nesting)"); } $out = $this->tick($nesting); } else { // Return the output array $out = $this->_makeReturnTable(); // Things to do for nest-logged parts (currently, only Kettenrad is) if ($this->nest_logging) { if ($breakFlag) { Factory::getLog()->log(LogLevel::DEBUG, "*** Engine steps batching: Break flag detected."); } // Reset the break flag $configuration->set('volatile.breakflag', false); // Log that we're breaking the step Factory::getLog()->log(LogLevel::DEBUG, "*** Batching of engine steps finished. I will now return control to the caller."); // Do I need client-side sleep? $serverSideSleep = true; if (method_exists($this, 'getTag')) { $tag = $this->getTag(); $clientSideSleep = Factory::getConfiguration()->get('akeeba.basic.clientsidewait', 0); if (in_array($tag, array('backend', 'restorepoint')) && $clientSideSleep) { $serverSideSleep = false; } } // Enforce minimum execution time $timer = Factory::getTimer(); $this->waitTimeMsec = (int)$timer->enforce_min_exec_time(true, $serverSideSleep); } } // Send a Return Table back to the caller return $out; } /** * Returns a copy of the class's status array * * @return array The response array */ public function getStatusArray() { return $this->_makeReturnTable(); } /** * Sends any kind of setup information to the engine part. Using this, * we avoid passing parameters to the constructor of the class. These * parameters should be passed as an indexed array and should be taken * into account during the preparation process only. This function will * set the error flag if it's called after the engine part is prepared. * * @param array $parametersArray The parameters to be passed to the engine part. * * @return void */ public function setup($parametersArray) { if ($this->isPrepared) { $this->setState('error', get_class($this) . ":: Can't modify configuration after the preparation of " . $this->active_domain); } else { $this->_parametersArray = $parametersArray; if (array_key_exists('root', $parametersArray)) { $this->databaseRoot = $parametersArray['root']; } } } /** * Returns the state of this engine part. * * @return string The state of this engine part. It can be one of error, init, prepared, running, postrun, * finished. */ public function getState() { if ($this->getError()) { return "error"; } if (!($this->isPrepared)) { return "init"; } if (!($this->isFinished) && !($this->isRunning) && !($this->hasRan) && ($this->isPrepared)) { return "prepared"; } if (!($this->isFinished) && $this->isRunning && !($this->hasRan)) { return "running"; } if (!($this->isFinished) && !($this->isRunning) && $this->hasRan) { return "postrun"; } if ($this->isFinished) { return "finished"; } } /** * Constructs a Response Array based on the engine part's state. * * @return array The Response Array for the current state */ protected function _makeReturnTable() { // Get a list of warnings $warnings = $this->getWarnings(); // Report only new warnings if there is no warnings queue size if ($this->_warnings_queue_size == 0) { if (($this->warnings_pointer > 0) && ($this->warnings_pointer < (count($warnings)))) { $warnings = array_slice($warnings, $this->warnings_pointer + 1); $this->warnings_pointer += count($warnings); } else { $this->warnings_pointer = count($warnings); } } $out = array( 'HasRun' => (!($this->isFinished)), 'Domain' => $this->active_domain, 'Step' => $this->active_step, 'Substep' => $this->active_substep, 'Error' => $this->getError(), 'Warnings' => $warnings ); return $out; } /** * Set the current domain of the engine * * @param string $new_domain The domain to set * * @return void */ protected function setDomain($new_domain) { $this->active_domain = $new_domain; } /** * Get the current domain of the engine * * @return string The current domain */ public function getDomain() { return $this->active_domain; } /** * Set the current step of the engine * * @param string $new_step The step to set * * @return void */ protected function setStep($new_step) { $this->active_step = $new_step; } /** * Get the current step of the engine * * @return string The current step */ public function getStep() { return $this->active_step; } /** * Set the current sub-step of the engine * * @param string $new_substep The sub-step to set * * @return void */ protected function setSubstep($new_substep) { $this->active_substep = $new_substep; } /** * Get the current sub-step of the engine * * @return string The current sub-step */ public function getSubstep() { return $this->active_substep; } /** * Implement this if your Engine Part can return the percentage of its work already complete * * @return float A number from 0 (nothing done) to 1 (all done) */ public function getProgress() { return 0; } }