PluginProbe ʕ •ᴥ•ʔ
Matomo Analytics – Powerful, Privacy-First Insights for WordPress / 5.0.3
Matomo Analytics – Powerful, Privacy-First Insights for WordPress v5.0.3
5.13.0 5.12.1 5.12.0 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 / Plugin / ControllerAdmin.php
matomo / app / core / Plugin Last commit date
ConsoleCommand 2 years ago Dimension 2 years ago API.php 2 years ago AggregatedMetric.php 2 years ago ArchivedMetric.php 2 years ago Archiver.php 2 years ago Categories.php 2 years ago ComponentFactory.php 2 years ago ComputedMetric.php 2 years ago ConsoleCommand.php 2 years ago Controller.php 2 years ago ControllerAdmin.php 2 years ago Dependency.php 2 years ago LogTablesProvider.php 2 years ago Manager.php 2 years ago Menu.php 2 years ago MetadataLoader.php 2 years ago Metric.php 2 years ago PluginException.php 2 years ago ProcessedMetric.php 2 years ago ReleaseChannels.php 2 years ago Report.php 2 years ago ReportsProvider.php 2 years ago RequestProcessors.php 2 years ago Segment.php 2 years ago SettingsProvider.php 2 years ago Tasks.php 2 years ago ThemeStyles.php 2 years ago ViewDataTable.php 2 years ago Visualization.php 2 years ago WidgetsProvider.php 2 years ago
ControllerAdmin.php
343 lines
1 <?php
2
3 /**
4 * Matomo - free/libre analytics platform
5 *
6 * @link https://matomo.org
7 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
8 *
9 */
10 namespace Piwik\Plugin;
11
12 use Piwik\Config as PiwikConfig;
13 use Piwik\Config;
14 use Piwik\Container\StaticContainer;
15 use Piwik\Date;
16 use Piwik\Development;
17 use Piwik\Menu\MenuAdmin;
18 use Piwik\Menu\MenuTop;
19 use Piwik\Notification;
20 use Piwik\Notification\Manager as NotificationManager;
21 use Piwik\Piwik;
22 use Piwik\Plugins\Marketplace\Marketplace;
23 use Piwik\Tracker\TrackerConfig;
24 use Piwik\Url;
25 use Piwik\Version;
26 use Piwik\View;
27 use Piwik\ProxyHttp;
28 use Piwik\SettingsPiwik;
29 /**
30 * Base class of plugin controllers that provide administrative functionality.
31 *
32 * See {@link Controller} to learn more about Piwik controllers.
33 *
34 */
35 abstract class ControllerAdmin extends \Piwik\Plugin\Controller
36 {
37 private static function notifyWhenTrackingStatisticsDisabled()
38 {
39 $statsEnabled = PiwikConfig::getInstance()->Tracker['record_statistics'];
40 if ($statsEnabled == "0") {
41 $notification = new Notification(Piwik::translate('General_StatisticsAreNotRecorded'));
42 $notification->context = Notification::CONTEXT_INFO;
43 Notification\Manager::notify('ControllerAdmin_StatsAreNotRecorded', $notification);
44 }
45 }
46 private static function notifyAnyInvalidLicense()
47 {
48 if (!Marketplace::isMarketplaceEnabled()) {
49 return;
50 }
51 if (Piwik::isUserIsAnonymous()) {
52 return;
53 }
54 if (!Piwik::isUserHasSomeAdminAccess()) {
55 return;
56 }
57 if (Development::isEnabled()) {
58 return;
59 }
60 $expired = StaticContainer::get('Piwik\\Plugins\\Marketplace\\Plugins\\InvalidLicenses');
61 $messageLicenseMissing = $expired->getMessageNoLicense();
62 if (!empty($messageLicenseMissing)) {
63 $notification = new Notification($messageLicenseMissing);
64 $notification->raw = true;
65 $notification->context = Notification::CONTEXT_ERROR;
66 $notification->title = Piwik::translate('Marketplace_LicenseMissing');
67 Notification\Manager::notify('ControllerAdmin_LicenseMissingWarning', $notification);
68 }
69 $messageExceeded = $expired->getMessageExceededLicenses();
70 if (!empty($messageExceeded)) {
71 $notification = new Notification($messageExceeded);
72 $notification->raw = true;
73 $notification->context = Notification::CONTEXT_WARNING;
74 $notification->title = Piwik::translate('Marketplace_LicenseExceeded');
75 Notification\Manager::notify('ControllerAdmin_LicenseExceededWarning', $notification);
76 }
77 $messageExpired = $expired->getMessageExpiredLicenses();
78 if (!empty($messageExpired)) {
79 $notification = new Notification($messageExpired);
80 $notification->raw = true;
81 $notification->context = Notification::CONTEXT_WARNING;
82 $notification->title = Piwik::translate('Marketplace_LicenseExpired');
83 Notification\Manager::notify('ControllerAdmin_LicenseExpiredWarning', $notification);
84 }
85 }
86 private static function notifyAnyInvalidPlugin()
87 {
88 if (!Piwik::hasUserSuperUserAccess()) {
89 return;
90 }
91 $missingPlugins = \Piwik\Plugin\Manager::getInstance()->getMissingPlugins();
92 if (empty($missingPlugins)) {
93 return;
94 }
95 $pluginsLink = Url::getCurrentQueryStringWithParametersModified(['module' => 'CorePluginsAdmin', 'action' => 'plugins']);
96 $invalidPluginsWarning = Piwik::translate('CoreAdminHome_InvalidPluginsWarning', [self::getPiwikVersion(), '<strong>' . implode('</strong>,&nbsp;<wbr><strong>', $missingPlugins) . '</strong>']) . "<br/>" . Piwik::translate('CoreAdminHome_InvalidPluginsYouCanUninstall', ['<a href="' . $pluginsLink . '"/>', '</a>']);
97 $notification = new Notification($invalidPluginsWarning);
98 $notification->raw = true;
99 $notification->context = Notification::CONTEXT_WARNING;
100 $notification->title = Piwik::translate('General_Warning');
101 Notification\Manager::notify('ControllerAdmin_InvalidPluginsWarning', $notification);
102 }
103 /**
104 * Calls {@link setBasicVariablesView()} and {@link setBasicVariablesAdminView()}
105 * using the supplied view.
106 *
107 * @param View $view
108 * @param string $viewType If 'admin', the admin variables are set as well as basic ones.
109 */
110 protected function setBasicVariablesViewAs($view, $viewType = 'admin')
111 {
112 $this->setBasicVariablesNoneAdminView($view);
113 if ($viewType === 'admin') {
114 self::setBasicVariablesAdminView($view);
115 }
116 }
117 private static function notifyIfURLIsNotSecure()
118 {
119 $isURLSecure = ProxyHttp::isHttps();
120 if ($isURLSecure) {
121 return;
122 }
123 if (!Piwik::hasUserSuperUserAccess()) {
124 return;
125 }
126 if (Url::isLocalHost(Url::getCurrentHost())) {
127 return;
128 }
129 if (Development::isEnabled()) {
130 return;
131 }
132 $message = Piwik::translate('General_CurrentlyUsingUnsecureHttp');
133 $message .= " ";
134 $message .= Piwik::translate('General_ReadThisToLearnMore', ['<a rel="noreferrer noopener" target="_blank" href="' . Url::addCampaignParametersToMatomoLink('https://matomo.org/faq/how-to/faq_91/">'), '</a>']);
135 $notification = new Notification($message);
136 $notification->context = Notification::CONTEXT_WARNING;
137 $notification->raw = true;
138 Notification\Manager::notify('ControllerAdmin_HttpIsUsed', $notification);
139 }
140 private static function notifyIfDevelopmentModeOnButNotInstalledThroughGit()
141 {
142 if (!Piwik::hasUserSuperUserAccess()) {
143 return;
144 }
145 if (!Development::isEnabled()) {
146 return;
147 }
148 if (SettingsPiwik::isGitDeployment()) {
149 return;
150 }
151 $message = Piwik::translate('General_WarningDevelopmentModeOnButNotGitInstalled');
152 $notification = new Notification($message);
153 $notification->context = Notification::CONTEXT_WARNING;
154 $notification->raw = true;
155 $notification->flags = Notification::FLAG_CLEAR;
156 Notification\Manager::notify('ControllerAdmin_DevelopmentModeOn', $notification);
157 }
158 /**
159 * @ignore
160 */
161 public static function displayWarningIfConfigFileNotWritable()
162 {
163 $isConfigFileWritable = PiwikConfig::getInstance()->isFileWritable();
164 if (!$isConfigFileWritable) {
165 $exception = PiwikConfig::getInstance()->getConfigNotWritableException();
166 $message = $exception->getMessage();
167 $notification = new Notification($message);
168 $notification->raw = true;
169 $notification->context = Notification::CONTEXT_WARNING;
170 Notification\Manager::notify('ControllerAdmin_ConfigNotWriteable', $notification);
171 }
172 }
173 private static function notifyIfEAcceleratorIsUsed()
174 {
175 $isEacceleratorUsed = ini_get('eaccelerator.enable');
176 if (empty($isEacceleratorUsed)) {
177 return;
178 }
179 $message = sprintf("You are using the PHP accelerator & optimizer eAccelerator which is known to be not compatible with Matomo.\n We have disabled eAccelerator, which might affect the performance of Matomo.\n Read the %srelated ticket%s for more information and how to fix this problem.", '<a rel="noreferrer noopener" target="_blank" href="https://github.com/matomo-org/matomo/issues/4439">', '</a>');
180 $notification = new Notification($message);
181 $notification->context = Notification::CONTEXT_WARNING;
182 $notification->raw = true;
183 Notification\Manager::notify('ControllerAdmin_EacceleratorIsUsed', $notification);
184 }
185 /**
186 * PHP Version required by the next major Matomo version
187 * @return string
188 */
189 private static function getNextRequiredMinimumPHP()
190 {
191 return '7.2';
192 }
193 private static function isUsingPhpVersionCompatibleWithNextPiwik()
194 {
195 return version_compare(PHP_VERSION, self::getNextRequiredMinimumPHP(), '>=');
196 }
197 private static function notifyWhenPhpVersionIsNotCompatibleWithNextMajorPiwik()
198 {
199 if (self::isUsingPhpVersionCompatibleWithNextPiwik()) {
200 return;
201 }
202 $youMustUpgradePHP = Piwik::translate('General_YouMustUpgradePhpVersionToReceiveLatestPiwik');
203 $message = Piwik::translate('General_PiwikCannotBeUpgradedBecausePhpIsTooOld') . ' ' . sprintf(Piwik::translate('General_PleaseUpgradeYourPhpVersionSoYourPiwikDataStaysSecure'), self::getNextRequiredMinimumPHP());
204 $notification = new Notification($message);
205 $notification->title = $youMustUpgradePHP;
206 $notification->priority = Notification::PRIORITY_LOW;
207 $notification->context = Notification::CONTEXT_WARNING;
208 $notification->type = Notification::TYPE_TRANSIENT;
209 $notification->flags = Notification::FLAG_NO_CLEAR;
210 NotificationManager::notify('PHPVersionTooOldForNewestPiwikCheck', $notification);
211 }
212 private static function notifyWhenPhpVersionIsEOL()
213 {
214 if (defined('PIWIK_TEST_MODE')) {
215 // to avoid changing every admin UI test
216 return;
217 }
218 $notifyPhpIsEOL = Piwik::hasUserSuperUserAccess() && self::isPhpVersionEOL();
219 if (!$notifyPhpIsEOL) {
220 return;
221 }
222 $deprecatedMajorPhpVersion = PHP_MAJOR_VERSION . '.' . PHP_MINOR_VERSION;
223 $message = '';
224 if (version_compare(PHP_VERSION, self::getNextRequiredMinimumPHP(), '<')) {
225 $message = Piwik::translate('General_WarningPiwikWillStopSupportingPHPVersion', [$deprecatedMajorPhpVersion, self::getNextRequiredMinimumPHP()]) . '<br/>';
226 }
227 $message .= Piwik::translate('General_WarningPhpVersionXIsTooOld', $deprecatedMajorPhpVersion);
228 $notification = new Notification($message);
229 $notification->raw = true;
230 $notification->title = Piwik::translate('General_Warning');
231 $notification->priority = Notification::PRIORITY_LOW;
232 $notification->context = Notification::CONTEXT_WARNING;
233 $notification->type = Notification::TYPE_TRANSIENT;
234 $notification->flags = Notification::FLAG_NO_CLEAR;
235 NotificationManager::notify('PHPVersionCheck', $notification);
236 }
237 private static function notifyWhenDebugOnDemandIsEnabled($trackerSetting)
238 {
239 if (!Development::isEnabled() && Piwik::hasUserSuperUserAccess() && TrackerConfig::getConfigValue($trackerSetting)) {
240 $message = Piwik::translate('General_WarningDebugOnDemandEnabled');
241 $message = sprintf($message, '"' . $trackerSetting . '"', '"[Tracker] ' . $trackerSetting . '"', '"0"', '"config/config.ini.php"');
242 $notification = new Notification($message);
243 $notification->title = Piwik::translate('General_Warning');
244 $notification->priority = Notification::PRIORITY_LOW;
245 $notification->context = Notification::CONTEXT_WARNING;
246 $notification->type = Notification::TYPE_TRANSIENT;
247 $notification->flags = Notification::FLAG_NO_CLEAR;
248 NotificationManager::notify('Tracker' . $trackerSetting, $notification);
249 }
250 }
251 /**
252 * Assigns view properties that would be useful to views that render admin pages.
253 *
254 * Assigns the following variables:
255 *
256 * - **statisticsNotRecorded** - Set to true if the `[Tracker] record_statistics` INI
257 * config is `0`. If not `0`, this variable will not be defined.
258 * - **topMenu** - The result of `MenuTop::getInstance()->getMenu()`.
259 * - **enableFrames** - The value of the `[General] enable_framed_pages` INI config option. If
260 * true, {@link Piwik\View::setXFrameOptions()} is called on the view.
261 * - **isSuperUser** - Whether the current user is a superuser or not.
262 * - **usingOldGeoIPPlugin** - Whether this Piwik install is currently using the old GeoIP
263 * plugin or not.
264 * - **invalidPluginsWarning** - Set if some of the plugins to load (determined by INI configuration)
265 * are invalid or missing.
266 * - **phpVersion** - The current PHP version.
267 * - **phpIsNewEnough** - Whether the current PHP version is new enough to run Piwik.
268 * - **adminMenu** - The result of `MenuAdmin::getInstance()->getMenu()`.
269 *
270 * @param View $view
271 * @api
272 */
273 public static function setBasicVariablesAdminView(View $view)
274 {
275 self::notifyWhenTrackingStatisticsDisabled();
276 self::notifyIfEAcceleratorIsUsed();
277 self::notifyIfURLIsNotSecure();
278 self::notifyIfDevelopmentModeOnButNotInstalledThroughGit();
279 $view->topMenu = MenuTop::getInstance()->getMenu();
280 $view->isDataPurgeSettingsEnabled = self::isDataPurgeSettingsEnabled();
281 $enableFrames = PiwikConfig::getInstance()->General['enable_framed_settings'];
282 $view->enableFrames = $enableFrames;
283 if (!$enableFrames) {
284 $view->setXFrameOptions('sameorigin');
285 }
286 $view->isSuperUser = Piwik::hasUserSuperUserAccess();
287 self::notifyAnyInvalidLicense();
288 self::notifyAnyInvalidPlugin();
289 self::notifyWhenPhpVersionIsEOL();
290 self::notifyWhenPhpVersionIsNotCompatibleWithNextMajorPiwik();
291 self::notifyWhenDebugOnDemandIsEnabled('debug');
292 self::notifyWhenDebugOnDemandIsEnabled('debug_on_demand');
293 /**
294 * Posted when rendering an admin page and notifications about any warnings or errors should be triggered.
295 * You can use it for example when you have a plugin that needs to be configured in order to work and the
296 * plugin has not been configured yet. It can be also used to cancel / remove other notifications by calling
297 * eg `Notification\Manager::cancel($notificationId)`.
298 *
299 * **Example**
300 *
301 * public function onTriggerAdminNotifications(Piwik\Widget\WidgetsList $list)
302 * {
303 * if ($pluginFooIsNotConfigured) {
304 * $notification = new Notification('The plugin foo has not been configured yet');
305 * $notification->context = Notification::CONTEXT_WARNING;
306 * Notification\Manager::notify('fooNotConfigured', $notification);
307 * }
308 * }
309 *
310 */
311 Piwik::postEvent('Controller.triggerAdminNotifications');
312 $view->adminMenu = MenuAdmin::getInstance()->getMenu();
313 $notifications = $view->notifications;
314 if (empty($notifications)) {
315 $view->notifications = NotificationManager::getAllNotificationsToDisplay();
316 NotificationManager::cancelAllNonPersistent();
317 }
318 }
319 public static function isDataPurgeSettingsEnabled()
320 {
321 return (bool) Config::getInstance()->General['enable_delete_old_data_settings_admin'];
322 }
323 protected static function getPiwikVersion()
324 {
325 return "Matomo " . Version::VERSION;
326 }
327 private static function isPhpVersionEOL()
328 {
329 $phpEOL = '7.3';
330 // End of security update for certain PHP versions as of https://www.php.net/supported-versions.php
331 if (Date::today()->isLater(Date::factory('2022-11-28'))) {
332 $phpEOL = '7.4';
333 }
334 if (Date::today()->isLater(Date::factory('2023-11-26'))) {
335 $phpEOL = '8.0';
336 }
337 if (Date::today()->isLater(Date::factory('2024-11-25'))) {
338 $phpEOL = '8.1';
339 }
340 return version_compare(PHP_MAJOR_VERSION . '.' . PHP_MINOR_VERSION, $phpEOL, '<=');
341 }
342 }
343