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