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
diff options
context:
space:
mode:
Diffstat (limited to 'core/Plugin/Manager.php')
-rw-r--r--core/Plugin/Manager.php313
1 files changed, 137 insertions, 176 deletions
diff --git a/core/Plugin/Manager.php b/core/Plugin/Manager.php
index 9f8941170b..6e0d5ba91a 100644
--- a/core/Plugin/Manager.php
+++ b/core/Plugin/Manager.php
@@ -9,14 +9,12 @@
namespace Piwik\Plugin;
-use Piwik\Cache\PersistentCache;
-use Piwik\CacheFile;
+use Piwik\Cache;
use Piwik\Columns\Dimension;
-use Piwik\Common;
use Piwik\Config as PiwikConfig;
use Piwik\Config;
+use Piwik\Container\StaticContainer;
use Piwik\Db;
-use Piwik\Development;
use Piwik\EventDispatcher;
use Piwik\Filesystem;
use Piwik\Log;
@@ -26,9 +24,8 @@ use Piwik\Plugin;
use Piwik\Singleton;
use Piwik\Theme;
use Piwik\Tracker;
-use Piwik\Translate;
+use Piwik\Translation\Translator;
use Piwik\Updater;
-use Piwik\SettingsServer;
use Piwik\Plugin\Dimension\ActionDimension;
use Piwik\Plugin\Dimension\ConversionDimension;
use Piwik\Plugin\Dimension\VisitDimension;
@@ -93,12 +90,14 @@ class Manager extends Singleton
'ExampleTheme'
);
+ private $trackerPluginsNotToLoad = array();
+
/**
* Loads plugin that are enabled
*/
public function loadActivatedPlugins()
{
- $pluginsToLoad = Config::getInstance()->Plugins['Plugins'];
+ $pluginsToLoad = $this->getActivatedPluginsFromConfig();
$this->loadPlugins($pluginsToLoad);
}
@@ -108,7 +107,7 @@ class Manager extends Singleton
public function loadCorePluginsDuringTracker()
{
$pluginsToLoad = Config::getInstance()->Plugins['Plugins'];
- $pluginsToLoad = array_diff($pluginsToLoad, Tracker::getPluginsNotToLoad());
+ $pluginsToLoad = array_diff($pluginsToLoad, $this->getTrackerPluginsNotToLoad());
$this->loadPlugins($pluginsToLoad);
}
@@ -117,10 +116,11 @@ class Manager extends Singleton
*/
public function loadTrackerPlugins()
{
- $cache = new PersistentCache('PluginsTracker');
+ $cacheId = 'PluginsTracker';
+ $cache = Cache::getEagerCache();
- if ($cache->has()) {
- $pluginsTracker = $cache->get();
+ if ($cache->contains($cacheId)) {
+ $pluginsTracker = $cache->fetch($cacheId);
} else {
$this->unloadPlugins();
@@ -135,22 +135,46 @@ class Manager extends Singleton
}
if (!empty($pluginsTracker)) {
- $cache->set($pluginsTracker);
+ $cache->save($cacheId, $pluginsTracker);
}
}
- $this->unloadPlugins();
-
if (empty($pluginsTracker)) {
+ $this->unloadPlugins();
return array();
}
- $pluginsTracker = array_diff($pluginsTracker, Tracker::getPluginsNotToLoad());
+ $pluginsTracker = array_diff($pluginsTracker, $this->getTrackerPluginsNotToLoad());
$this->doNotLoadAlwaysActivatedPlugins();
$this->loadPlugins($pluginsTracker);
+
+ // we could simply unload all plugins first before loading plugins but this way it is much faster
+ // since we won't have to create each plugin again and we won't have to parse each plugin metadata file
+ // again etc
+ $this->makeSureOnlyActivatedPluginsAreLoaded();
+
return $pluginsTracker;
}
+ /**
+ * Do not load the specified plugins (used during testing, to disable Provider plugin)
+ * @param array $plugins
+ */
+ public function setTrackerPluginsNotToLoad($plugins)
+ {
+ $this->trackerPluginsNotToLoad = $plugins;
+ }
+
+ /**
+ * Get list of plugins to not load
+ *
+ * @return array
+ */
+ public function getTrackerPluginsNotToLoad()
+ {
+ return $this->trackerPluginsNotToLoad;
+ }
+
public function getCorePluginsDisabledByDefault()
{
return array_merge( $this->corePluginsDisabledByDefault, $this->coreThemesDisabledByDefault);
@@ -177,10 +201,11 @@ class Manager extends Singleton
/**
* Update Plugins config
*
- * @param array $plugins Plugins
+ * @param array $pluginsToLoad Plugins
*/
private function updatePluginsConfig($pluginsToLoad)
{
+ $pluginsToLoad = $this->sortPluginsSameOrderAsGlobalConfig($pluginsToLoad);
$section = PiwikConfig::getInstance()->Plugins;
$section['Plugins'] = $pluginsToLoad;
PiwikConfig::getInstance()->Plugins = $section;
@@ -237,7 +262,7 @@ class Manager extends Singleton
public function isPluginActivated($name)
{
return in_array($name, $this->pluginsToLoad)
- || $this->isPluginAlwaysActivated($name);
+ || ($this->doLoadAlwaysActivatedPlugins && $this->isPluginAlwaysActivated($name));
}
/**
@@ -403,7 +428,7 @@ class Manager extends Singleton
*/
public function installLoadedPlugins()
{
- Log::verbose("Loaded plugins: " . implode(", ", array_keys($this->getLoadedPlugins())));
+ Log::debug("Loaded plugins: " . implode(", ", array_keys($this->getLoadedPlugins())));
$messages = array();
foreach ($this->getLoadedPlugins() as $plugin) {
try {
@@ -543,7 +568,8 @@ class Manager extends Singleton
*/
public function loadAllPluginsAndGetTheirInfo()
{
- $language = Translate::getLanguageToLoad();
+ /** @var Translator $translator */
+ $translator = StaticContainer::get('Piwik\Translation\Translator');
$plugins = array();
@@ -567,7 +593,7 @@ class Manager extends Singleton
'uninstallable' => true,
);
} else {
- $this->loadTranslation($pluginName, $language);
+ $translator->addDirectory(self::getPluginsDirectory() . $pluginName . '/lang');
$this->loadPlugin($pluginName);
$info = array(
'activated' => $this->isPluginActivated($pluginName),
@@ -578,7 +604,6 @@ class Manager extends Singleton
$plugins[$pluginName] = $info;
}
- $this->loadPluginTranslations();
$loadedPlugins = $this->getLoadedPlugins();
foreach ($loadedPlugins as $oPlugin) {
@@ -610,12 +635,7 @@ class Manager extends Singleton
*/
public function isPluginBundledWithCore($name)
{
- // Reading the plugins from the global.ini.php config file
- $pluginsBundledWithPiwik = PiwikConfig::getInstance()->getFromGlobalConfig('Plugins');
- $pluginsBundledWithPiwik = $pluginsBundledWithPiwik['Plugins'];
-
- return (!empty($pluginsBundledWithPiwik)
- && in_array($name, $pluginsBundledWithPiwik))
+ return $this->isPluginEnabledByDefault($name)
|| in_array($name, $this->getCorePluginsDisabledByDefault())
|| $name == self::DEFAULT_THEME;
}
@@ -644,8 +664,7 @@ class Manager extends Singleton
*/
public function loadPlugins(array $pluginsToLoad)
{
- $pluginsToLoad = array_unique($pluginsToLoad);
- $this->pluginsToLoad = $pluginsToLoad;
+ $this->pluginsToLoad = $this->makePluginsToLoad($pluginsToLoad);
$this->reloadActivatedPlugins();
}
@@ -666,57 +685,6 @@ class Manager extends Singleton
}
/**
- * Load translations for loaded plugins
- *
- * @param bool|string $language Optional language code
- */
- public function loadPluginTranslations($language = false)
- {
- if (empty($language)) {
- $language = Translate::getLanguageToLoad();
- }
-
- $cache = new CacheFile('tracker', 43200); // ttl=12hours
- $cacheKey = 'PluginTranslations';
-
- if (!empty($language)) {
- $cacheKey .= '-' . trim($language);
- }
-
- if (!empty($this->loadedPlugins)) {
- // makes sure to create a translation in case loaded plugins change (ie Tests vs Tracker vs UI etc)
- $cacheKey .= '-' . md5(implode('', $this->getLoadedPluginsName()));
- }
-
- $translations = $cache->get($cacheKey);
-
- if (!empty($translations) &&
- is_array($translations) &&
- !Development::isEnabled()) {
-
- Translate::mergeTranslationArray($translations);
- return;
- }
-
- $translations = array();
- $pluginNames = self::getAllPluginsNames();
-
- foreach ($pluginNames as $pluginName) {
- if ($this->isPluginLoaded($pluginName) ||
- $this->isPluginBundledWithCore($pluginName)) {
-
- $this->loadTranslation($pluginName, $language);
-
- if (isset($GLOBALS['Piwik_translations'][$pluginName])) {
- $translations[$pluginName] = $GLOBALS['Piwik_translations'][$pluginName];
- }
- }
- }
-
- $cache->set($cacheKey, $translations);
- }
-
- /**
* Execute postLoad() hook for loaded plugins
*/
public function postLoadPlugins()
@@ -742,7 +710,7 @@ class Manager extends Singleton
*
* array(
* 'UserCountry' => Plugin $pluginObject,
- * 'UserSettings' => Plugin $pluginObject,
+ * 'UserLanguage' => Plugin $pluginObject,
* );
*
* @return Plugin[]
@@ -776,7 +744,7 @@ class Manager extends Singleton
*
* array(
* 'UserCountry' => Plugin $pluginObject,
- * 'UserSettings' => Plugin $pluginObject,
+ * 'UserLanguage' => Plugin $pluginObject,
* );
*
* @return Plugin[]
@@ -799,7 +767,7 @@ class Manager extends Singleton
*
* array(
* 'UserCountry'
- * 'UserSettings'
+ * 'UserLanguage'
* );
*
* @return string[]
@@ -809,6 +777,13 @@ class Manager extends Singleton
return $this->pluginsToLoad;
}
+ public function getActivatedPluginsFromConfig()
+ {
+ $plugins = @Config::getInstance()->Plugins['Plugins'];
+
+ return $this->makePluginsToLoad($plugins);
+ }
+
/**
* Returns a Plugin object by name.
*
@@ -830,12 +805,6 @@ class Manager extends Singleton
*/
private function reloadActivatedPlugins()
{
- if ($this->doLoadAlwaysActivatedPlugins) {
- $this->pluginsToLoad = array_merge($this->pluginsToLoad, $this->pluginToAlwaysActivate);
- }
-
- $this->pluginsToLoad = array_unique($this->pluginsToLoad);
-
$pluginsToPostPendingEventsTo = array();
foreach ($this->pluginsToLoad as $pluginName) {
if (!$this->isPluginLoaded($pluginName)
@@ -1005,67 +974,14 @@ class Manager extends Singleton
*
* @param string $pluginName plugin name without prefix (eg. 'UserCountry')
* @param Plugin $newPlugin
+ * @internal
*/
- private function addLoadedPlugin($pluginName, Plugin $newPlugin)
+ public function addLoadedPlugin($pluginName, Plugin $newPlugin)
{
$this->loadedPlugins[$pluginName] = $newPlugin;
}
/**
- * Load translation
- *
- * @param Plugin $plugin
- * @param string $langCode
- * @throws \Exception
- * @return bool whether the translation was found and loaded
- */
- private function loadTranslation($plugin, $langCode)
- {
- // we are in Tracker mode if Loader is not (yet) loaded
- if (SettingsServer::isTrackerApiRequest()) {
- return false;
- }
-
- if (is_string($plugin)) {
- $pluginName = $plugin;
- } else {
- $pluginName = $plugin->getPluginName();
- }
-
- $path = self::getPluginsDirectory() . $pluginName . '/lang/%s.json';
-
- $defaultLangPath = sprintf($path, $langCode);
- $defaultEnglishLangPath = sprintf($path, 'en');
-
- $translationsLoaded = false;
-
- // merge in english translations as default first
- if (file_exists($defaultEnglishLangPath)) {
- $translations = $this->getTranslationsFromFile($defaultEnglishLangPath);
- $translationsLoaded = true;
- if (isset($translations[$pluginName])) {
- // only merge translations of plugin - prevents overwritten strings
- Translate::mergeTranslationArray(array($pluginName => $translations[$pluginName]));
- }
- }
-
- // merge in specific language translations (to overwrite english defaults)
- if (!empty($langCode) &&
- $defaultEnglishLangPath != $defaultLangPath &&
- file_exists($defaultLangPath)) {
-
- $translations = $this->getTranslationsFromFile($defaultLangPath);
- $translationsLoaded = true;
- if (isset($translations[$pluginName])) {
- // only merge translations of plugin - prevents overwritten strings
- Translate::mergeTranslationArray(array($pluginName => $translations[$pluginName]));
- }
- }
-
- return $translationsLoaded;
- }
-
- /**
* Return names of all installed plugins.
*
* @return array
@@ -1193,27 +1109,6 @@ class Manager extends Singleton
}
/**
- * @param string $pathToTranslationFile
- * @throws \Exception
- * @return mixed
- */
- private function getTranslationsFromFile($pathToTranslationFile)
- {
- $data = file_get_contents($pathToTranslationFile);
- $translations = json_decode($data, true);
-
- if (is_null($translations) && Common::hasJsonErrorOccurred()) {
- $jsonError = Common::getLastJsonError();
-
- $message = sprintf('Not able to load translation file %s: %s', $pathToTranslationFile, $jsonError);
-
- throw new \Exception($message);
- }
-
- return $translations;
- }
-
- /**
* @param $pluginName
* @return bool
*/
@@ -1335,18 +1230,84 @@ class Manager extends Singleton
{
Option::delete('version_' . $version);
}
-}
-/**
- */
-class PluginException extends \Exception
-{
- function __construct($pluginName, $message)
+ private function makeSureOnlyActivatedPluginsAreLoaded()
+ {
+ foreach ($this->getLoadedPlugins() as $pluginName => $plugin) {
+ if (!in_array($pluginName, $this->pluginsToLoad)) {
+ $this->unloadPlugin($plugin);
+ }
+ }
+ }
+
+ /**
+ * Reading the plugins from the global.ini.php config file
+ *
+ * @return array
+ */
+ protected function getPluginsFromGlobalIniConfigFile()
+ {
+ $pluginsBundledWithPiwik = PiwikConfig::getInstance()->getFromGlobalConfig('Plugins');
+ $pluginsBundledWithPiwik = $pluginsBundledWithPiwik['Plugins'];
+ return $pluginsBundledWithPiwik;
+ }
+
+ /**
+ * @param $name
+ * @return bool
+ */
+ protected function isPluginEnabledByDefault($name)
+ {
+ $pluginsBundledWithPiwik = $this->getPluginsFromGlobalIniConfigFile();
+
+ if(empty($pluginsBundledWithPiwik)) {
+ return false;
+ }
+ return in_array($name, $pluginsBundledWithPiwik);
+ }
+
+ /**
+ * @param array $pluginsToLoad
+ * @return array
+ */
+ private function makePluginsToLoad(array $pluginsToLoad)
{
- parent::__construct("There was a problem installing the plugin " . $pluginName . ": " . $message . "
- If this plugin has already been installed, and if you want to hide this message</b>, you must add the following line under the
- [PluginsInstalled]
- entry in your config/config.ini.php file:
- PluginsInstalled[] = $pluginName");
+ $pluginsToLoad = array_unique($pluginsToLoad);
+ if ($this->doLoadAlwaysActivatedPlugins) {
+ $pluginsToLoad = array_merge($pluginsToLoad, $this->pluginToAlwaysActivate);
+ }
+ $pluginsToLoad = array_unique($pluginsToLoad);
+ $pluginsToLoad = $this->sortPluginsSameOrderAsGlobalConfig($pluginsToLoad);
+ return $pluginsToLoad;
+ }
+
+ private function sortPluginsSameOrderAsGlobalConfig(array $plugins)
+ {
+ $global = $this->getPluginsFromGlobalIniConfigFile();
+ if(empty($global)) {
+ return $plugins;
+ }
+ $global = array_values($global);
+ $plugins = array_values($plugins);
+
+ $defaultPluginsLoadedFirst = array_intersect($global, $plugins);
+
+ $otherPluginsToLoadAfterDefaultPlugins = array_diff($plugins, $defaultPluginsLoadedFirst);
+
+ // sort by name to have a predictable order for those extra plugins
+ sort($otherPluginsToLoadAfterDefaultPlugins);
+
+ $sorted = array_merge($defaultPluginsLoadedFirst, $otherPluginsToLoadAfterDefaultPlugins);
+
+ return $sorted;
+ }
+
+ public function loadPluginTranslations()
+ {
+ /** @var Translator $translator */
+ $translator = StaticContainer::get('Piwik\Translation\Translator');
+ foreach ($this->getAllPluginsNames() as $pluginName) {
+ $translator->addDirectory(self::getPluginsDirectory() . $pluginName . '/lang');
+ }
}
}