PluginProbe ʕ •ᴥ•ʔ
Matomo Analytics – Powerful, Privacy-First Insights for WordPress / 5.2.0
Matomo Analytics – Powerful, Privacy-First Insights for WordPress v5.2.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 1 year ago API.php 1 year ago AggregatedMetric.php 2 years ago ArchivedMetric.php 1 year ago Archiver.php 1 year ago Categories.php 2 years ago ComponentFactory.php 2 years ago ComputedMetric.php 1 year ago ConsoleCommand.php 1 year ago Controller.php 1 year ago ControllerAdmin.php 1 year ago Dependency.php 1 year ago LogTablesProvider.php 2 years ago Manager.php 1 year ago Menu.php 1 year ago MetadataLoader.php 1 year ago Metric.php 1 year ago PluginException.php 1 year ago ProcessedMetric.php 1 year ago ReleaseChannels.php 2 years ago Report.php 1 year ago ReportsProvider.php 2 years ago RequestProcessors.php 2 years ago Segment.php 1 year ago SettingsProvider.php 2 years ago Tasks.php 1 year ago ThemeStyles.php 2 years ago ViewDataTable.php 1 year ago Visualization.php 1 year ago WidgetsProvider.php 2 years ago
ControllerAdmin.php
345 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\Plugin;
10
11 use Piwik\Config as PiwikConfig;
12 use Piwik\Config;
13 use Piwik\Container\StaticContainer;
14 use Piwik\Date;
15 use Piwik\Development;
16 use Piwik\Exception\MissingFilePermissionException;
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 try {
164 PiwikConfig::getInstance()->checkConfigIsWritable();
165 } catch (MissingFilePermissionException $exception) {
166 $notification = new Notification($exception->getMessage());
167 $notification->raw = \true;
168 $notification->context = Notification::CONTEXT_WARNING;
169 Notification\Manager::notify('ControllerAdmin_ConfigNotWriteable', $notification);
170 }
171 }
172 private static function notifyIfEAcceleratorIsUsed()
173 {
174 $isEacceleratorUsed = ini_get('eaccelerator.enable');
175 if (empty($isEacceleratorUsed)) {
176 return;
177 }
178 $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>');
179 $notification = new Notification($message);
180 $notification->context = Notification::CONTEXT_WARNING;
181 $notification->raw = \true;
182 Notification\Manager::notify('ControllerAdmin_EacceleratorIsUsed', $notification);
183 }
184 /**
185 * PHP Version required by the next major Matomo version
186 * @return string
187 */
188 private static function getNextRequiredMinimumPHP()
189 {
190 return '7.2';
191 }
192 private static function isUsingPhpVersionCompatibleWithNextPiwik()
193 {
194 return version_compare(\PHP_VERSION, self::getNextRequiredMinimumPHP(), '>=');
195 }
196 private static function notifyWhenPhpVersionIsNotCompatibleWithNextMajorPiwik()
197 {
198 if (self::isUsingPhpVersionCompatibleWithNextPiwik()) {
199 return;
200 }
201 $youMustUpgradePHP = Piwik::translate('General_YouMustUpgradePhpVersionToReceiveLatestPiwik');
202 $message = Piwik::translate('General_PiwikCannotBeUpgradedBecausePhpIsTooOld') . ' ' . sprintf(Piwik::translate('General_PleaseUpgradeYourPhpVersionSoYourPiwikDataStaysSecure'), self::getNextRequiredMinimumPHP());
203 $notification = new Notification($message);
204 $notification->title = $youMustUpgradePHP;
205 $notification->priority = Notification::PRIORITY_LOW;
206 $notification->context = Notification::CONTEXT_WARNING;
207 $notification->type = Notification::TYPE_TRANSIENT;
208 $notification->flags = Notification::FLAG_NO_CLEAR;
209 NotificationManager::notify('PHPVersionTooOldForNewestPiwikCheck', $notification);
210 }
211 private static function notifyWhenPhpVersionIsEOL()
212 {
213 if (defined('PIWIK_TEST_MODE')) {
214 // to avoid changing every admin UI test
215 return;
216 }
217 $notifyPhpIsEOL = Piwik::hasUserSuperUserAccess() && self::isPhpVersionEOL();
218 if (!$notifyPhpIsEOL) {
219 return;
220 }
221 $deprecatedMajorPhpVersion = \PHP_MAJOR_VERSION . '.' . \PHP_MINOR_VERSION;
222 $message = '';
223 if (version_compare(\PHP_VERSION, self::getNextRequiredMinimumPHP(), '<')) {
224 $message = Piwik::translate('General_WarningPiwikWillStopSupportingPHPVersion', [$deprecatedMajorPhpVersion, self::getNextRequiredMinimumPHP()]) . '<br/>';
225 }
226 $message .= Piwik::translate('General_WarningPhpVersionXIsTooOld', $deprecatedMajorPhpVersion);
227 $notification = new Notification($message);
228 $notification->raw = \true;
229 $notification->title = Piwik::translate('General_Warning');
230 $notification->priority = Notification::PRIORITY_LOW;
231 $notification->context = Notification::CONTEXT_WARNING;
232 $notification->type = Notification::TYPE_TRANSIENT;
233 $notification->flags = Notification::FLAG_NO_CLEAR;
234 NotificationManager::notify('PHPVersionCheck', $notification);
235 }
236 private static function notifyWhenDebugOnDemandIsEnabled($trackerSetting)
237 {
238 if (!Development::isEnabled() && Piwik::hasUserSuperUserAccess() && TrackerConfig::getConfigValue($trackerSetting)) {
239 $message = Piwik::translate('General_WarningDebugOnDemandEnabled');
240 $message = sprintf($message, '"' . $trackerSetting . '"', '"[Tracker] ' . $trackerSetting . '"', '"0"', '"config/config.ini.php"');
241 $notification = new Notification($message);
242 $notification->title = Piwik::translate('General_Warning');
243 $notification->priority = Notification::PRIORITY_LOW;
244 $notification->context = Notification::CONTEXT_WARNING;
245 $notification->type = Notification::TYPE_TRANSIENT;
246 $notification->flags = Notification::FLAG_NO_CLEAR;
247 NotificationManager::notify('Tracker' . $trackerSetting, $notification);
248 }
249 }
250 /**
251 * Assigns view properties that would be useful to views that render admin pages.
252 *
253 * Assigns the following variables:
254 *
255 * - **statisticsNotRecorded** - Set to true if the `[Tracker] record_statistics` INI
256 * config is `0`. If not `0`, this variable will not be defined.
257 * - **topMenu** - The result of `MenuTop::getInstance()->getMenu()`.
258 * - **enableFrames** - The value of the `[General] enable_framed_pages` INI config option. If
259 * true, {@link Piwik\View::setXFrameOptions()} is called on the view.
260 * - **isSuperUser** - Whether the current user is a superuser or not.
261 * - **usingOldGeoIPPlugin** - Whether this Piwik install is currently using the old GeoIP
262 * plugin or not.
263 * - **invalidPluginsWarning** - Set if some of the plugins to load (determined by INI configuration)
264 * are invalid or missing.
265 * - **phpVersion** - The current PHP version.
266 * - **phpIsNewEnough** - Whether the current PHP version is new enough to run Piwik.
267 * - **adminMenu** - The result of `MenuAdmin::getInstance()->getMenu()`.
268 *
269 * @param View $view
270 * @api
271 */
272 public static function setBasicVariablesAdminView(View $view)
273 {
274 self::notifyWhenTrackingStatisticsDisabled();
275 self::notifyIfEAcceleratorIsUsed();
276 self::notifyIfURLIsNotSecure();
277 self::notifyIfDevelopmentModeOnButNotInstalledThroughGit();
278 $view->topMenu = MenuTop::getInstance()->getMenu();
279 $view->isDataPurgeSettingsEnabled = self::isDataPurgeSettingsEnabled();
280 $enableFrames = PiwikConfig::getInstance()->General['enable_framed_settings'];
281 $view->enableFrames = $enableFrames;
282 if (!$enableFrames) {
283 $view->setXFrameOptions('sameorigin');
284 }
285 $view->isSuperUser = Piwik::hasUserSuperUserAccess();
286 self::notifyAnyInvalidLicense();
287 self::notifyAnyInvalidPlugin();
288 self::notifyWhenPhpVersionIsEOL();
289 self::notifyWhenPhpVersionIsNotCompatibleWithNextMajorPiwik();
290 self::notifyWhenDebugOnDemandIsEnabled('debug');
291 self::notifyWhenDebugOnDemandIsEnabled('debug_on_demand');
292 /**
293 * Posted when rendering an admin page and notifications about any warnings or errors should be triggered.
294 * You can use it for example when you have a plugin that needs to be configured in order to work and the
295 * plugin has not been configured yet. It can be also used to cancel / remove other notifications by calling
296 * eg `Notification\Manager::cancel($notificationId)`.
297 *
298 * **Example**
299 *
300 * public function onTriggerAdminNotifications(Piwik\Widget\WidgetsList $list)
301 * {
302 * if ($pluginFooIsNotConfigured) {
303 * $notification = new Notification('The plugin foo has not been configured yet');
304 * $notification->context = Notification::CONTEXT_WARNING;
305 * Notification\Manager::notify('fooNotConfigured', $notification);
306 * }
307 * }
308 *
309 */
310 Piwik::postEvent('Controller.triggerAdminNotifications');
311 $view->adminMenu = MenuAdmin::getInstance()->getMenu();
312 $notifications = $view->notifications;
313 if (empty($notifications)) {
314 $view->notifications = NotificationManager::getAllNotificationsToDisplay();
315 NotificationManager::cancelAllNonPersistent();
316 }
317 }
318 public static function isDataPurgeSettingsEnabled()
319 {
320 return (bool) Config::getInstance()->General['enable_delete_old_data_settings_admin'];
321 }
322 protected static function getPiwikVersion()
323 {
324 return "Matomo " . Version::VERSION;
325 }
326 private static function isPhpVersionEOL()
327 {
328 $phpEOL = '8.0';
329 // End of security update for certain PHP versions as of https://www.php.net/supported-versions
330 if (Date::today()->isLater(Date::factory('2025-12-31'))) {
331 $phpEOL = '8.1';
332 }
333 if (Date::today()->isLater(Date::factory('2026-12-31'))) {
334 $phpEOL = '8.2';
335 }
336 if (Date::today()->isLater(Date::factory('2027-12-31'))) {
337 $phpEOL = '8.3';
338 }
339 if (Date::today()->isLater(Date::factory('2028-12-31'))) {
340 $phpEOL = '8.4';
341 }
342 return version_compare(\PHP_MAJOR_VERSION . '.' . \PHP_MINOR_VERSION, $phpEOL, '<=');
343 }
344 }
345