'Installation_Welcome', 'systemCheck' => 'Installation_SystemCheck', 'databaseSetup' => 'Installation_DatabaseSetup', 'databaseCheck' => 'Installation_DatabaseCheck', 'tablesCreation' => 'Installation_Tables', 'generalSetup' => 'Installation_SuperUser', 'firstWebsiteSetup' => 'Installation_SetupWebsite', 'trackingCode' => 'General_JsTrackingTag', 'finished' => 'Installation_Congratulations', ); protected $session; public function __construct() { $this->session = new SessionNamespace('Installation'); if (!isset($this->session->currentStepDone)) { $this->session->currentStepDone = ''; $this->session->skipThisStep = array(); } } protected static function initServerFilesForSecurity() { if (SettingsServer::isIIS()) { ServerFilesGenerator::createWebConfigFiles(); } else { ServerFilesGenerator::createHtAccessFiles(); } ServerFilesGenerator::createWebRootFiles(); } /** * Get installation steps * * @return array installation steps */ public function getInstallationSteps() { return $this->steps; } /** * Get default action (first installation step) * * @return string function name */ function getDefaultAction() { $steps = array_keys($this->steps); return $steps[0]; } /** * Installation Step 1: Welcome */ function welcome($message = false) { // Delete merged js/css files to force regenerations based on updated activated plugin list Filesystem::deleteAllCacheOnUpdate(); $view = new View( '@Installation/welcome', $this->getInstallationSteps(), __FUNCTION__ ); $view->newInstall = !$this->isFinishedInstallation(); $view->errorMessage = $message; $this->skipThisStep(__FUNCTION__); $view->showNextStep = $view->newInstall; $this->session->currentStepDone = __FUNCTION__; return $view->render(); } /** * Installation Step 2: System Check */ function systemCheck() { $this->checkPreviousStepIsValid(__FUNCTION__); $view = new View( '@Installation/systemCheck', $this->getInstallationSteps(), __FUNCTION__ ); $this->skipThisStep(__FUNCTION__); $view->duringInstall = true; $this->setupSystemCheckView($view); $this->session->general_infos = $view->infos['general_infos']; $this->session->general_infos['salt'] = Common::generateUniqId(); // make sure DB sessions are used if the filesystem is NFS if ($view->infos['is_nfs']) { $this->session->general_infos['session_save_handler'] = 'dbtable'; } $view->showNextStep = !$view->problemWithSomeDirectories && $view->infos['phpVersion_ok'] && count($view->infos['adapters']) && !count($view->infos['missing_extensions']) && !count($view->infos['missing_functions']); // On the system check page, if all is green, display Next link at the top $view->showNextStepAtTop = $view->showNextStep; $this->session->currentStepDone = __FUNCTION__; return $view->render(); } /** * Installation Step 3: Database Set-up * @throws Exception|Zend_Db_Adapter_Exception */ function databaseSetup() { $this->checkPreviousStepIsValid(__FUNCTION__); // case the user hits the back button $this->session->skipThisStep = array( 'firstWebsiteSetup' => false, 'trackingCode' => false, ); $this->skipThisStep(__FUNCTION__); $view = new View( '@Installation/databaseSetup', $this->getInstallationSteps(), __FUNCTION__ ); $view->showNextStep = false; $form = new FormDatabaseSetup(); if ($form->validate()) { try { $dbInfos = $form->createDatabaseObject(); $this->session->databaseCreated = true; DbHelper::checkDatabaseVersion(); $this->session->databaseVersionOk = true; $this->createConfigFileIfNeeded($dbInfos); $this->redirectToNextStep(__FUNCTION__); } catch (Exception $e) { $view->errorMessage = Common::sanitizeInputValue($e->getMessage()); } } $view->addForm($form); return $view->render(); } /** * Installation Step 4: Database Check */ function databaseCheck() { $this->checkPreviousStepIsValid(__FUNCTION__); $view = new View( '@Installation/databaseCheck', $this->getInstallationSteps(), __FUNCTION__ ); $error = false; $this->skipThisStep(__FUNCTION__); if (isset($this->session->databaseVersionOk) && $this->session->databaseVersionOk === true ) { $view->databaseVersionOk = true; } else { $error = true; } if (isset($this->session->databaseCreated) && $this->session->databaseCreated === true ) { $view->databaseName = Config::getInstance()->database['dbname']; $view->databaseCreated = true; } else { $error = true; } $db = Db::get(); try { $db->checkClientVersion(); } catch (Exception $e) { $view->clientVersionWarning = $e->getMessage(); $error = true; } if (!DbHelper::isDatabaseConnectionUTF8()) { Config::getInstance()->database['charset'] = 'utf8'; Config::getInstance()->forceSave(); } $view->showNextStep = true; $this->session->currentStepDone = __FUNCTION__; if ($error === false) { $this->redirectToNextStep(__FUNCTION__); } return $view->render(); } /** * Installation Step 5: Table Creation */ function tablesCreation() { $this->checkPreviousStepIsValid(__FUNCTION__); $view = new View( '@Installation/tablesCreation', $this->getInstallationSteps(), __FUNCTION__ ); $this->skipThisStep(__FUNCTION__); if (Common::getRequestVar('deleteTables', 0, 'int') == 1) { Db::dropAllTables(); $view->existingTablesDeleted = true; // when the user decides to drop the tables then we dont skip the next steps anymore // workaround ZF-1743 $tmp = $this->session->skipThisStep; $tmp['firstWebsiteSetup'] = false; $tmp['trackingCode'] = false; $this->session->skipThisStep = $tmp; } $tablesInstalled = DbHelper::getTablesInstalled(); $view->tablesInstalled = ''; if (count($tablesInstalled) > 0) { // we have existing tables $view->tablesInstalled = implode(', ', $tablesInstalled); $view->someTablesInstalled = true; Access::getInstance(); Piwik::setUserHasSuperUserAccess(); if ($this->hasEnoughTablesToReuseDb($tablesInstalled) && count(APISitesManager::getInstance()->getAllSitesId()) > 0 && count(APIUsersManager::getInstance()->getUsers()) > 0 ) { $view->showReuseExistingTables = true; // when the user reuses the same tables we skip the website creation step // workaround ZF-1743 $tmp = $this->session->skipThisStep; $tmp['firstWebsiteSetup'] = true; $tmp['trackingCode'] = true; $this->session->skipThisStep = $tmp; } } else { DbHelper::createTables(); DbHelper::createAnonymousUser(); Updater::recordComponentSuccessfullyUpdated('core', Version::VERSION); $view->tablesCreated = true; $view->showNextStep = true; } $this->session->currentStepDone = __FUNCTION__; return $view->render(); } function reuseTables() { $this->checkPreviousStepIsValid(__FUNCTION__); $steps = $this->getInstallationSteps(); $steps['tablesCreation'] = 'Installation_ReusingTables'; $view = new View( '@Installation/reuseTables', $steps, 'tablesCreation' ); Access::getInstance(); Piwik::setUserHasSuperUserAccess(); $updater = new Updater(); $componentsWithUpdateFile = CoreUpdater::getComponentUpdates($updater); if (empty($componentsWithUpdateFile)) { $this->session->currentStepDone = 'tablesCreation'; $this->redirectToNextStep('tablesCreation'); return ''; } $oldVersion = Option::get('version_core'); $result = CoreUpdater::updateComponents($updater, $componentsWithUpdateFile); $view->coreError = $result['coreError']; $view->warningMessages = $result['warnings']; $view->errorMessages = $result['errors']; $view->deactivatedPlugins = $result['deactivatedPlugins']; $view->currentVersion = Version::VERSION; $view->oldVersion = $oldVersion; $view->showNextStep = true; $this->session->currentStepDone = 'tablesCreation'; return $view->render(); } /** * Installation Step 6: General Set-up (superuser login/password/email and subscriptions) */ function generalSetup() { $this->checkPreviousStepIsValid(__FUNCTION__); $view = new View( '@Installation/generalSetup', $this->getInstallationSteps(), __FUNCTION__ ); $this->skipThisStep(__FUNCTION__); $form = new FormGeneralSetup(); if ($form->validate()) { try { $this->createSuperUser($form->getSubmitValue('login'), $form->getSubmitValue('password'), $form->getSubmitValue('email')); $url = Config::getInstance()->General['api_service_url']; $url .= '/1.0/subscribeNewsletter/'; $params = array( 'email' => $form->getSubmitValue('email'), 'security' => $form->getSubmitValue('subscribe_newsletter_security'), 'community' => $form->getSubmitValue('subscribe_newsletter_community'), 'url' => Url::getCurrentUrlWithoutQueryString(), ); if ($params['security'] == '1' || $params['community'] == '1' ) { if (!isset($params['security'])) { $params['security'] = '0'; } if (!isset($params['community'])) { $params['community'] = '0'; } $url .= '?' . http_build_query($params, '', '&'); try { Http::sendHttpRequest($url, $timeout = 2); } catch (Exception $e) { // e.g., disable_functions = fsockopen; allow_url_open = Off } } $this->redirectToNextStep(__FUNCTION__); } catch (Exception $e) { $view->errorMessage = $e->getMessage(); } } $view->addForm($form); return $view->render(); } /** * Installation Step 7: Configure first web-site */ public function firstWebsiteSetup() { $this->checkPreviousStepIsValid(__FUNCTION__); $view = new View( '@Installation/firstWebsiteSetup', $this->getInstallationSteps(), __FUNCTION__ ); $this->skipThisStep(__FUNCTION__); $form = new FormFirstWebsiteSetup(); if (!isset($this->session->generalSetupSuccessMessage)) { $view->displayGeneralSetupSuccess = true; $this->session->generalSetupSuccessMessage = true; } $this->initObjectsToCallAPI(); if ($form->validate()) { $name = Common::unsanitizeInputValue($form->getSubmitValue('siteName')); $url = Common::unsanitizeInputValue($form->getSubmitValue('url')); $ecommerce = (int)$form->getSubmitValue('ecommerce'); try { $result = APISitesManager::getInstance()->addSite($name, $url, $ecommerce); $this->session->site_idSite = $result; $this->session->site_name = $name; $this->session->site_url = $url; $this->redirectToNextStep(__FUNCTION__); } catch (Exception $e) { $view->errorMessage = $e->getMessage(); } } $view->addForm($form); return $view->render(); } /** * Installation Step 8: Display JavaScript tracking code */ public function trackingCode() { $this->checkPreviousStepIsValid(__FUNCTION__); $view = new View( '@Installation/trackingCode', $this->getInstallationSteps(), __FUNCTION__ ); $this->skipThisStep(__FUNCTION__); if (!isset($this->session->firstWebsiteSetupSuccessMessage)) { $view->displayfirstWebsiteSetupSuccess = true; $this->session->firstWebsiteSetupSuccessMessage = true; } $siteName = $this->session->site_name; $idSite = $this->session->site_idSite; // Load the Tracking code and help text from the SitesManager $viewTrackingHelp = new \Piwik\View('@SitesManager/_displayJavascriptCode'); $viewTrackingHelp->displaySiteName = $siteName; $viewTrackingHelp->jsTag = Piwik::getJavascriptCode($idSite, Url::getCurrentUrlWithoutFileName()); $viewTrackingHelp->idSite = $idSite; $viewTrackingHelp->piwikUrl = Url::getCurrentUrlWithoutFileName(); $view->trackingHelp = $viewTrackingHelp->render(); $view->displaySiteName = $siteName; $view->showNextStep = true; $this->session->currentStepDone = __FUNCTION__; return $view->render(); } /** * Installation Step 9: Finished! */ public function finished() { $this->checkPreviousStepIsValid(__FUNCTION__); $view = new View( '@Installation/finished', $this->getInstallationSteps(), __FUNCTION__ ); $this->skipThisStep(__FUNCTION__); if (!$this->isFinishedInstallation()) { $this->addTrustedHosts(); $this->markInstallationAsCompleted(); } $view->showNextStep = false; $this->session->currentStepDone = __FUNCTION__; $output = $view->render(); $this->session->unsetAll(); return $output; } /** * This controller action renders an admin tab that runs the installation * system check, so people can see if there are any issues w/ their running * Piwik installation. * * This admin tab is only viewable by the Super User. */ public function systemCheckPage() { Piwik::checkUserHasSuperUserAccess(); $view = new View( '@Installation/systemCheckPage', $this->getInstallationSteps(), __FUNCTION__ ); $this->setBasicVariablesView($view); $view->duringInstall = false; $this->setupSystemCheckView($view); $infos = $view->infos; $infos['extra'] = self::performAdminPageOnlySystemCheck(); $view->infos = $infos; return $view->render(); } /** * Instantiate access and log objects */ protected function initObjectsToCallAPI() { Piwik::setUserHasSuperUserAccess(); } /** * Write configuration file from session-store */ protected function createConfigFileIfNeeded($dbInfos) { $config = Config::getInstance(); try { // expect exception since config.ini.php doesn't exist yet $config->checkLocalConfigFound(); } catch (Exception $e) { if (!empty($this->session->general_infos)) { $config->General = $this->session->general_infos; } } $config->General['installation_in_progress'] = 1; $config->database = $dbInfos; $config->forceSave(); unset($this->session->general_infos); } /** * Write configuration file from session-store */ protected function markInstallationAsCompleted() { $config = Config::getInstance(); unset($config->General['installation_in_progress']); $config->forceSave(); } /** * Save language selection in session-store */ public function saveLanguage() { $language = Common::getRequestVar('language'); LanguagesManager::setLanguageForSession($language); Url::redirectToReferrer(); } /** * Prints out the CSS for installer/updater * * During installation and update process, we load a minimal Less file. * At this point Piwik may not be setup yet to write files in tmp/assets/ * so in this case we compile and return the string on every request. */ public function getBaseCss() { @header('Content-Type: text/css'); return AssetManager::getInstance()->getCompiledBaseCss()->getContent(); } /** * The previous step is valid if it is either * - any step before (OK to go back) * - the current step (case when validating a form) * If step is invalid, then exit. * * @param string $currentStep Current step */ protected function checkPreviousStepIsValid($currentStep) { $error = false; if (empty($this->session->currentStepDone)) { $error = true; } else if ($currentStep == 'finished' && $this->session->currentStepDone == 'finished') { // ok to refresh this page or use language selector } else if ($currentStep == 'reuseTables' && in_array($this->session->currentStepDone, array('tablesCreation', 'reuseTables'))) { // this is ok, we cannot add 'reuseTables' to steps as it would appear in the menu otherwise } else { if ($this->isFinishedInstallation()) { $error = true; } $steps = array_keys($this->steps); // the currentStep $currentStepId = array_search($currentStep, $steps); // the step before $previousStepId = array_search($this->session->currentStepDone, $steps); // not OK if currentStepId > previous+1 if ($currentStepId > $previousStepId + 1) { $error = true; } } if ($error) { \Piwik\Plugins\Login\Controller::clearSession(); $message = Piwik::translate('Installation_ErrorInvalidState', array('
', '', '', '') ); Piwik::exitWithErrorMessage($message); } } /** * Redirect to next step * * @param string $currentStep Current step * @return void */ protected function redirectToNextStep($currentStep) { $steps = array_keys($this->steps); $this->session->currentStepDone = $currentStep; $nextStep = $steps[1 + array_search($currentStep, $steps)]; Piwik::redirectToModule('Installation', $nextStep); } /** * Skip this step (typically to mark the current function as completed) * * @param string $step function name */ protected function skipThisStep($step) { $skipThisStep = $this->session->skipThisStep; if (isset($skipThisStep[$step]) && $skipThisStep[$step]) { $this->redirectToNextStep($step); } } /** * Extract host from URL * * @param string $url URL * * @return string|false */ protected function extractHost($url) { $urlParts = parse_url($url); if (isset($urlParts['host']) && strlen($host = $urlParts['host'])) { return $host; } return false; } /** * Add trusted hosts */ protected function addTrustedHosts() { $trustedHosts = array(); // extract host from the request header if (($host = $this->extractHost('http://' . Url::getHost())) !== false) { $trustedHosts[] = $host; } // extract host from first web site if (($host = $this->extractHost(urldecode($this->session->site_url))) !== false) { $trustedHosts[] = $host; } $trustedHosts = array_unique($trustedHosts); if (count($trustedHosts)) { $general = Config::getInstance()->General; $general['trusted_hosts'] = $trustedHosts; Config::getInstance()->General = $general; Config::getInstance()->forceSave(); } } /** * Get system information */ public static function getSystemInformation() { global $piwik_minimumPHPVersion; $minimumMemoryLimit = Config::getInstance()->General['minimum_memory_limit']; $infos = array(); $infos['general_infos'] = array(); $directoriesToCheck = array( '/tmp/', '/tmp/assets/', '/tmp/cache/', '/tmp/climulti/', '/tmp/latest/', '/tmp/logs/', '/tmp/sessions/', '/tmp/tcpdf/', '/tmp/templates_c/', ); if (!DbHelper::isInstalled()) { // at install, need /config to be writable (so we can create config.ini.php) $directoriesToCheck[] = '/config/'; } $infos['directories'] = Filechecks::checkDirectoriesWritable($directoriesToCheck); $infos['can_auto_update'] = Filechecks::canAutoUpdate(); self::initServerFilesForSecurity(); $infos['phpVersion_minimum'] = $piwik_minimumPHPVersion; $infos['phpVersion'] = PHP_VERSION; $infos['phpVersion_ok'] = version_compare($piwik_minimumPHPVersion, $infos['phpVersion']) === -1; // critical errors $extensions = @get_loaded_extensions(); $needed_extensions = array( 'zlib', 'SPL', 'iconv', 'json', 'mbstring', ); // HHVM provides the required subset of Reflection but lists Reflections as missing if (!defined('HHVM_VERSION')) { $needed_extensions[] = 'Reflection'; } $infos['needed_extensions'] = $needed_extensions; $infos['missing_extensions'] = array(); foreach ($needed_extensions as $needed_extension) { if (!in_array($needed_extension, $extensions)) { $infos['missing_extensions'][] = $needed_extension; } } // Special case for mbstring if (!function_exists('mb_get_info') || ((int)ini_get('mbstring.func_overload')) != 0) { $infos['missing_extensions'][] = 'mbstring'; } $infos['pdo_ok'] = false; if (in_array('PDO', $extensions)) { $infos['pdo_ok'] = true; } $infos['adapters'] = Adapter::getAdapters(); $needed_functions = array( 'debug_backtrace', 'create_function', 'eval', 'gzcompress', 'gzuncompress', 'pack', ); $infos['needed_functions'] = $needed_functions; $infos['missing_functions'] = array(); foreach ($needed_functions as $needed_function) { if (!self::functionExists($needed_function)) { $infos['missing_functions'][] = $needed_function; } } // warnings $desired_extensions = array( 'json', 'libxml', 'dom', 'SimpleXML', ); $infos['desired_extensions'] = $desired_extensions; $infos['missing_desired_extensions'] = array(); foreach ($desired_extensions as $desired_extension) { if (!in_array($desired_extension, $extensions)) { $infos['missing_desired_extensions'][] = $desired_extension; } } $desired_functions = array( 'set_time_limit', 'mail', 'parse_ini_file', 'glob', ); $infos['desired_functions'] = $desired_functions; $infos['missing_desired_functions'] = array(); foreach ($desired_functions as $desired_function) { if (!self::functionExists($desired_function)) { $infos['missing_desired_functions'][] = $desired_function; } } $infos['openurl'] = Http::getTransportMethod(); $infos['gd_ok'] = SettingsServer::isGdExtensionEnabled(); $serverSoftware = isset($_SERVER['SERVER_SOFTWARE']) ? $_SERVER['SERVER_SOFTWARE'] : ''; $infos['serverVersion'] = addslashes($serverSoftware); $infos['serverOs'] = @php_uname(); $infos['serverTime'] = date('H:i:s'); $infos['memoryMinimum'] = $minimumMemoryLimit; $infos['memory_ok'] = true; $infos['memoryCurrent'] = ''; $raised = SettingsServer::raiseMemoryLimitIfNecessary(); if (($memoryValue = SettingsServer::getMemoryLimitValue()) > 0) { $infos['memoryCurrent'] = $memoryValue . 'M'; $infos['memory_ok'] = $memoryValue >= $minimumMemoryLimit; } $infos['isWindows'] = SettingsServer::isWindows(); $integrityInfo = Filechecks::getFileIntegrityInformation(); $infos['integrity'] = $integrityInfo[0]; $infos['integrityErrorMessages'] = array(); if (isset($integrityInfo[1])) { if ($infos['integrity'] == false) { $infos['integrityErrorMessages'][] = Piwik::translate('General_FileIntegrityWarningExplanation'); } $infos['integrityErrorMessages'] = array_merge($infos['integrityErrorMessages'], array_slice($integrityInfo, 1)); } $infos['timezone'] = SettingsServer::isTimezoneSupportEnabled(); $infos['tracker_status'] = Common::getRequestVar('trackerStatus', 0, 'int'); $infos['protocol'] = ProxyHeaders::getProtocolInformation(); if (!\Piwik\ProxyHttp::isHttps() && $infos['protocol'] !== null) { $infos['general_infos']['assume_secure_protocol'] = '1'; } if (count($headers = ProxyHeaders::getProxyClientHeaders()) > 0) { $infos['general_infos']['proxy_client_headers'] = $headers; } if (count($headers = ProxyHeaders::getProxyHostHeaders()) > 0) { $infos['general_infos']['proxy_host_headers'] = $headers; } // check if filesystem is NFS, if it is file based sessions won't work properly $infos['is_nfs'] = Filesystem::checkIfFileSystemIsNFS(); $infos = self::enrichSystemChecks($infos); return $infos; } /** * @param $infos * @return mixed */ public static function enrichSystemChecks($infos) { // determine whether there are any errors/warnings from the checks done above $infos['has_errors'] = false; $infos['has_warnings'] = false; if (in_array(0, $infos['directories']) // if a directory is not writable || !$infos['phpVersion_ok'] || !empty($infos['missing_extensions']) || empty($infos['adapters']) || !empty($infos['missing_functions']) ) { $infos['has_errors'] = true; } if ( !empty($infos['missing_desired_extensions']) || !$infos['gd_ok'] || !$infos['memory_ok'] || !empty($infos['integrityErrorMessages']) || !$infos['timezone'] // if timezone support isn't available || $infos['tracker_status'] != 0 || $infos['is_nfs'] ) { $infos['has_warnings'] = true; } return $infos; } /** * Test if function exists. Also handles case where function is disabled via Suhosin. * * @param string $functionName Function name * @return bool True if function exists (not disabled); False otherwise. */ public static function functionExists($functionName) { // eval() is a language construct if ($functionName == 'eval') { // does not check suhosin.executor.eval.whitelist (or blacklist) if (extension_loaded('suhosin')) { return @ini_get("suhosin.executor.disable_eval") != "1"; } return true; } $exists = function_exists($functionName); if (extension_loaded('suhosin')) { $blacklist = @ini_get("suhosin.executor.func.blacklist"); if (!empty($blacklist)) { $blacklistFunctions = array_map('strtolower', array_map('trim', explode(',', $blacklist))); return $exists && !in_array($functionName, $blacklistFunctions); } } return $exists; } /** * Utility function, sets up a view that will display system check info. * * @param View $view */ private function setupSystemCheckView($view) { $view->infos = self::getSystemInformation(); $view->helpMessages = array( 'zlib' => 'Installation_SystemCheckZlibHelp', 'SPL' => 'Installation_SystemCheckSplHelp', 'iconv' => 'Installation_SystemCheckIconvHelp', 'mbstring' => 'Installation_SystemCheckMbstringHelp', 'Reflection' => 'Required extension that is built in PHP, see http://www.php.net/manual/en/book.reflection.php', 'json' => 'Installation_SystemCheckWarnJsonHelp', 'libxml' => 'Installation_SystemCheckWarnLibXmlHelp', 'dom' => 'Installation_SystemCheckWarnDomHelp', 'SimpleXML' => 'Installation_SystemCheckWarnSimpleXMLHelp', 'set_time_limit' => 'Installation_SystemCheckTimeLimitHelp', 'mail' => 'Installation_SystemCheckMailHelp', 'parse_ini_file' => 'Installation_SystemCheckParseIniFileHelp', 'glob' => 'Installation_SystemCheckGlobHelp', 'debug_backtrace' => 'Installation_SystemCheckDebugBacktraceHelp', 'create_function' => 'Installation_SystemCheckCreateFunctionHelp', 'eval' => 'Installation_SystemCheckEvalHelp', 'gzcompress' => 'Installation_SystemCheckGzcompressHelp', 'gzuncompress' => 'Installation_SystemCheckGzuncompressHelp', 'pack' => 'Installation_SystemCheckPackHelp', 'php5-json' => 'Installation_SystemCheckJsonHelp', ); $view->problemWithSomeDirectories = (false !== array_search(false, $view->infos['directories'])); } /** * Performs extra system checks for the 'System Check' admin page. These * checks are not performed during Installation. * * The following checks are performed: * - Check for whether LOAD DATA INFILE can be used. The result of the check * is stored in $result['load_data_infile_available']. The error message is * stored in $result['load_data_infile_error']. * * - Check whether geo location is setup correctly * * @return array */ public static function performAdminPageOnlySystemCheck() { $result = array(); self::checkLoadDataInfile($result); self::checkGeolocation($result); return $result; } private static function checkGeolocation(&$result) { $currentProviderId = LocationProvider::getCurrentProviderId(); $allProviders = LocationProvider::getAllProviderInfo(); $isRecommendedProvider = in_array($currentProviderId, array( LocationProvider\GeoIp\Php::ID, $currentProviderId == LocationProvider\GeoIp\Pecl::ID)); $isProviderInstalled = ($allProviders[$currentProviderId]['status'] == LocationProvider::INSTALLED); $result['geolocation_using_non_recommended'] = $result['geolocation_ok'] = false; if ($isRecommendedProvider && $isProviderInstalled) { $result['geolocation_ok'] = true; } elseif ($isProviderInstalled) { $result['geolocation_using_non_recommended'] = true; } } private static function checkLoadDataInfile(&$result) { // check if LOAD DATA INFILE works $optionTable = Common::prefixTable('option'); $testOptionNames = array('test_system_check1', 'test_system_check2'); $result['load_data_infile_available'] = false; try { $result['load_data_infile_available'] = Db\BatchInsert::tableInsertBatch( $optionTable, array('option_name', 'option_value'), array( array($testOptionNames[0], '1'), array($testOptionNames[1], '2'), ), $throwException = true ); } catch (Exception $ex) { $result['load_data_infile_error'] = str_replace("\n", "
", $ex->getMessage()); } // delete the temporary rows that were created Db::exec("DELETE FROM `$optionTable` WHERE option_name IN ('" . implode("','", $testOptionNames) . "')"); } private function createSuperUser($login, $password, $email) { $this->initObjectsToCallAPI(); $api = APIUsersManager::getInstance(); $api->addUser($login, $password, $email); $this->initObjectsToCallAPI(); $api->setSuperUserAccess($login, true); } private function isFinishedInstallation() { $isConfigFileFound = file_exists(Config::getInstance()->getLocalPath()); if (!$isConfigFileFound) { return false; } $general = Config::getInstance()->General; $isInstallationInProgress = false; if (array_key_exists('installation_in_progress', $general)) { $isInstallationInProgress = (bool) $general['installation_in_progress']; } return !$isInstallationInProgress; } private function hasEnoughTablesToReuseDb($tablesInstalled) { if (empty($tablesInstalled) || !is_array($tablesInstalled)) { return false; } $archiveTables = ArchiveTableCreator::getTablesArchivesInstalled(); $baseTablesInstalled = count($tablesInstalled) - count($archiveTables); $minimumCountPiwikTables = 12; return $baseTablesInstalled >= $minimumCountPiwikTables; } }