PDF rausgenommen
This commit is contained in:
246
msd2/tracking/piwik/core/Application/Environment.php
Normal file
246
msd2/tracking/piwik/core/Application/Environment.php
Normal file
@ -0,0 +1,246 @@
|
||||
<?php
|
||||
/**
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace Piwik\Application;
|
||||
|
||||
use DI\Container;
|
||||
use Piwik\Application\Kernel\EnvironmentValidator;
|
||||
use Piwik\Application\Kernel\GlobalSettingsProvider;
|
||||
use Piwik\Application\Kernel\PluginList;
|
||||
use Piwik\Container\ContainerFactory;
|
||||
use Piwik\Container\StaticContainer;
|
||||
use Piwik\Piwik;
|
||||
|
||||
/**
|
||||
* Encapsulates Piwik environment setup and access.
|
||||
*
|
||||
* The Piwik environment consists of two main parts: the kernel and the DI container.
|
||||
*
|
||||
* The 'kernel' is the core part of Piwik that cannot be modified / extended through the DI container.
|
||||
* It includes components that are required to create the DI container.
|
||||
*
|
||||
* Currently the only objects in the 'kernel' are a GlobalSettingsProvider object and a
|
||||
* PluginList object. The GlobalSettingsProvider object is required for the current PluginList
|
||||
* implementation and for checking whether Development mode is enabled. The PluginList is
|
||||
* needed in order to determine what plugins are activated, since plugins can provide their
|
||||
* own DI configuration.
|
||||
*
|
||||
* The DI container contains every other Piwik object, including the Plugin\Manager,
|
||||
* plugin API instances, dependent services, etc. Plugins and users can override/extend
|
||||
* the objects in this container.
|
||||
*
|
||||
* NOTE: DI support in Piwik is currently a work in process; not everything is currently
|
||||
* stored in the DI container, but we are working towards this.
|
||||
*/
|
||||
class Environment
|
||||
{
|
||||
/**
|
||||
* @internal
|
||||
* @var EnvironmentManipulator
|
||||
*/
|
||||
private static $globalEnvironmentManipulator = null;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $environment;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $definitions;
|
||||
|
||||
/**
|
||||
* @var Container
|
||||
*/
|
||||
private $container;
|
||||
|
||||
/**
|
||||
* @var GlobalSettingsProvider
|
||||
*/
|
||||
private $globalSettingsProvider;
|
||||
|
||||
/**
|
||||
* @var PluginList
|
||||
*/
|
||||
private $pluginList;
|
||||
|
||||
/**
|
||||
* @param string $environment
|
||||
* @param array $definitions
|
||||
*/
|
||||
public function __construct($environment, array $definitions = array())
|
||||
{
|
||||
$this->environment = $environment;
|
||||
$this->definitions = $definitions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the kernel globals and DI container.
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
$this->invokeBeforeContainerCreatedHook();
|
||||
|
||||
$this->container = $this->createContainer();
|
||||
|
||||
StaticContainer::push($this->container);
|
||||
|
||||
$this->validateEnvironment();
|
||||
|
||||
$this->invokeEnvironmentBootstrappedHook();
|
||||
|
||||
Piwik::postEvent('Environment.bootstrapped'); // this event should be removed eventually
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys an environment. MUST be called when embedding environments.
|
||||
*/
|
||||
public function destroy()
|
||||
{
|
||||
StaticContainer::pop();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the DI container. All Piwik objects for a specific Piwik instance should be stored
|
||||
* in this container.
|
||||
*
|
||||
* @return Container
|
||||
*/
|
||||
public function getContainer()
|
||||
{
|
||||
return $this->container;
|
||||
}
|
||||
|
||||
/**
|
||||
* @link http://php-di.org/doc/container-configuration.html
|
||||
*/
|
||||
private function createContainer()
|
||||
{
|
||||
$pluginList = $this->getPluginListCached();
|
||||
$settings = $this->getGlobalSettingsCached();
|
||||
|
||||
$extraDefinitions = $this->getExtraDefinitionsFromManipulators();
|
||||
$definitions = array_merge(StaticContainer::getDefinitions(), $extraDefinitions, array($this->definitions));
|
||||
|
||||
$environments = array($this->environment);
|
||||
$environments = array_merge($environments, $this->getExtraEnvironmentsFromManipulators());
|
||||
|
||||
$containerFactory = new ContainerFactory($pluginList, $settings, $environments, $definitions);
|
||||
return $containerFactory->create();
|
||||
}
|
||||
|
||||
protected function getGlobalSettingsCached()
|
||||
{
|
||||
if ($this->globalSettingsProvider === null) {
|
||||
$original = $this->getGlobalSettings();
|
||||
$globalSettingsProvider = $this->getGlobalSettingsProviderOverride($original);
|
||||
|
||||
$this->globalSettingsProvider = $globalSettingsProvider ?: $original;
|
||||
}
|
||||
return $this->globalSettingsProvider;
|
||||
}
|
||||
|
||||
protected function getPluginListCached()
|
||||
{
|
||||
if ($this->pluginList === null) {
|
||||
$pluginList = $this->getPluginListOverride();
|
||||
$this->pluginList = $pluginList ?: $this->getPluginList();
|
||||
}
|
||||
return $this->pluginList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the kernel global GlobalSettingsProvider object. Derived classes can override this method
|
||||
* to provide a different implementation.
|
||||
*
|
||||
* @return null|GlobalSettingsProvider
|
||||
*/
|
||||
protected function getGlobalSettings()
|
||||
{
|
||||
return new GlobalSettingsProvider();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the kernel global PluginList object. Derived classes can override this method to
|
||||
* provide a different implementation.
|
||||
*
|
||||
* @return PluginList
|
||||
*/
|
||||
protected function getPluginList()
|
||||
{
|
||||
// TODO: in tracker should only load tracker plugins. can't do properly until tracker entrypoint is encapsulated.
|
||||
return new PluginList($this->getGlobalSettingsCached());
|
||||
}
|
||||
|
||||
private function validateEnvironment()
|
||||
{
|
||||
/** @var EnvironmentValidator $validator */
|
||||
$validator = $this->container->get('Piwik\Application\Kernel\EnvironmentValidator');
|
||||
$validator->validate();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param EnvironmentManipulator $manipulator
|
||||
* @internal
|
||||
*/
|
||||
public static function setGlobalEnvironmentManipulator(EnvironmentManipulator $manipulator)
|
||||
{
|
||||
self::$globalEnvironmentManipulator = $manipulator;
|
||||
}
|
||||
|
||||
private function getGlobalSettingsProviderOverride(GlobalSettingsProvider $original)
|
||||
{
|
||||
if (self::$globalEnvironmentManipulator) {
|
||||
return self::$globalEnvironmentManipulator->makeGlobalSettingsProvider($original);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private function invokeBeforeContainerCreatedHook()
|
||||
{
|
||||
if (self::$globalEnvironmentManipulator) {
|
||||
return self::$globalEnvironmentManipulator->beforeContainerCreated();
|
||||
}
|
||||
}
|
||||
|
||||
private function getExtraDefinitionsFromManipulators()
|
||||
{
|
||||
if (self::$globalEnvironmentManipulator) {
|
||||
return self::$globalEnvironmentManipulator->getExtraDefinitions();
|
||||
} else {
|
||||
return array();
|
||||
}
|
||||
}
|
||||
|
||||
private function invokeEnvironmentBootstrappedHook()
|
||||
{
|
||||
if (self::$globalEnvironmentManipulator) {
|
||||
self::$globalEnvironmentManipulator->onEnvironmentBootstrapped();
|
||||
}
|
||||
}
|
||||
|
||||
private function getExtraEnvironmentsFromManipulators()
|
||||
{
|
||||
if (self::$globalEnvironmentManipulator) {
|
||||
return self::$globalEnvironmentManipulator->getExtraEnvironments();
|
||||
} else {
|
||||
return array();
|
||||
}
|
||||
}
|
||||
|
||||
private function getPluginListOverride()
|
||||
{
|
||||
if (self::$globalEnvironmentManipulator) {
|
||||
return self::$globalEnvironmentManipulator->makePluginList($this->getGlobalSettingsCached());
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
<?php
|
||||
/**
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace Piwik\Application;
|
||||
|
||||
use Piwik\Application\Kernel\GlobalSettingsProvider;
|
||||
use Piwik\Application\Kernel\PluginList;
|
||||
|
||||
/**
|
||||
* Used to manipulate Environment instances before the container is created.
|
||||
* Only used by the testing environment setup code, shouldn't be used anywhere
|
||||
* else.
|
||||
*/
|
||||
interface EnvironmentManipulator
|
||||
{
|
||||
/**
|
||||
* Create a custom GlobalSettingsProvider kernel object, overriding the default behavior.
|
||||
*
|
||||
* @return GlobalSettingsProvider
|
||||
*/
|
||||
public function makeGlobalSettingsProvider(GlobalSettingsProvider $original);
|
||||
|
||||
/**
|
||||
* Create a custom PluginList kernel object, overriding the default behavior.@deprecated
|
||||
*
|
||||
* @param GlobalSettingsProvider $globalSettingsProvider
|
||||
* @return PluginList
|
||||
*/
|
||||
public function makePluginList(GlobalSettingsProvider $globalSettingsProvider);
|
||||
|
||||
/**
|
||||
* Invoked before the container is created.
|
||||
*/
|
||||
public function beforeContainerCreated();
|
||||
|
||||
/**
|
||||
* Return an array of definition arrays that override DI config specified in PHP config files.
|
||||
*
|
||||
* @return array[]
|
||||
*/
|
||||
public function getExtraDefinitions();
|
||||
|
||||
/**
|
||||
* Invoked after the container is created and the environment is considered bootstrapped.
|
||||
*/
|
||||
public function onEnvironmentBootstrapped();
|
||||
|
||||
/**
|
||||
* Return an array of environment names to apply after the normal environment.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function getExtraEnvironments();
|
||||
}
|
@ -0,0 +1,143 @@
|
||||
<?php
|
||||
/**
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace Piwik\Application\Kernel;
|
||||
|
||||
use Piwik\Common;
|
||||
use Piwik\Exception\NotYetInstalledException;
|
||||
use Piwik\Filechecks;
|
||||
use Piwik\Piwik;
|
||||
use Piwik\SettingsPiwik;
|
||||
use Piwik\SettingsServer;
|
||||
use Piwik\Translation\Translator;
|
||||
|
||||
/**
|
||||
* Validates the Piwik environment. This includes making sure the required config files
|
||||
* are present, and triggering the correct behaviour if otherwise.
|
||||
*/
|
||||
class EnvironmentValidator
|
||||
{
|
||||
/**
|
||||
* @var GlobalSettingsProvider
|
||||
*/
|
||||
protected $settingsProvider;
|
||||
|
||||
/**
|
||||
* @var Translator
|
||||
*/
|
||||
protected $translator;
|
||||
|
||||
public function __construct(GlobalSettingsProvider $settingsProvider, Translator $translator)
|
||||
{
|
||||
$this->settingsProvider = $settingsProvider;
|
||||
$this->translator = $translator;
|
||||
}
|
||||
|
||||
public function validate()
|
||||
{
|
||||
$this->checkConfigFileExists($this->settingsProvider->getPathGlobal());
|
||||
|
||||
if(SettingsPiwik::isPiwikInstalled()) {
|
||||
$this->checkConfigFileExists($this->settingsProvider->getPathLocal(), $startInstaller = false);
|
||||
return;
|
||||
}
|
||||
|
||||
$startInstaller = true;
|
||||
|
||||
if(SettingsServer::isTrackerApiRequest()) {
|
||||
// if Piwik is not installed yet, the piwik.php should do nothing and not return an error
|
||||
throw new NotYetInstalledException("As Matomo is not installed yet, the Tracking API cannot proceed and will exit without error.");
|
||||
}
|
||||
|
||||
if(Common::isPhpCliMode()) {
|
||||
// in CLI, do not start/redirect to installer, simply output the exception at the top
|
||||
$startInstaller = false;
|
||||
}
|
||||
|
||||
// Start the installation when config file not found
|
||||
$this->checkConfigFileExists($this->settingsProvider->getPathLocal(), $startInstaller);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $path
|
||||
* @param bool $startInstaller
|
||||
* @throws \Exception
|
||||
*/
|
||||
private function checkConfigFileExists($path, $startInstaller = false)
|
||||
{
|
||||
if (is_readable($path)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$message = $this->getSpecificMessageWhetherFileExistsOrNot($path);
|
||||
|
||||
$exception = new NotYetInstalledException($message);
|
||||
|
||||
if ($startInstaller) {
|
||||
$this->startInstallation($exception);
|
||||
} else {
|
||||
throw $exception;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $exception
|
||||
*/
|
||||
private function startInstallation($exception)
|
||||
{
|
||||
/**
|
||||
* Triggered when the configuration file cannot be found or read, which usually
|
||||
* means Piwik is not installed yet.
|
||||
*
|
||||
* This event can be used to start the installation process or to display a custom error message.
|
||||
*
|
||||
* @param \Exception $exception The exception that was thrown by `Config::getInstance()`.
|
||||
*/
|
||||
Piwik::postEvent('Config.NoConfigurationFile', array($exception), $pending = true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $path
|
||||
* @return string
|
||||
*/
|
||||
private function getMessageWhenFileExistsButNotReadable($path)
|
||||
{
|
||||
$format = " \n<b>» %s </b>";
|
||||
if(Common::isPhpCliMode()) {
|
||||
$format = "\n » %s \n";
|
||||
}
|
||||
|
||||
return sprintf($format,
|
||||
$this->translator->translate('General_ExceptionConfigurationFilePleaseCheckReadableByUser',
|
||||
array($path, Filechecks::getUser())));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $path
|
||||
* @return string
|
||||
*/
|
||||
private function getSpecificMessageWhetherFileExistsOrNot($path)
|
||||
{
|
||||
if (!file_exists($path)) {
|
||||
$message = $this->translator->translate('General_ExceptionConfigurationFileNotFound', array($path));
|
||||
if (Common::isPhpCliMode()) {
|
||||
$message .= $this->getMessageWhenFileExistsButNotReadable($path);
|
||||
}
|
||||
} else {
|
||||
$message = $this->translator->translate('General_ExceptionConfigurationFileExistsButNotReadable',
|
||||
array($path));
|
||||
$message .= $this->getMessageWhenFileExistsButNotReadable($path);
|
||||
}
|
||||
|
||||
if (Common::isPhpCliMode()) {
|
||||
$message = "\n" . $message;
|
||||
}
|
||||
return $message;
|
||||
}
|
||||
}
|
@ -0,0 +1,111 @@
|
||||
<?php
|
||||
/**
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace Piwik\Application\Kernel;
|
||||
|
||||
use Piwik\Config;
|
||||
use Piwik\Config\IniFileChain;
|
||||
|
||||
/**
|
||||
* Provides global settings. Global settings are organized in sections where
|
||||
* each section contains a list of name => value pairs. Setting values can
|
||||
* be primitive values or arrays of primitive values.
|
||||
*
|
||||
* Uses the config.ini.php, common.ini.php and global.ini.php files to provide global settings.
|
||||
*
|
||||
* At the moment a singleton instance of this class is used in order to get tests to pass.
|
||||
*/
|
||||
class GlobalSettingsProvider
|
||||
{
|
||||
/**
|
||||
* @var IniFileChain
|
||||
*/
|
||||
protected $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)
|
||||
{
|
||||
$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->reload(array($this->pathGlobal, $this->pathCommon), $this->pathLocal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a settings section.
|
||||
*
|
||||
* @param string $name
|
||||
* @return array
|
||||
*/
|
||||
public function &getSection($name)
|
||||
{
|
||||
$section =& $this->iniFileChain->get($name);
|
||||
return $section;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a settings section.
|
||||
*
|
||||
* @param string $name
|
||||
* @param array $value
|
||||
*/
|
||||
public function setSection($name, $value)
|
||||
{
|
||||
$this->iniFileChain->set($name, $value);
|
||||
}
|
||||
|
||||
public function getIniFileChain()
|
||||
{
|
||||
return $this->iniFileChain;
|
||||
}
|
||||
|
||||
public function getPathGlobal()
|
||||
{
|
||||
return $this->pathGlobal;
|
||||
}
|
||||
|
||||
public function getPathLocal()
|
||||
{
|
||||
return $this->pathLocal;
|
||||
}
|
||||
|
||||
public function getPathCommon()
|
||||
{
|
||||
return $this->pathCommon;
|
||||
}
|
||||
}
|
193
msd2/tracking/piwik/core/Application/Kernel/PluginList.php
Normal file
193
msd2/tracking/piwik/core/Application/Kernel/PluginList.php
Normal file
@ -0,0 +1,193 @@
|
||||
<?php
|
||||
/**
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace Piwik\Application\Kernel;
|
||||
|
||||
use Piwik\Plugin\MetadataLoader;
|
||||
|
||||
/**
|
||||
* Lists the currently activated plugins. Used when setting up Piwik's environment before
|
||||
* initializing the DI container.
|
||||
*
|
||||
* Uses the [Plugins] section in Piwik's INI config to get the activated plugins.
|
||||
*
|
||||
* Depends on GlobalSettingsProvider being used.
|
||||
*
|
||||
* TODO: parts of Plugin\Manager edit the plugin list; maybe PluginList implementations should be mutable?
|
||||
*/
|
||||
class PluginList
|
||||
{
|
||||
/**
|
||||
* @var GlobalSettingsProvider
|
||||
*/
|
||||
private $settings;
|
||||
|
||||
/**
|
||||
* Plugins bundled with core package, disabled by default
|
||||
* @var array
|
||||
*/
|
||||
private $corePluginsDisabledByDefault = array(
|
||||
'DBStats',
|
||||
'ExampleCommand',
|
||||
'ExampleSettingsPlugin',
|
||||
'ExampleUI',
|
||||
'ExampleVisualization',
|
||||
'ExamplePluginTemplate',
|
||||
'ExampleTracker',
|
||||
'ExampleLogTables',
|
||||
'ExampleReport',
|
||||
'MobileAppMeasurable',
|
||||
'Provider',
|
||||
'TagManager'
|
||||
);
|
||||
|
||||
// Themes bundled with core package, disabled by default
|
||||
private $coreThemesDisabledByDefault = array(
|
||||
'ExampleTheme'
|
||||
);
|
||||
|
||||
public function __construct(GlobalSettingsProvider $settings)
|
||||
{
|
||||
$this->settings = $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of plugins that should be loaded. Used by the container factory to
|
||||
* load plugin specific DI overrides.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function getActivatedPlugins()
|
||||
{
|
||||
$section = $this->settings->getSection('Plugins');
|
||||
return @$section['Plugins'] ?: array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of plugins that are bundled with Piwik.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function getPluginsBundledWithPiwik()
|
||||
{
|
||||
$pathGlobal = $this->settings->getPathGlobal();
|
||||
|
||||
$section = $this->settings->getIniFileChain()->getFrom($pathGlobal, 'Plugins');
|
||||
return $section['Plugins'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the plugins bundled with core package that are disabled by default.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function getCorePluginsDisabledByDefault()
|
||||
{
|
||||
return array_merge($this->corePluginsDisabledByDefault, $this->coreThemesDisabledByDefault);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array of plugins in the order they should be loaded. We cannot use DI here as DI is not initialized
|
||||
* at this stage.
|
||||
*
|
||||
* @params string[] $plugins
|
||||
* @return \string[]
|
||||
*/
|
||||
public function sortPlugins(array $plugins)
|
||||
{
|
||||
$global = $this->getPluginsBundledWithPiwik();
|
||||
if (empty($global)) {
|
||||
return $plugins;
|
||||
}
|
||||
|
||||
// we need to make sure a possibly disabled plugin will be still loaded before any 3rd party plugin
|
||||
$global = array_merge($global, $this->corePluginsDisabledByDefault);
|
||||
|
||||
$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
|
||||
natcasesort($otherPluginsToLoadAfterDefaultPlugins);
|
||||
|
||||
$sorted = array_merge($defaultPluginsLoadedFirst, $otherPluginsToLoadAfterDefaultPlugins);
|
||||
|
||||
return $sorted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array of plugins in the order they should be saved in config.ini.php. This basically influences
|
||||
* the order of the plugin config.php and which config will be loaded first. We want to make sure to require the
|
||||
* config or a required plugin first before loading the plugin that requires it.
|
||||
*
|
||||
* We do not sort using this logic on each request since it is much slower than `sortPlugins()`. The order
|
||||
* of plugins in config.ini.php is only important for the ContainerFactory. During a regular request it is otherwise
|
||||
* fine to load the plugins in the order of `sortPlugins()` since we will make sure that required plugins will be
|
||||
* loaded first in plugin manager.
|
||||
*
|
||||
* @param string[] $plugins
|
||||
* @param array[] $pluginJsonCache For internal testing only
|
||||
* @return \string[]
|
||||
*/
|
||||
public function sortPluginsAndRespectDependencies(array $plugins, $pluginJsonCache = array())
|
||||
{
|
||||
$global = $this->getPluginsBundledWithPiwik();
|
||||
|
||||
if (empty($global)) {
|
||||
return $plugins;
|
||||
}
|
||||
|
||||
// we need to make sure a possibly disabled plugin will be still loaded before any 3rd party plugin
|
||||
$global = array_merge($global, $this->corePluginsDisabledByDefault);
|
||||
|
||||
$global = array_values($global);
|
||||
$plugins = array_values($plugins);
|
||||
|
||||
$defaultPluginsLoadedFirst = array_intersect($global, $plugins);
|
||||
|
||||
$otherPluginsToLoadAfterDefaultPlugins = array_diff($plugins, $defaultPluginsLoadedFirst);
|
||||
|
||||
// we still want to sort alphabetically by default
|
||||
natcasesort($otherPluginsToLoadAfterDefaultPlugins);
|
||||
|
||||
$sorted = array();
|
||||
foreach ($otherPluginsToLoadAfterDefaultPlugins as $pluginName) {
|
||||
$sorted = $this->sortRequiredPlugin($pluginName, $pluginJsonCache, $otherPluginsToLoadAfterDefaultPlugins, $sorted);
|
||||
}
|
||||
|
||||
$sorted = array_merge($defaultPluginsLoadedFirst, $sorted);
|
||||
|
||||
return $sorted;
|
||||
}
|
||||
|
||||
private function sortRequiredPlugin($pluginName, &$pluginJsonCache, $toBeSorted, $sorted)
|
||||
{
|
||||
if (!isset($pluginJsonCache[$pluginName])) {
|
||||
$loader = new MetadataLoader($pluginName);
|
||||
$pluginJsonCache[$pluginName] = $loader->loadPluginInfoJson();
|
||||
}
|
||||
|
||||
if (!empty($pluginJsonCache[$pluginName]['require'])) {
|
||||
$dependencies = $pluginJsonCache[$pluginName]['require'];
|
||||
foreach ($dependencies as $possiblePluginName => $key) {
|
||||
if (in_array($possiblePluginName, $toBeSorted, true) && !in_array($possiblePluginName, $sorted, true)) {
|
||||
$sorted = $this->sortRequiredPlugin($possiblePluginName, $pluginJsonCache, $toBeSorted, $sorted);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!in_array($pluginName, $sorted, true)) {
|
||||
$sorted[] = $pluginName;
|
||||
}
|
||||
|
||||
return $sorted;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user