PluginProbe ʕ •ᴥ•ʔ
Matomo Analytics – Powerful, Privacy-First Insights for WordPress / trunk
Matomo Analytics – Powerful, Privacy-First Insights for WordPress vtrunk
5.11.1 5.11.0 5.10.2 5.10.1 trunk 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.1.0 1.1.1 1.1.2 1.1.3 1.2.0 1.3.0 1.3.1 1.3.2 4.0.0 4.0.1 4.0.2 4.0.3 4.0.4 4.1.0 4.1.1 4.1.2 4.1.3 4.10.0 4.11.0 4.12.0 4.13.0 4.13.2 4.13.3 4.13.4 4.13.5 4.14.0 4.14.1 4.14.2 4.15.0 4.15.1 4.15.2 4.15.3 4.2.0 4.3.0 4.3.1 4.4.1 4.4.2 4.5.0 4.6.0 5.0.1 5.0.2 5.0.3 5.0.4 5.0.5 5.0.6 5.0.7 5.0.8 5.1.0 5.1.1 5.1.2 5.1.3 5.1.4 5.1.5 5.1.6 5.1.7 5.10.0 5.2.0 5.2.1 5.2.2 5.3.0 5.3.1 5.3.2 5.3.3 5.6.0 5.6.1 5.7.0 5.7.1 5.8.0 5.8.1 5.8.2
matomo / app / core / Application / Kernel / PluginList.php
matomo / app / core / Application / Kernel Last commit date
EnvironmentValidator.php 1 year ago GlobalSettingsProvider.php 2 years ago PluginList.php 1 month ago
PluginList.php
150 lines
1 <?php
2
3 /**
4 * Matomo - free/libre analytics platform
5 *
6 * @link https://matomo.org
7 * @license https://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
8 */
9 namespace Piwik\Application\Kernel;
10
11 use Piwik\Plugin\MetadataLoader;
12 /**
13 * Lists the currently activated plugins. Used when setting up Piwik's environment before
14 * initializing the DI container.
15 *
16 * Uses the [Plugins] section in Piwik's INI config to get the activated plugins.
17 *
18 * Depends on GlobalSettingsProvider being used.
19 *
20 * TODO: parts of Plugin\Manager edit the plugin list; maybe PluginList implementations should be mutable?
21 */
22 class PluginList
23 {
24 /**
25 * @var GlobalSettingsProvider
26 */
27 private $settings;
28 /**
29 * Plugins bundled with core package, disabled by default
30 * @var array
31 */
32 private $corePluginsDisabledByDefault = array('ArchivingMetrics', 'DBStats', 'ExamplePlugin', 'ExampleCommand', 'ExampleSettingsPlugin', 'ExampleUI', 'ExampleVisualization', 'ExamplePluginTemplate', 'ExampleTracker', 'ExampleLogTables', 'ExampleReport', 'ExampleAPI', 'ExampleVue', 'MobileAppMeasurable', 'TagManager');
33 // Themes bundled with core package, disabled by default
34 private $coreThemesDisabledByDefault = array('ExampleTheme');
35 public function __construct(\Piwik\Application\Kernel\GlobalSettingsProvider $settings)
36 {
37 $this->settings = $settings;
38 }
39 /**
40 * Returns the list of plugins that should be loaded. Used by the container factory to
41 * load plugin specific DI overrides.
42 *
43 * @return string[]
44 */
45 public function getActivatedPlugins()
46 {
47 $section = $this->settings->getSection('Plugins');
48 $plugins = @$section['Plugins'] ?: array();
49 return $plugins;
50 }
51 /**
52 * Returns the list of plugins that are bundled with Piwik.
53 *
54 * @return string[]
55 */
56 public function getPluginsBundledWithPiwik()
57 {
58 $pathGlobal = $this->settings->getPathGlobal();
59 $section = $this->settings->getIniFileChain()->getFrom($pathGlobal, 'Plugins');
60 return $section['Plugins'];
61 }
62 /**
63 * Returns the plugins bundled with core package that are disabled by default.
64 *
65 * @return string[]
66 */
67 public function getCorePluginsDisabledByDefault()
68 {
69 return array_merge($this->corePluginsDisabledByDefault, $this->coreThemesDisabledByDefault);
70 }
71 /**
72 * Sorts an array of plugins in the order they should be loaded. We cannot use DI here as DI is not initialized
73 * at this stage.
74 *
75 * @params string[] $plugins
76 * @return list<string>
77 */
78 public function sortPlugins(array $plugins)
79 {
80 $global = $this->getPluginsBundledWithPiwik();
81 if (empty($global)) {
82 return $plugins;
83 }
84 // we need to make sure a possibly disabled plugin will be still loaded before any 3rd party plugin
85 $global = array_merge($global, $this->corePluginsDisabledByDefault);
86 $global = array_values($global);
87 $plugins = array_values($plugins);
88 $defaultPluginsLoadedFirst = array_intersect($global, $plugins);
89 $otherPluginsToLoadAfterDefaultPlugins = array_diff($plugins, $defaultPluginsLoadedFirst);
90 // sort by name to have a predictable order for those extra plugins
91 natcasesort($otherPluginsToLoadAfterDefaultPlugins);
92 $sorted = array_merge($defaultPluginsLoadedFirst, $otherPluginsToLoadAfterDefaultPlugins);
93 return $sorted;
94 }
95 /**
96 * Sorts an array of plugins in the order they should be saved in config.ini.php. This basically influences
97 * the order of the plugin config.php and which config will be loaded first. We want to make sure to require the
98 * config or a required plugin first before loading the plugin that requires it.
99 *
100 * We do not sort using this logic on each request since it is much slower than `sortPlugins()`. The order
101 * of plugins in config.ini.php is only important for the ContainerFactory. During a regular request it is otherwise
102 * fine to load the plugins in the order of `sortPlugins()` since we will make sure that required plugins will be
103 * loaded first in plugin manager.
104 *
105 * @param string[] $plugins
106 * @param array[] $pluginJsonCache For internal testing only
107 * @return \string[]
108 */
109 public function sortPluginsAndRespectDependencies(array $plugins, $pluginJsonCache = array())
110 {
111 $global = $this->getPluginsBundledWithPiwik();
112 if (empty($global)) {
113 return $plugins;
114 }
115 // we need to make sure a possibly disabled plugin will be still loaded before any 3rd party plugin
116 $global = array_merge($global, $this->corePluginsDisabledByDefault);
117 $global = array_values($global);
118 $plugins = array_values($plugins);
119 $defaultPluginsLoadedFirst = array_intersect($global, $plugins);
120 $otherPluginsToLoadAfterDefaultPlugins = array_diff($plugins, $defaultPluginsLoadedFirst);
121 // we still want to sort alphabetically by default
122 natcasesort($otherPluginsToLoadAfterDefaultPlugins);
123 $sorted = array();
124 foreach ($otherPluginsToLoadAfterDefaultPlugins as $pluginName) {
125 $sorted = $this->sortRequiredPlugin($pluginName, $pluginJsonCache, $otherPluginsToLoadAfterDefaultPlugins, $sorted);
126 }
127 $sorted = array_merge($defaultPluginsLoadedFirst, $sorted);
128 return $sorted;
129 }
130 private function sortRequiredPlugin($pluginName, &$pluginJsonCache, $toBeSorted, $sorted)
131 {
132 if (!isset($pluginJsonCache[$pluginName])) {
133 $loader = new MetadataLoader($pluginName);
134 $pluginJsonCache[$pluginName] = $loader->loadPluginInfoJson();
135 }
136 if (!empty($pluginJsonCache[$pluginName]['require'])) {
137 $dependencies = $pluginJsonCache[$pluginName]['require'];
138 foreach ($dependencies as $possiblePluginName => $key) {
139 if (in_array($possiblePluginName, $toBeSorted, \true) && !in_array($possiblePluginName, $sorted, \true)) {
140 $sorted = $this->sortRequiredPlugin($possiblePluginName, $pluginJsonCache, $toBeSorted, $sorted);
141 }
142 }
143 }
144 if (!in_array($pluginName, $sorted, \true)) {
145 $sorted[] = $pluginName;
146 }
147 return $sorted;
148 }
149 }
150