PluginProbe ʕ •ᴥ•ʔ
Matomo Analytics – Powerful, Privacy-First Insights for WordPress / 5.8.2
Matomo Analytics – Powerful, Privacy-First Insights for WordPress v5.8.2
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 / SettingsPiwik.php
matomo / app / core Last commit date
API 3 months ago Access 3 months ago Application 3 months ago Archive 3 months ago ArchiveProcessor 3 months ago Archiver 2 years ago AssetManager 3 months ago Auth 7 months ago Category 7 months ago Changes 3 months ago CliMulti 1 year ago Columns 3 months ago Concurrency 3 months ago Config 3 months ago Container 3 months ago CronArchive 3 months ago DataAccess 3 months ago DataFiles 2 years ago DataTable 3 months ago Db 3 months ago DeviceDetector 1 year ago Email 2 years ago Exception 4 months ago Http 4 months ago Intl 3 months ago Log 2 years ago Mail 1 year ago Measurable 7 months ago Menu 3 months ago Metrics 3 months ago Notification 7 months ago Period 3 months ago Plugin 3 months ago Policy 3 months ago ProfessionalServices 1 year ago Report 1 year ago ReportRenderer 3 months ago Request 3 months ago Scheduler 3 months ago Segment 3 months ago Session 3 months ago Settings 3 months ago Tracker 3 months ago Translation 3 months ago Twig 1 year ago UpdateCheck 3 months ago Updater 4 months ago Updates 3 months ago Validators 1 year ago View 7 months ago ViewDataTable 3 months ago Visualization 1 year ago Widget 3 months ago .htaccess 2 years ago Access.php 3 months ago Archive.php 3 months ago ArchiveProcessor.php 4 months ago AssetManager.php 3 months ago Auth.php 7 months ago AuthResult.php 7 months ago BaseFactory.php 2 years ago Cache.php 2 years ago CacheId.php 4 months ago CliMulti.php 3 months ago Common.php 3 months ago Config.php 3 months ago Console.php 3 months ago Context.php 2 years ago Cookie.php 1 year ago CronArchive.php 3 months ago DI.php 3 months ago DataArray.php 5 months ago DataTable.php 3 months ago Date.php 3 months ago Db.php 3 months ago DbHelper.php 3 months ago Development.php 1 year ago ErrorHandler.php 7 months ago EventDispatcher.php 1 year ago ExceptionHandler.php 4 months ago FileIntegrity.php 3 months ago Filechecks.php 1 year ago Filesystem.php 3 months ago FrontController.php 4 months ago Http.php 4 months ago IP.php 1 year ago Log.php 3 months ago LogDeleter.php 1 year ago Mail.php 1 year ago Metrics.php 3 months ago NoAccessException.php 2 years ago Nonce.php 7 months ago Notification.php 7 months ago NumberFormatter.php 5 months ago Option.php 5 months ago Period.php 3 months ago Piwik.php 3 months ago Plugin.php 3 months ago Process.php 1 year ago Profiler.php 7 months ago ProxyHeaders.php 4 months ago ProxyHttp.php 5 months ago QuickForm2.php 3 months ago RankingQuery.php 5 months ago ReportRenderer.php 3 months ago Request.php 3 months ago Segment.php 3 months ago Sequence.php 7 months ago Session.php 3 months ago SettingsPiwik.php 3 months ago SettingsServer.php 1 year ago Singleton.php 2 years ago Site.php 4 months ago SiteContentDetector.php 3 months ago SupportedBrowser.php 2 years ago TCPDF.php 1 year ago Theme.php 1 year ago Timer.php 2 years ago Tracker.php 3 months ago Twig.php 3 months ago Unzip.php 1 year ago UpdateCheck.php 3 months ago Updater.php 3 months ago UpdaterErrorException.php 2 years ago Updates.php 3 months ago Url.php 3 months ago UrlHelper.php 3 months ago Version.php 3 months ago View.php 3 months ago bootstrap.php 1 year ago dispatch.php 2 years ago testMinimumPhpVersion.php 7 months ago
SettingsPiwik.php
405 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;
10
11 use Exception;
12 use Piwik\Cache as PiwikCache;
13 use Piwik\Config\GeneralConfig;
14 use Piwik\Container\StaticContainer;
15 /**
16 * Contains helper methods that can be used to get common Piwik settings.
17 *
18 */
19 class SettingsPiwik
20 {
21 public const OPTION_PIWIK_URL = 'piwikUrl';
22 /**
23 * Get salt from [General] section. Should ONLY be used as a seed to create hashes
24 *
25 * NOTE: Keep this salt secret! Never output anywhere or share it etc.
26 *
27 */
28 public static function getSalt() : ?string
29 {
30 static $salt = null;
31 if (is_null($salt)) {
32 $salt = \Piwik\Config::getInstance()->General['salt'] ?? '';
33 }
34 return $salt;
35 }
36 /**
37 * Should Piwik check that the login & password have minimum length and valid characters?
38 *
39 * @return bool True if checks enabled; false otherwise
40 */
41 public static function isUserCredentialsSanityCheckEnabled() : bool
42 {
43 return \Piwik\Config::getInstance()->General['disable_checks_usernames_attributes'] == 0;
44 }
45 /**
46 * Should Piwik show the update notification to superusers only?
47 *
48 * @return bool True if show to superusers only; false otherwise
49 */
50 public static function isShowUpdateNotificationToSuperUsersOnlyEnabled() : bool
51 {
52 return \Piwik\Config::getInstance()->General['show_update_notification_to_superusers_only'] == 1;
53 }
54 /**
55 * Returns every stored segment to pre-process for each site during cron archiving.
56 *
57 * @return array The list of stored segments that apply to all sites.
58 */
59 public static function getKnownSegmentsToArchive() : array
60 {
61 $cacheId = 'KnownSegmentsToArchive';
62 $cache = PiwikCache::getTransientCache();
63 if ($cache->contains($cacheId)) {
64 return $cache->fetch($cacheId);
65 }
66 $segments = \Piwik\Config::getInstance()->Segments;
67 $segmentsToProcess = isset($segments['Segments']) ? $segments['Segments'] : array();
68 /**
69 * Triggered during the cron archiving process to collect segments that
70 * should be pre-processed for all websites. The archiving process will be launched
71 * for each of these segments when archiving data.
72 *
73 * This event can be used to add segments to be pre-processed. If your plugin depends
74 * on data from a specific segment, this event could be used to provide enhanced
75 * performance.
76 *
77 * _Note: If you just want to add a segment that is managed by the user, use the
78 * SegmentEditor API._
79 *
80 * **Example**
81 *
82 * Piwik::addAction('Segments.getKnownSegmentsToArchiveAllSites', function (&$segments) {
83 * $segments[] = 'country=jp;city=Tokyo';
84 * });
85 *
86 * @param array &$segmentsToProcess List of segment definitions, eg,
87 *
88 * array(
89 * 'browserCode=ff;resolution=800x600',
90 * 'country=jp;city=Tokyo'
91 * )
92 *
93 * Add segments to this array in your event handler.
94 */
95 \Piwik\Piwik::postEvent('Segments.getKnownSegmentsToArchiveAllSites', array(&$segmentsToProcess));
96 $segmentsToProcess = array_unique($segmentsToProcess);
97 $cache->save($cacheId, $segmentsToProcess);
98 return $segmentsToProcess;
99 }
100 /**
101 * Returns the list of stored segments to pre-process for an individual site when executing
102 * cron archiving.
103 *
104 * @param int $idSite The ID of the site to get stored segments for.
105 * @return string[] The list of stored segments that apply to the requested site.
106 */
107 public static function getKnownSegmentsToArchiveForSite($idSite) : array
108 {
109 $cacheId = 'KnownSegmentsToArchiveForSite' . $idSite;
110 $cache = PiwikCache::getTransientCache();
111 if ($cache->contains($cacheId)) {
112 return $cache->fetch($cacheId);
113 }
114 $segments = array();
115 /**
116 * Triggered during the cron archiving process to collect segments that
117 * should be pre-processed for one specific site. The archiving process will be launched
118 * for each of these segments when archiving data for that one site.
119 *
120 * This event can be used to add segments to be pre-processed for one site.
121 *
122 * _Note: If you just want to add a segment that is managed by the user, you should use the
123 * SegmentEditor API._
124 *
125 * **Example**
126 *
127 * Piwik::addAction('Segments.getKnownSegmentsToArchiveForSite', function (&$segments, $idSite) {
128 * $segments[] = 'country=jp;city=Tokyo';
129 * });
130 *
131 * @param array &$segmentsToProcess List of segment definitions, eg,
132 *
133 * array(
134 * 'browserCode=ff;resolution=800x600',
135 * 'country=JP;city=Tokyo'
136 * )
137 *
138 * Add segments to this array in your event handler.
139 * @param int $idSite The ID of the site to get segments for.
140 */
141 \Piwik\Piwik::postEvent('Segments.getKnownSegmentsToArchiveForSite', array(&$segments, $idSite));
142 $segments = array_unique($segments);
143 $cache->save($cacheId, $segments);
144 return $segments;
145 }
146 /**
147 * Number of websites to show in the Website selector
148 *
149 */
150 public static function getWebsitesCountToDisplay() : int
151 {
152 $count = max(\Piwik\Config::getInstance()->General['site_selector_max_sites'], \Piwik\Config::getInstance()->General['autocomplete_min_sites']);
153 return (int) $count;
154 }
155 /**
156 * Returns the URL to this Piwik instance, eg. **https://demo.piwik.org/** or **https://example.org/piwik/**.
157 *
158 * @return string|false return false if no value is configured and we are in PHP CLI mode
159 * @api
160 */
161 public static function getPiwikUrl()
162 {
163 $url = \Piwik\Option::get(self::OPTION_PIWIK_URL);
164 $isPiwikCoreDispatching = defined('PIWIK_ENABLE_DISPATCH') && PIWIK_ENABLE_DISPATCH;
165 if (\Piwik\Common::isPhpCliMode() || \Piwik\SettingsServer::isArchivePhpTriggered() || !$isPiwikCoreDispatching) {
166 return $url;
167 }
168 $currentUrl = \Piwik\Common::sanitizeInputValue(\Piwik\Url::getCurrentUrlWithoutFileName());
169 // when script is called from /misc/cron/archive.php, Piwik URL is /index.php
170 $currentUrl = str_replace("/misc/cron", "", $currentUrl);
171 if (empty($url) || $currentUrl !== $url) {
172 $host = \Piwik\Url::getHostFromUrl($currentUrl);
173 if (strlen($currentUrl) >= strlen('http://a/') && \Piwik\Url::isValidHost($host) && !\Piwik\Url::isLocalHost($host)) {
174 self::overwritePiwikUrl($currentUrl);
175 }
176 $url = $currentUrl;
177 }
178 if (\Piwik\ProxyHttp::isHttps()) {
179 $url = str_replace("http://", "https://", $url);
180 }
181 return $url;
182 }
183 public static function isMatomoInstalled() : bool
184 {
185 $config = \Piwik\Config::getInstance()->getLocalPath();
186 $exists = file_exists($config);
187 // Piwik is not installed if the config file is not found
188 if (!$exists) {
189 return \false;
190 }
191 $general = \Piwik\Config::getInstance()->General;
192 $isInstallationInProgress = \false;
193 if (array_key_exists('installation_in_progress', $general)) {
194 $isInstallationInProgress = (bool) $general['installation_in_progress'];
195 }
196 if ($isInstallationInProgress) {
197 return \false;
198 }
199 // Check that the database section is really set, ie. file is not empty
200 if (empty(\Piwik\Config::getInstance()->database['username'])) {
201 return \false;
202 }
203 return \true;
204 }
205 /**
206 * Check if outgoing internet connections are enabled
207 * This is often disable in an intranet environment
208 *
209 */
210 public static function isInternetEnabled() : bool
211 {
212 return (bool) \Piwik\Config::getInstance()->General['enable_internet_features'];
213 }
214 /**
215 * Detect whether user has enabled auto updates. Please note this config is a bit misleading. It is currently
216 * actually used for 2 things: To disable making any connections back to Piwik, and to actually disable the auto
217 * update of core and plugins.
218 */
219 public static function isAutoUpdateEnabled() : bool
220 {
221 $enableAutoUpdate = (bool) \Piwik\Config::getInstance()->General['enable_auto_update'];
222 if (self::isInternetEnabled() === \true && $enableAutoUpdate === \true) {
223 return \true;
224 }
225 return \false;
226 }
227 /**
228 * Detects whether an auto update can be made. An update is possible if the user is not on multiple servers and if
229 * automatic updates are actually enabled. If a user is running Piwik on multiple servers an update is not possible
230 * as it would be installed only on one server instead of all of them. Also if a user has disabled automatic updates
231 * we cannot perform any automatic updates.
232 *
233 */
234 public static function isAutoUpdatePossible() : bool
235 {
236 return !self::isMultiServerEnvironment() && self::isAutoUpdateEnabled();
237 }
238 /**
239 * Returns `true` if Piwik is running on more than one server. For example in a load balanced environment. In this
240 * case we should not make changes to the config and not install a plugin via the UI as it would be only executed
241 * on one server.
242 */
243 public static function isMultiServerEnvironment() : bool
244 {
245 $is = \Piwik\Config::getInstance()->General['multi_server_environment'];
246 return !empty($is);
247 }
248 /**
249 * Returns `true` if segmentation is allowed for this user, `false` if otherwise.
250 *
251 * @api
252 */
253 public static function isSegmentationEnabled() : bool
254 {
255 return !\Piwik\Piwik::isUserIsAnonymous() || \Piwik\Config::getInstance()->General['anonymous_user_enable_use_segments_API'];
256 }
257 /**
258 * Returns true if unique visitors should be processed for the given period type.
259 *
260 * Unique visitor processing is controlled by the `[General] enable_processing_unique_visitors_...`
261 * INI config options. By default, unique visitors are processed only for day/week/month periods.
262 *
263 * @param string $periodLabel `"day"`, `"week"`, `"month"`, `"year"` or `"range"`
264 * @api
265 */
266 public static function isUniqueVisitorsEnabled(string $periodLabel) : bool
267 {
268 $generalSettings = \Piwik\Config::getInstance()->General;
269 $settingName = "enable_processing_unique_visitors_{$periodLabel}";
270 $result = !empty($generalSettings[$settingName]) && $generalSettings[$settingName] == 1;
271 // check enable_processing_unique_visitors_year_and_range for backwards compatibility
272 if (($periodLabel === 'year' || $periodLabel === 'range') && isset($generalSettings['enable_processing_unique_visitors_year_and_range'])) {
273 $result |= $generalSettings['enable_processing_unique_visitors_year_and_range'] == 1;
274 }
275 return $result;
276 }
277 /**
278 * If Piwik uses per-domain config file, make sure CustomLogo is unique
279 * @throws \Piwik\Exception\DI\DependencyException
280 * @throws \Piwik\Exception\DI\NotFoundException
281 * @throws Exception
282 */
283 public static function rewriteMiscUserPathWithInstanceId(string $path) : string
284 {
285 $tmp = StaticContainer::get('path.misc.user');
286 $path = self::rewritePathAppendPiwikInstanceId($path, $tmp);
287 return $path;
288 }
289 /**
290 * Returns true if the Piwik server appears to be working.
291 *
292 * If the Piwik server is in an error state (eg. some directories are not writable and Piwik displays error message),
293 * or if the Piwik server is "offline",
294 * this will return false..
295 *
296 * @throws Exception
297 */
298 public static function checkPiwikServerWorking(string $piwikServerUrl, bool $acceptInvalidSSLCertificates = \false) : void
299 {
300 // Now testing if the webserver is running
301 try {
302 $fetched = \Piwik\Http::sendHttpRequestBy('curl', $piwikServerUrl, $timeout = 45, $userAgent = null, $destinationPath = null, $file = null, $followDepth = 0, $acceptLanguage = \false, $acceptInvalidSSLCertificates);
303 } catch (Exception $e) {
304 $fetched = "ERROR fetching: " . $e->getMessage();
305 }
306 // this will match when Piwik not installed yet, or favicon not customised
307 $expectedStringAlt = 'plugins/CoreHome/images/favicon.png';
308 // this will match when Piwik is installed and favicon has been customised
309 $expectedString = 'misc/user/';
310 // see checkPiwikIsNotInstalled()
311 $expectedStringAlreadyInstalled = 'piwik-is-already-installed';
312 $expectedStringNotFound = strpos($fetched, $expectedString) === \false && strpos($fetched, $expectedStringAlt) === \false && strpos($fetched, $expectedStringAlreadyInstalled) === \false;
313 $hasError = \false !== strpos($fetched, PAGE_TITLE_WHEN_ERROR);
314 if ($hasError || $expectedStringNotFound) {
315 throw new Exception("\nMatomo should be running at: " . $piwikServerUrl . " but this URL returned an unexpected response: '" . $fetched . "'\n\n");
316 }
317 }
318 /**
319 * Returns true if Piwik is deployed using git
320 * FAQ: https://piwik.org/faq/how-to-install/faq_18271/
321 *
322 */
323 public static function isGitDeployment() : bool
324 {
325 return file_exists(PIWIK_INCLUDE_PATH . '/.git/HEAD');
326 }
327 public static function getCurrentGitBranch() : string
328 {
329 $file = PIWIK_INCLUDE_PATH . '/.git/HEAD';
330 if (!file_exists($file)) {
331 return '';
332 }
333 $firstLineOfGitHead = file($file);
334 if (empty($firstLineOfGitHead)) {
335 return '';
336 }
337 $firstLineOfGitHead = $firstLineOfGitHead[0];
338 $parts = explode('/', $firstLineOfGitHead);
339 if (empty($parts[2])) {
340 return '';
341 }
342 $currentGitBranch = trim($parts[2]);
343 return $currentGitBranch;
344 }
345 /**
346 * @throws Exception
347 */
348 protected static function rewritePathAppendPiwikInstanceId(string $pathToRewrite, string $leadingPathToAppendHostnameTo) : string
349 {
350 $instanceId = self::getPiwikInstanceId();
351 if (empty($instanceId)) {
352 return $pathToRewrite;
353 }
354 if (($posTmp = strrpos($pathToRewrite, $leadingPathToAppendHostnameTo)) === \false) {
355 throw new Exception("The path {$pathToRewrite} was expected to contain the string {$leadingPathToAppendHostnameTo}");
356 }
357 $tmpToReplace = $leadingPathToAppendHostnameTo . $instanceId . '/';
358 // replace only the latest occurrence (in case path contains twice /tmp)
359 $pathToRewrite = substr_replace($pathToRewrite, $tmpToReplace, $posTmp, strlen($leadingPathToAppendHostnameTo));
360 return $pathToRewrite;
361 }
362 /**
363 * @throws Exception
364 * @return string|false return string or false if not set
365 */
366 public static function getPiwikInstanceId()
367 {
368 // until Matomo is installed, we use hostname as instance_id
369 if (!self::isMatomoInstalled() && \Piwik\Common::isPhpCliMode()) {
370 // enterprise:install use case
371 return \Piwik\Config::getHostname();
372 }
373 // config.ini.php not ready yet, instance_id will not be set
374 if (!\Piwik\Config::getInstance()->existsLocalConfig()) {
375 return \false;
376 }
377 $instanceId = GeneralConfig::getConfigValue('instance_id');
378 if (!empty($instanceId)) {
379 return preg_replace('/[^\\w\\.-]/', '', $instanceId);
380 }
381 // do not rewrite the path as Matomo uses the standard config.ini.php file
382 return \false;
383 }
384 public static function overwritePiwikUrl(string $currentUrl) : void
385 {
386 \Piwik\Option::set(self::OPTION_PIWIK_URL, $currentUrl, $autoLoad = \true);
387 }
388 public static function isHttpsForced() : bool
389 {
390 if (!self::isMatomoInstalled()) {
391 // Only enable this feature after Piwik is already installed
392 return \false;
393 }
394 return \Piwik\Config::getInstance()->General['force_ssl'] == 1;
395 }
396 /**
397 * Note: this config settig is also checked in the InterSites plugin
398 *
399 */
400 public static function isSameFingerprintAcrossWebsites() : bool
401 {
402 return (bool) \Piwik\Config::getInstance()->Tracker['enable_fingerprinting_across_websites'];
403 }
404 }
405