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