Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/matomo-org/matomo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authordiosmosis <benaka@piwik.pro>2015-04-09 06:36:22 +0300
committerdiosmosis <benaka@piwik.pro>2015-04-09 06:36:22 +0300
commit67829227ce2d0c4473466acbc42118a7a150b14c (patch)
tree973ebb1b5aa30d0b47a8d14ce73b7524a4051be0 /core
parent47e7d3a74c6b13431e489d2d652af53410f880ad (diff)
Added environment validation system test (mostly failing) that tests Piwik's behavior when INI files are gone or corrupt from each Piwik endpoint (tracker/reporting UI/console). Hacked test code to make it possible and for some tests to pass.
Diffstat (limited to 'core')
-rw-r--r--core/Application/Environment.php2
-rw-r--r--core/Application/Kernel/EnvironmentValidator.php14
-rw-r--r--core/Application/Kernel/GlobalSettingsProvider/IniSettingsProvider.php48
-rw-r--r--core/Application/Kernel/PluginList.php7
-rw-r--r--core/Application/Kernel/PluginList/IniPluginList.php16
-rw-r--r--core/Config.php105
-rw-r--r--core/Config/IniFileChain.php7
-rw-r--r--core/ExceptionHandler.php6
-rw-r--r--core/Plugin/Manager.php5
-rw-r--r--core/Translation/Translator.php3
10 files changed, 124 insertions, 89 deletions
diff --git a/core/Application/Environment.php b/core/Application/Environment.php
index 38a6c2eb5c..6687b015c4 100644
--- a/core/Application/Environment.php
+++ b/core/Application/Environment.php
@@ -150,6 +150,8 @@ class Environment
*/
protected function getGlobalSettings()
{
+ // TODO: need to be able to set path global/local/etc. which is in DI... for now works because TestingEnvironment creates
+ // singleton instance before this method.
return IniSettingsProvider::getSingletonInstance();
}
diff --git a/core/Application/Kernel/EnvironmentValidator.php b/core/Application/Kernel/EnvironmentValidator.php
index 9474652ac9..9e116a7cb1 100644
--- a/core/Application/Kernel/EnvironmentValidator.php
+++ b/core/Application/Kernel/EnvironmentValidator.php
@@ -12,6 +12,7 @@ use Piwik\Application\Kernel\GlobalSettingsProvider\IniSettingsProvider;
use Piwik\Common;
use Piwik\Piwik;
use Piwik\SettingsServer;
+use Piwik\Translate;
use Piwik\Translation\Translator;
/**
@@ -33,6 +34,7 @@ class EnvironmentValidator
public function __construct(GlobalSettingsProvider $settingsProvider, Translator $translator)
{
$this->iniSettingsProvider = $settingsProvider;
+ $this->translator = $translator;
}
public function validate()
@@ -40,23 +42,23 @@ class EnvironmentValidator
$inTrackerRequest = SettingsServer::isTrackerApiRequest();
$inConsole = Common::isPhpCliMode();
- $this->checkConfigFileExists('global.ini.php');
- $this->checkConfigFileExists('config.ini.php', $startInstaller = !$inTrackerRequest && !$inConsole);
+ $this->checkConfigFileExists($this->iniSettingsProvider->getPathGlobal());
+ $this->checkConfigFileExists($this->iniSettingsProvider->getPathLocal(), $startInstaller = !$inTrackerRequest && !$inConsole);
}
/**
- * @param $filename
+ * @param $path
* @param bool $startInstaller
* @throws \Exception
*/
- private function checkConfigFileExists($filename, $startInstaller = false)
+ private function checkConfigFileExists($path, $startInstaller = false)
{
- $path = PIWIK_INCLUDE_PATH . '/config/' . $filename;
-
if (is_readable($path)) {
return;
}
+ Translate::loadAllTranslations();
+
$message = $this->translator->translate('General_ExceptionConfigurationFileNotFound', array($path));
$exception = new \Exception($message);
diff --git a/core/Application/Kernel/GlobalSettingsProvider/IniSettingsProvider.php b/core/Application/Kernel/GlobalSettingsProvider/IniSettingsProvider.php
index 07dd25606e..75123b1645 100644
--- a/core/Application/Kernel/GlobalSettingsProvider/IniSettingsProvider.php
+++ b/core/Application/Kernel/GlobalSettingsProvider/IniSettingsProvider.php
@@ -28,17 +28,42 @@ class IniSettingsProvider implements GlobalSettingsProvider
private $iniFileChain;
/**
+ * @var string
+ */
+ protected $pathGlobal = null;
+
+ /**
+ * @var string
+ */
+ protected $pathCommon = null;
+
+ /**
+ * @var string
+ */
+ protected $pathLocal = null;
+
+ /**
* @param string|null $pathGlobal Path to the global.ini.php file. Or null to use the default.
* @param string|null $pathLocal Path to the config.ini.php file. Or null to use the default.
* @param string|null $pathCommon Path to the common.ini.php file. Or null to use the default.
*/
public function __construct($pathGlobal = null, $pathLocal = null, $pathCommon = null)
{
- $pathGlobal = $pathGlobal ?: Config::getGlobalConfigPath();
- $pathCommon = $pathCommon ?: Config::getCommonConfigPath();
- $pathLocal = $pathLocal ?: Config::getLocalConfigPath();
+ $this->pathGlobal = $pathGlobal ?: Config::getGlobalConfigPath();
+ $this->pathCommon = $pathCommon ?: Config::getCommonConfigPath();
+ $this->pathLocal = $pathLocal ?: Config::getLocalConfigPath();
+
+ $this->iniFileChain = new IniFileChain();
+ $this->reload();
+ }
+
+ public function reload($pathGlobal = null, $pathLocal = null, $pathCommon = null)
+ {
+ $this->pathGlobal = $pathGlobal ?: $this->pathGlobal;
+ $this->pathCommon = $pathCommon ?: $this->pathCommon;
+ $this->pathLocal = $pathLocal ?: $this->pathLocal;
- $this->iniFileChain = new IniFileChain(array($pathGlobal, $pathCommon), $pathLocal);
+ $this->iniFileChain->reload(array($this->pathGlobal, $this->pathCommon), $this->pathLocal);
}
public function &getSection($name)
@@ -57,6 +82,21 @@ class IniSettingsProvider implements GlobalSettingsProvider
return $this->iniFileChain;
}
+ public function getPathGlobal()
+ {
+ return $this->pathGlobal;
+ }
+
+ public function getPathLocal()
+ {
+ return $this->pathLocal;
+ }
+
+ public function getPathCommon()
+ {
+ return $this->pathCommon;
+ }
+
public static function getSingletonInstance($pathGlobal = null, $pathLocal = null, $pathCommon = null)
{
if (self::$instance === null) {
diff --git a/core/Application/Kernel/PluginList.php b/core/Application/Kernel/PluginList.php
index 9d5e03cc0a..672110853b 100644
--- a/core/Application/Kernel/PluginList.php
+++ b/core/Application/Kernel/PluginList.php
@@ -23,4 +23,11 @@ interface PluginList
* @return string[]
*/
public function getActivatedPlugins();
+
+ /**
+ * Returns the list of plugins that are bundled with Piwik.
+ *
+ * @return string[]
+ */
+ public function getPluginsBundledWithPiwik();
} \ No newline at end of file
diff --git a/core/Application/Kernel/PluginList/IniPluginList.php b/core/Application/Kernel/PluginList/IniPluginList.php
index 6636cc4fd6..8825661e82 100644
--- a/core/Application/Kernel/PluginList/IniPluginList.php
+++ b/core/Application/Kernel/PluginList/IniPluginList.php
@@ -9,16 +9,19 @@
namespace Piwik\Application\Kernel\PluginList;
use Piwik\Application\Kernel\GlobalSettingsProvider;
+use Piwik\Application\Kernel\GlobalSettingsProvider\IniSettingsProvider;
use Piwik\Application\Kernel\PluginList;
/**
* Default implementation of the PluginList interface. Uses the [Plugins] section
* in Piwik's INI config to get the activated plugins.
+ *
+ * Depends on IniSettingsProvider being used.
*/
class IniPluginList implements PluginList
{
/**
- * @var GlobalSettingsProvider
+ * @var IniSettingsProvider
*/
private $settings;
@@ -35,4 +38,15 @@ class IniPluginList implements PluginList
$section = $this->settings->getSection('Plugins');
return @$section['Plugins'] ?: array();
}
+
+ /**
+ * @return string[]
+ */
+ public function getPluginsBundledWithPiwik()
+ {
+ $pathGlobal = $this->settings->getPathGlobal();
+
+ $section = $this->settings->getIniFileChain()->getFrom($pathGlobal, 'Plugins');
+ return $section['Plugins'];
+ }
} \ No newline at end of file
diff --git a/core/Config.php b/core/Config.php
index 42cec66702..edc54d6a07 100644
--- a/core/Config.php
+++ b/core/Config.php
@@ -52,17 +52,10 @@ class Config extends Singleton
/**
* @var boolean
*/
- protected $pathGlobal = null;
- protected $pathCommon = null;
- protected $pathLocal = null;
-
- /**
- * @var boolean
- */
protected $doNotWriteConfigInTests = false;
/**
- * @var IniFileChain
+ * @var IniSettingsProvider
*/
protected $settings;
@@ -70,11 +63,7 @@ class Config extends Singleton
public function __construct($pathGlobal = null, $pathLocal = null, $pathCommon = null)
{
- $this->pathGlobal = $pathGlobal ?: self::getGlobalConfigPath();
- $this->pathCommon = $pathCommon ?: self::getCommonConfigPath();
- $this->pathLocal = $pathLocal ?: self::getLocalConfigPath();
-
- $this->settings = IniSettingsProvider::getSingletonInstance($pathGlobal, $pathLocal, $pathCommon)->getIniFileChain();
+ $this->settings = IniSettingsProvider::getSingletonInstance($pathGlobal, $pathLocal, $pathCommon);
}
/**
@@ -84,7 +73,7 @@ class Config extends Singleton
*/
public function getLocalPath()
{
- return $this->pathLocal;
+ return $this->settings->getPathLocal();
}
/**
@@ -94,7 +83,7 @@ class Config extends Singleton
*/
public function getGlobalPath()
{
- return $this->pathGlobal;
+ return $this->settings->getPathGlobal();
}
/**
@@ -104,7 +93,7 @@ class Config extends Singleton
*/
public function getCommonPath()
{
- return $this->pathCommon;
+ return $this->settings->getPathCommon();
}
/**
@@ -121,37 +110,35 @@ class Config extends Singleton
$this->doNotWriteConfigInTests = true;
}
- $this->pathLocal = $pathLocal ?: Config::getLocalConfigPath();
- $this->pathGlobal = $pathGlobal ?: Config::getGlobalConfigPath();
- $this->pathCommon = $pathCommon ?: Config::getCommonConfigPath();
+ $this->reload($pathLocal, $pathGlobal, $pathCommon);
- $this->reload();
+ $chain = $this->settings->getIniFileChain();
- $databaseTestsSettings = $this->settings->get('database_tests'); // has to be __get otherwise when called from TestConfig, PHP will issue a NOTICE
+ $databaseTestsSettings = $chain->get('database_tests'); // has to be __get otherwise when called from TestConfig, PHP will issue a NOTICE
if (!empty($databaseTestsSettings)) {
- $this->settings->set('database', $databaseTestsSettings);
+ $chain->set('database', $databaseTestsSettings);
}
// Ensure local mods do not affect tests
if (empty($pathGlobal)) {
- $this->settings->set('Debug', $this->settings->getFrom($this->pathGlobal, 'Debug'));
- $this->settings->set('mail', $this->settings->getFrom($this->pathGlobal, 'mail'));
- $this->settings->set('General', $this->settings->getFrom($this->pathGlobal, 'General'));
- $this->settings->set('Segments', $this->settings->getFrom($this->pathGlobal, 'Segments'));
- $this->settings->set('Tracker', $this->settings->getFrom($this->pathGlobal, 'Tracker'));
- $this->settings->set('Deletelogs', $this->settings->getFrom($this->pathGlobal, 'Deletelogs'));
- $this->settings->set('Deletereports', $this->settings->getFrom($this->pathGlobal, 'Deletereports'));
- $this->settings->set('Development', $this->settings->getFrom($this->pathGlobal, 'Development'));
+ $chain->set('Debug', $chain->getFrom($this->getGlobalPath(), 'Debug'));
+ $chain->set('mail', $chain->getFrom($this->getGlobalPath(), 'mail'));
+ $chain->set('General', $chain->getFrom($this->getGlobalPath(), 'General'));
+ $chain->set('Segments', $chain->getFrom($this->getGlobalPath(), 'Segments'));
+ $chain->set('Tracker', $chain->getFrom($this->getGlobalPath(), 'Tracker'));
+ $chain->set('Deletelogs', $chain->getFrom($this->getGlobalPath(), 'Deletelogs'));
+ $chain->set('Deletereports', $chain->getFrom($this->getGlobalPath(), 'Deletereports'));
+ $chain->set('Development', $chain->getFrom($this->getGlobalPath(), 'Development'));
}
// for unit tests, we set that no plugin is installed. This will force
// the test initialization to create the plugins tables, execute ALTER queries, etc.
- $this->settings->set('PluginsInstalled', array('PluginsInstalled' => array()));
+ $chain->set('PluginsInstalled', array('PluginsInstalled' => array()));
}
protected function postConfigTestEvent()
{
- Piwik::postTestEvent('Config.createConfigSingleton', array($this->settings, $this) );
+ Piwik::postTestEvent('Config.createConfigSingleton', array($this->settings->getIniFileChain(), $this) );
}
/**
@@ -230,7 +217,7 @@ class Config extends Singleton
return $limits;
}
- protected static function getByDomainConfigPath()
+ public static function getByDomainConfigPath()
{
$host = self::getHostname();
$hostConfig = self::getLocalConfigInfoForHostname($host);
@@ -281,16 +268,15 @@ class Config extends Singleton
throw new Exception('Piwik domain is not a valid looking hostname (' . $filename . ').');
}
- $this->pathLocal = $hostConfig['path'];
- $this->initialized = false;
+ $pathLocal = $hostConfig['path'];
try {
- $this->reload();
+ $this->reload($pathLocal);
} catch (Exception $ex) {
// pass (not required for local file to exist at this point)
}
- return $this->pathLocal;
+ return $pathLocal;
}
/**
@@ -300,7 +286,7 @@ class Config extends Singleton
*/
public function isFileWritable()
{
- return is_writable($this->pathLocal);
+ return is_writable($this->settings->getPathLocal());
}
/**
@@ -330,11 +316,10 @@ class Config extends Singleton
* @throws \Exception if the global config file is not found and this is a tracker request, or
* if the local config file is not found and this is NOT a tracker request.
*/
- protected function reload()
+ protected function reload($pathLocal = null, $pathGlobal = null, $pathCommon = null)
{
$this->initialized = false;
-
- $this->settings->reload(array($this->pathGlobal, $this->pathCommon), $this->pathLocal);
+ $this->settings->reload($pathGlobal, $pathLocal, $pathCommon);
}
/**
@@ -342,7 +327,7 @@ class Config extends Singleton
*/
public function existsLocalConfig()
{
- return is_readable($this->pathLocal);
+ return is_readable($this->getLocalPath());
}
public function deleteLocalConfig()
@@ -351,13 +336,6 @@ class Config extends Singleton
unlink($configLocal);
}
-/* public function checkLocalConfigFound()
- {
- if (!$this->existsLocalConfig()) {
- throw new ConfigNotFoundException(Piwik::translate('General_ExceptionConfigurationFileNotFound', array($this->pathLocal)));
- }
- }*/
-
/**
* Decode HTML entities
*
@@ -412,28 +390,21 @@ class Config extends Singleton
if (!$this->initialized) {
$this->initialized = true;
- // this is done lazily and not in __construct so Installation will properly be triggered. ideally, it should be
- // done in __construct, but the exception that is thrown depends on Translator which depends on Config. the
- // circular dependency causes problems.
- /*if (!SettingsServer::isTrackerApiRequest()) {
- $this->checkLocalConfigFound();
- }*/
-
$this->postConfigTestEvent();
}
- $section =& $this->settings->get($name);
+ $section =& $this->settings->getIniFileChain()->get($name);
return $section;
}
public function getFromGlobalConfig($name)
{
- return $this->settings->getFrom($this->pathGlobal, $name);
+ return $this->settings->getIniFileChain()->getFrom($this->getGlobalPath(), $name);
}
public function getFromCommonConfig($name)
{
- return $this->settings->getFrom($this->pathCommon, $name);
+ return $this->settings->getIniFileChain()->getFrom($this->getCommonPath(), $name);
}
/**
@@ -445,7 +416,7 @@ class Config extends Singleton
*/
public function __set($name, $value)
{
- $this->settings->set($name, $value);
+ $this->settings->getIniFileChain()->set($name, $value);
}
/**
@@ -456,16 +427,18 @@ class Config extends Singleton
*/
public function dumpConfig()
{
- $this->encodeValues($this->settings->getAll());
+ $chain = $this->settings->getIniFileChain();
+
+ $this->encodeValues($chain->getAll());
try {
$header = "; <?php exit; ?> DO NOT REMOVE THIS LINE\n";
$header .= "; file automatically generated or modified by Piwik; you can manually override the default values in global.ini.php by redefining them in this file.\n";
- $dumpedString = $this->settings->dumpChanges($header);
+ $dumpedString = $chain->dumpChanges($header);
- $this->decodeValues($this->settings->getAll());
+ $this->decodeValues($chain->getAll());
} catch (Exception $ex) {
- $this->decodeValues($this->settings->getAll());
+ $this->decodeValues($chain->getAll());
throw $ex;
}
@@ -495,7 +468,7 @@ class Config extends Singleton
if ($output !== null
&& $output !== false
) {
- $success = @file_put_contents($this->pathLocal, $output);
+ $success = @file_put_contents($this->getLocalPath(), $output);
if ($success === false) {
throw $this->getConfigNotWritableException();
}
@@ -522,7 +495,7 @@ class Config extends Singleton
*/
public function getConfigNotWritableException()
{
- $path = "config/" . basename($this->pathLocal);
+ $path = "config/" . basename($this->getLocalPath());
return new Exception(Piwik::translate('General_ConfigFileIsNotWritable', array("(" . $path . ")", "")));
}
} \ No newline at end of file
diff --git a/core/Config/IniFileChain.php b/core/Config/IniFileChain.php
index bffca9cbc6..95516921b8 100644
--- a/core/Config/IniFileChain.php
+++ b/core/Config/IniFileChain.php
@@ -206,12 +206,7 @@ class IniFileChain
$reader = new IniReader();
foreach ($this->settingsChain as $file => $ignore) {
if (is_readable($file)) {
- try {
- $this->settingsChain[$file] = $reader->readFile($file);
- } catch (IniReadingException $ex) {
- $message = Piwik::translate('General_ExceptionUnreadableFileDisabledMethod', array($file, "parse_ini_file()"));
- throw new IniReadingException($message, $code = 0, $ex);
- }
+ $this->settingsChain[$file] = $reader->readFile($file);
}
}
diff --git a/core/ExceptionHandler.php b/core/ExceptionHandler.php
index e68a058e4a..5b02cd77f6 100644
--- a/core/ExceptionHandler.php
+++ b/core/ExceptionHandler.php
@@ -78,7 +78,11 @@ class ExceptionHandler
$logoHeaderUrl = $logo->getHeaderLogoUrl();
$logoFaviconUrl = $logo->getPathUserFavicon();
} catch (Exception $ex) {
- Log::debug($ex);
+ try {
+ Log::debug($ex);
+ } catch (\Exception $otherEx) {
+ // DI container may not be setup at this point
+ }
}
$result = Piwik_GetErrorMessagePage($message, $debugTrace, true, true, $logoHeaderUrl, $logoFaviconUrl);
diff --git a/core/Plugin/Manager.php b/core/Plugin/Manager.php
index 0d69083af7..1cdf9ebb2e 100644
--- a/core/Plugin/Manager.php
+++ b/core/Plugin/Manager.php
@@ -1280,9 +1280,7 @@ class Manager
*/
protected function getPluginsFromGlobalIniConfigFile() // TODO: if this is only used for sorting, move to PluginList
{
- $pluginsBundledWithPiwik = PiwikConfig::getInstance()->getFromGlobalConfig('Plugins');
- $pluginsBundledWithPiwik = $pluginsBundledWithPiwik['Plugins'];
- return $pluginsBundledWithPiwik;
+ return $this->pluginList->getPluginsBundledWithPiwik();
}
/**
@@ -1292,7 +1290,6 @@ class Manager
protected function isPluginEnabledByDefault($name)
{
$pluginsBundledWithPiwik = $this->getPluginsFromGlobalIniConfigFile();
-
if(empty($pluginsBundledWithPiwik)) {
return false;
}
diff --git a/core/Translation/Translator.php b/core/Translation/Translator.php
index dda946ccd9..46503a0185 100644
--- a/core/Translation/Translator.php
+++ b/core/Translation/Translator.php
@@ -114,7 +114,8 @@ class Translator
*/
public function getDefaultLanguage()
{
- return Config::getInstance()->General['default_language'];
+ $generalSection = Config::getInstance()->General;
+ return @$generalSection['default_language'] ?: 'en';
}
/**