Newer
Older
<?php
/**
* Piwik - Open source web analytics
robocoder
a validé
*
* @link http://piwik.org
robocoder
a validé
*
mattab
a validé
* @package Installation
mattab
a validé
namespace Piwik\Plugins\Installation;
use Exception;
use Piwik\API\Request;
use Piwik\AssetManager;
use Piwik\Common;
use Piwik\Config;
use Piwik\DataAccess\ArchiveTableCreator;
use Piwik\Db\Adapter;
mattab
a validé
use Piwik\Db;
mattab
a validé
use Piwik\Plugins\LanguagesManager\LanguagesManager;
use Piwik\Plugins\SitesManager\API as APISitesManager;
use Piwik\Plugins\UsersManager\API as APIUsersManager;
use Piwik\ProxyHeaders;
use Piwik\Session\SessionNamespace;
use Piwik\SettingsServer;
use Piwik\Updater;
use Piwik\Url;
use Piwik\Version;
mattab
a validé
use Zend_Db_Adapter_Exception;
robocoder
a validé
* Installation controller
robocoder
a validé
*
mattab
a validé
* @package Installation
mattab
a validé
class Controller extends \Piwik\Controller\Admin
// public so plugins can add/delete installation steps
public $steps = array(
mattab
a validé
'welcome' => 'Installation_Welcome',
'systemCheck' => 'Installation_SystemCheck',
'databaseSetup' => 'Installation_DatabaseSetup',
'databaseCheck' => 'Installation_DatabaseCheck',
'tablesCreation' => 'Installation_Tables',
'generalSetup' => 'Installation_SuperUser',
'firstWebsiteSetup' => 'Installation_SetupWebsite',
'trackingCode' => 'General_JsTrackingTag',
mattab
a validé
'finished' => 'Installation_Congratulations',
);
protected $session;
public function __construct()
{
mattab
a validé
$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();
mattab
a validé
$view = new View(
$this->getInstallationSteps(),
__FUNCTION__
);
$isConfigFileFound = file_exists(Config::getLocalConfigPath());
$view->newInstall = !$isConfigFileFound;
$view->errorMessage = $message;
$this->skipThisStep(__FUNCTION__);
$view->showNextStep = $view->newInstall;
$this->session->currentStepDone = __FUNCTION__;
echo $view->render();
}
/**
* Installation Step 2: System Check
*/
function systemCheck()
{
$this->checkPreviousStepIsValid(__FUNCTION__);
mattab
a validé
$view = new View(
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
$this->getInstallationSteps(),
__FUNCTION__
);
$this->skipThisStep(__FUNCTION__);
$view->duringInstall = true;
$this->setupSystemCheckView($view);
$this->session->general_infos = $view->infos['general_infos'];
// 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__;
echo $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(
mattab
a validé
'firstWebsiteSetup' => false,
'trackingCode' => false,
);
mattab
a validé
$view = new View(
$this->getInstallationSteps(),
__FUNCTION__
);
$this->skipThisStep(__FUNCTION__);
$view->showNextStep = false;
mattab
a validé
$form = new FormDatabaseSetup();
if ($form->validate()) {
try {
$dbInfos = $form->createDatabaseObject();
$this->session->databaseCreated = true;
$this->session->databaseVersionOk = true;
$this->session->db_infos = $dbInfos;
$this->redirectToNextStep(__FUNCTION__);
} catch (Exception $e) {
$view->errorMessage = Common::sanitizeInputValue($e->getMessage());
}
}
$view->addForm($form);
echo $view->render();
}
/**
* Installation Step 4: Database Check
*/
function databaseCheck()
{
$this->checkPreviousStepIsValid(__FUNCTION__);
mattab
a validé
$view = new View(
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
$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
) {
$dbInfos = $this->session->db_infos;
$view->databaseName = $dbInfos['dbname'];
$view->databaseCreated = true;
} else {
$error = true;
}
$this->createDbFromSessionInformation();
try {
$db->checkClientVersion();
} catch (Exception $e) {
$view->clientVersionWarning = $e->getMessage();
$error = true;
}
if (!DbHelper::isDatabaseConnectionUTF8()) {
$dbInfos = $this->session->db_infos;
$dbInfos['charset'] = 'utf8';
$this->session->db_infos = $dbInfos;
}
$view->showNextStep = true;
$this->session->currentStepDone = __FUNCTION__;
if ($error === false) {
$this->redirectToNextStep(__FUNCTION__);
}
echo $view->render();
}
/**
* Installation Step 5: Table Creation
*/
function tablesCreation()
{
$this->checkPreviousStepIsValid(__FUNCTION__);
mattab
a validé
$view = new View(
$this->getInstallationSteps(),
__FUNCTION__
);
$this->skipThisStep(__FUNCTION__);
$this->createDbFromSessionInformation();
if (Common::getRequestVar('deleteTables', 0, 'int') == 1) {
$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;
// remove monthly archive tables
$archiveTables = ArchiveTableCreator::getTablesArchivesInstalled();
$baseTablesInstalled = count($tablesInstalled) - count($archiveTables);
$minimumCountPiwikTables = 17;
Piwik::setUserIsSuperUser();
if ($baseTablesInstalled >= $minimumCountPiwikTables &&
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 {
Updater::recordComponentSuccessfullyUpdated('core', Version::VERSION);
$view->tablesCreated = true;
$view->showNextStep = true;
}
$this->session->currentStepDone = __FUNCTION__;
echo $view->render();
}
/**
* Installation Step 6: General Set-up (superuser login/password/email and subscriptions)
*/
function generalSetup()
{
$this->checkPreviousStepIsValid(__FUNCTION__);
mattab
a validé
$view = new View(
$this->getInstallationSteps(),
__FUNCTION__
);
$this->skipThisStep(__FUNCTION__);
mattab
a validé
$form = new FormGeneralSetup();
if ($form->validate()) {
$superUserInfos = array(
'login' => $form->getSubmitValue('login'),
'password' => md5($form->getSubmitValue('password')),
'email' => $form->getSubmitValue('email'),
'salt' => Common::generateUniqId(),
);
$this->session->superuser_infos = $superUserInfos;
$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__);
}
$view->addForm($form);
echo $view->render();
}
/**
* Installation Step 7: Configure first web-site
*/
public function firstWebsiteSetup()
{
$this->checkPreviousStepIsValid(__FUNCTION__);
mattab
a validé
$view = new View(
$this->getInstallationSteps(),
__FUNCTION__
);
$this->skipThisStep(__FUNCTION__);
mattab
a validé
$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');
$request = new Request("
method=SitesManager.addSite
&siteName=$name
&urls=$url
&ecommerce=$ecommerce
&format=original
");
robocoder
a validé
try {
$result = $request->process();
$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);
echo $view->render();
}
/**
* Installation Step 8: Display JavaScript tracking code
*/
public function trackingCode()
{
$this->checkPreviousStepIsValid(__FUNCTION__);
mattab
a validé
$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__;
echo $view->render();
}
/**
* Installation Step 9: Finished!
*/
public function finished()
{
$this->checkPreviousStepIsValid(__FUNCTION__);
mattab
a validé
$view = new View(
$this->getInstallationSteps(),
__FUNCTION__
);
$this->skipThisStep(__FUNCTION__);
$configPath = Config::getLocalConfigPath();
if (!file_exists($configPath)) {
$this->writeConfigFileFromSession();
}
$view->showNextStep = false;
$this->session->currentStepDone = __FUNCTION__;
echo $view->render();
$this->session->unsetAll();
}
/**
* 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::checkUserIsSuperUser();
$view = new View(
'@Installation/systemCheckPage',
$this->getInstallationSteps(),
__FUNCTION__
);
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
$this->setBasicVariablesView($view);
$view->duringInstall = false;
$this->setupSystemCheckView($view);
$infos = $view->infos;
$infos['extra'] = self::performAdminPageOnlySystemCheck();
$view->infos = $infos;
echo $view->render();
}
/**
* Instantiate access and log objects
*/
protected function initObjectsToCallAPI()
{
// connect to the database using the DB infos currently in the session
$this->createDbFromSessionInformation();
Piwik::setUserIsSuperUser();
}
/**
* Create database connection from session-store
*/
protected function createDbFromSessionInformation()
{
$dbInfos = $this->session->db_infos;
Config::getInstance()->database = $dbInfos;
Db::createDatabaseObject($dbInfos);
}
/**
* Write configuration file from session-store
*/
protected function writeConfigFileFromSession()
{
if (!isset($this->session->superuser_infos)
|| !isset($this->session->db_infos)
) {
return;
}
$config = Config::getInstance();
try {
// expect exception since config.ini.php doesn't exist yet
} catch (Exception $e) {
$config->superuser = $this->session->superuser_infos;
$config->database = $this->session->db_infos;
if (!empty($this->session->general_infos)) {
$config->General = $this->session->general_infos;
}
$config->forceSave();
}
unset($this->session->superuser_infos);
unset($this->session->db_infos);
unset($this->session->general_infos);
}
/**
* Save language selection in session-store
*/
public function saveLanguage()
{
$language = Common::getRequestVar('language');
mattab
a validé
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()
{
Benaka Moorthi
a validé
@header('Content-Type: text/css');
echo AssetManager::getCompiledBaseCss();
}
/**
* 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 (file_exists(Config::getLocalConfigPath())) {
$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) {
mattab
a validé
\Piwik\Plugins\Login\Controller::clearSession();
$message = Piwik::translate('Installation_ErrorInvalidState',
'<a href=\'' . Common::sanitizeInputValue(Url::getCurrentUrlWithoutFileName()) . '\'>',
'</a>')
);
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)
*
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
*/
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)) {
$this->session->general_infos['trusted_hosts'] = $trustedHosts;
}
}
/**
* 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();
// at install, need /config to be writable (so we can create config.ini.php)
$directoriesToCheck[] = '/config/';
}
$directoriesToCheck = array_merge($directoriesToCheck, array(
mattab
a validé
'/tmp/',
'/tmp/assets/',
'/tmp/cache/',
mattab
a validé
'/tmp/latest/',
'/tmp/logs/',
mattab
a validé
'/tmp/sessions/',
'/tmp/tcpdf/',
'/tmp/templates_c/',
mattab
a validé
));
$infos['directories'] = Filechecks::checkDirectoriesWritable($directoriesToCheck);
$infos['can_auto_update'] = Filechecks::canAutoUpdate();
self::initServerFilesForSecurity();
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
$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',
'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;
}
}
$infos['pdo_ok'] = false;
if (in_array('PDO', $extensions)) {
$infos['pdo_ok'] = true;
}
$infos['adapters'] = Adapter::getAdapters();
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
$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();
$infos['hasMbstring'] = false;
$infos['multibyte_ok'] = true;
if (function_exists('mb_internal_encoding')) {
$infos['hasMbstring'] = true;
if (((int)ini_get('mbstring.func_overload')) != 0) {
$infos['multibyte_ok'] = false;
}
}
$serverSoftware = isset($_SERVER['SERVER_SOFTWARE']) ? $_SERVER['SERVER_SOFTWARE'] : '';
$infos['serverVersion'] = addslashes($serverSoftware);
$infos['serverOs'] = @php_uname();
$infos['serverTime'] = date('H:i:s');
$infos['registerGlobals_ok'] = ini_get('register_globals') == 0;
$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();
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
// 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 (!$infos['can_auto_update']
|| !empty($infos['missing_desired_extensions'])
|| !$infos['gd_ok']
|| !$infos['multibyte_ok']
|| !$infos['registerGlobals_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
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
*/
private function setupSystemCheckView($view)
{
$view->infos = self::getSystemInformation();
$view->helpMessages = array(
'zlib' => 'Installation_SystemCheckZlibHelp',
'SPL' => 'Installation_SystemCheckSplHelp',
'iconv' => 'Installation_SystemCheckIconvHelp',
'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',
);
$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'].
*
* @return array
*/
public static function performAdminPageOnlySystemCheck()
{
$result = array();
// 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(