PluginProbe ʕ •ᴥ•ʔ
Matomo Analytics – Powerful, Privacy-First Insights for WordPress / 4.0.2
Matomo Analytics – Powerful, Privacy-First Insights for WordPress v4.0.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 / Config.php
matomo / app / core Last commit date
API 5 years ago Access 5 years ago Application 5 years ago Archive 5 years ago ArchiveProcessor 5 years ago Archiver 5 years ago AssetManager 5 years ago Auth 5 years ago Category 5 years ago CliMulti 5 years ago Columns 5 years ago Composer 5 years ago Concurrency 5 years ago Config 5 years ago Container 5 years ago CronArchive 5 years ago DataAccess 5 years ago DataFiles 5 years ago DataTable 5 years ago Db 5 years ago DeviceDetector 5 years ago Email 5 years ago Exception 5 years ago Http 5 years ago Intl 5 years ago Mail 5 years ago Measurable 5 years ago Menu 5 years ago Metrics 5 years ago Notification 5 years ago Period 5 years ago Plugin 5 years ago ProfessionalServices 5 years ago Report 5 years ago ReportRenderer 5 years ago Scheduler 5 years ago Segment 5 years ago Session 5 years ago Settings 5 years ago Tracker 5 years ago Translation 5 years ago UpdateCheck 5 years ago Updater 5 years ago Updates 5 years ago Validators 5 years ago View 5 years ago ViewDataTable 5 years ago Visualization 5 years ago Widget 5 years ago .htaccess 6 years ago Access.php 5 years ago Archive.php 5 years ago ArchiveProcessor.php 5 years ago AssetManager.php 5 years ago Auth.php 5 years ago AuthResult.php 5 years ago BaseFactory.php 5 years ago Cache.php 5 years ago CacheId.php 5 years ago CliMulti.php 5 years ago Common.php 5 years ago Config.php 5 years ago Console.php 5 years ago Context.php 5 years ago Cookie.php 5 years ago CronArchive.php 5 years ago DataArray.php 5 years ago DataTable.php 5 years ago Date.php 5 years ago Db.php 5 years ago DbHelper.php 5 years ago Development.php 5 years ago ErrorHandler.php 5 years ago EventDispatcher.php 5 years ago ExceptionHandler.php 5 years ago FileIntegrity.php 5 years ago Filechecks.php 5 years ago Filesystem.php 5 years ago FrontController.php 5 years ago Http.php 5 years ago IP.php 5 years ago Log.php 5 years ago LogDeleter.php 5 years ago Mail.php 5 years ago Metrics.php 5 years ago NoAccessException.php 5 years ago Nonce.php 5 years ago Notification.php 5 years ago NumberFormatter.php 5 years ago Option.php 5 years ago Period.php 5 years ago Piwik.php 5 years ago Plugin.php 5 years ago Profiler.php 5 years ago ProxyHeaders.php 5 years ago ProxyHttp.php 5 years ago QuickForm2.php 5 years ago RankingQuery.php 5 years ago ReportRenderer.php 5 years ago Segment.php 5 years ago Sequence.php 5 years ago Session.php 5 years ago SettingsPiwik.php 5 years ago SettingsServer.php 5 years ago Singleton.php 5 years ago Site.php 5 years ago TCPDF.php 5 years ago Theme.php 5 years ago Timer.php 5 years ago Tracker.php 5 years ago Twig.php 5 years ago Unzip.php 5 years ago UpdateCheck.php 5 years ago Updater.php 5 years ago UpdaterErrorException.php 5 years ago Updates.php 5 years ago Url.php 5 years ago UrlHelper.php 5 years ago Version.php 5 years ago View.php 5 years ago bootstrap.php 5 years ago dispatch.php 5 years ago testMinimumPhpVersion.php 5 years ago
Config.php
454 lines
1 <?php
2 /**
3 * Matomo - free/libre analytics platform
4 *
5 * @link https://matomo.org
6 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
7 *
8 */
9
10 namespace Piwik;
11
12 use Exception;
13 use Piwik\Application\Kernel\GlobalSettingsProvider;
14 use Piwik\Container\StaticContainer;
15 use Piwik\Exception\MissingFilePermissionException;
16 use Piwik\ProfessionalServices\Advertising;
17
18 /**
19 * Singleton that provides read & write access to Piwik's INI configuration.
20 *
21 * This class reads and writes to the `config/config.ini.php` file. If config
22 * options are missing from that file, this class will look for their default
23 * values in `config/global.ini.php`.
24 *
25 * ### Examples
26 *
27 * **Getting a value:**
28 *
29 * // read the minimum_memory_limit option under the [General] section
30 * $minValue = Config::getInstance()->General['minimum_memory_limit'];
31 *
32 * **Setting a value:**
33 *
34 * // set the minimum_memory_limit option
35 * Config::getInstance()->General['minimum_memory_limit'] = 256;
36 * Config::getInstance()->forceSave();
37 *
38 * **Setting an entire section:**
39 *
40 * Config::getInstance()->MySection = array('myoption' => 1);
41 * Config::getInstance()->forceSave();
42 */
43 class Config
44 {
45 const DEFAULT_LOCAL_CONFIG_PATH = '/config/config.ini.php';
46 const DEFAULT_COMMON_CONFIG_PATH = '/config/common.config.ini.php';
47 const DEFAULT_GLOBAL_CONFIG_PATH = '/config/global.ini.php';
48
49 /**
50 * @var boolean
51 */
52 protected $doNotWriteConfigInTests = false;
53
54 /**
55 * @var GlobalSettingsProvider
56 */
57 protected $settings;
58
59 /**
60 * @return Config
61 */
62 public static function getInstance()
63 {
64 return StaticContainer::get('Piwik\Config');
65 }
66
67 public function __construct(GlobalSettingsProvider $settings)
68 {
69 $this->settings = $settings;
70 }
71
72 /**
73 * Returns the path to the local config file used by this instance.
74 *
75 * @return string
76 */
77 public function getLocalPath()
78 {
79 return $this->settings->getPathLocal();
80 }
81
82 /**
83 * Returns the path to the global config file used by this instance.
84 *
85 * @return string
86 */
87 public function getGlobalPath()
88 {
89 return $this->settings->getPathGlobal();
90 }
91
92 /**
93 * Returns the path to the common config file used by this instance.
94 *
95 * @return string
96 */
97 public function getCommonPath()
98 {
99 return $this->settings->getPathCommon();
100 }
101
102 /**
103 * Returns absolute path to the global configuration file
104 *
105 * @return string
106 */
107 public static function getGlobalConfigPath()
108 {
109 return PIWIK_DOCUMENT_ROOT . self::DEFAULT_GLOBAL_CONFIG_PATH;
110 }
111
112 /**
113 * Returns absolute path to the common configuration file.
114 *
115 * @return string
116 */
117 public static function getCommonConfigPath()
118 {
119 return PIWIK_USER_PATH . self::DEFAULT_COMMON_CONFIG_PATH;
120 }
121
122 /**
123 * Returns default absolute path to the local configuration file.
124 *
125 * @return string
126 */
127 public static function getDefaultLocalConfigPath()
128 {
129 return PIWIK_USER_PATH . self::DEFAULT_LOCAL_CONFIG_PATH;
130 }
131
132 /**
133 * Returns absolute path to the local configuration file
134 *
135 * @return string
136 */
137 public static function getLocalConfigPath()
138 {
139 if (!empty($GLOBALS['CONFIG_INI_PATH_RESOLVER']) && is_callable($GLOBALS['CONFIG_INI_PATH_RESOLVER'])) {
140 return call_user_func($GLOBALS['CONFIG_INI_PATH_RESOLVER']);
141 }
142
143 $path = self::getByDomainConfigPath();
144 if ($path) {
145 return $path;
146 }
147 return self::getDefaultLocalConfigPath();
148 }
149
150 private static function getLocalConfigInfoForHostname($hostname)
151 {
152 if (!$hostname) {
153 return array();
154 }
155
156 // Remove any port number to get actual hostname
157 $hostname = Url::getHostSanitized($hostname);
158 $standardConfigName = 'config.ini.php';
159 $perHostFilename = $hostname . '.' . $standardConfigName;
160 $pathDomainConfig = PIWIK_USER_PATH . '/config/' . $perHostFilename;
161 $pathDomainMiscUser = PIWIK_USER_PATH . '/misc/user/' . $hostname . '/' . $standardConfigName;
162
163 $locations = array(
164 array('file' => $perHostFilename, 'path' => $pathDomainConfig),
165 array('file' => $standardConfigName, 'path' => $pathDomainMiscUser)
166 );
167
168 return $locations;
169 }
170
171 public function getConfigHostnameIfSet()
172 {
173 if ($this->getByDomainConfigPath() === false) {
174 return false;
175 }
176 return $this->getHostname();
177 }
178
179 public function getClientSideOptions()
180 {
181 $general = $this->General;
182
183 return array(
184 'action_url_category_delimiter' => $general['action_url_category_delimiter'],
185 'action_title_category_delimiter' => $general['action_title_category_delimiter'],
186 'autocomplete_min_sites' => $general['autocomplete_min_sites'],
187 'datatable_export_range_as_day' => $general['datatable_export_range_as_day'],
188 'datatable_row_limits' => $this->getDatatableRowLimits(),
189 'are_ads_enabled' => Advertising::isAdsEnabledInConfig($general)
190 );
191 }
192
193 /**
194 * @param $general
195 * @return mixed
196 */
197 private function getDatatableRowLimits()
198 {
199 $limits = $this->General['datatable_row_limits'];
200 $limits = explode(",", $limits);
201 $limits = array_map('trim', $limits);
202 return $limits;
203 }
204
205 public static function getByDomainConfigPath()
206 {
207 $host = self::getHostname();
208 $hostConfigs = self::getLocalConfigInfoForHostname($host);
209
210 foreach ($hostConfigs as $hostConfig) {
211 if (Filesystem::isValidFilename($hostConfig['file'])
212 && file_exists($hostConfig['path'])
213 ) {
214 return $hostConfig['path'];
215 }
216 }
217
218 return false;
219 }
220
221 /**
222 * Returns the hostname of the current request (without port number)
223 *
224 * @return string
225 */
226 public static function getHostname()
227 {
228 // Check trusted requires config file which is not ready yet
229 $host = Url::getHost($checkIfTrusted = false);
230
231 // Remove any port number to get actual hostname
232 $host = Url::getHostSanitized($host);
233
234 return $host;
235 }
236
237 /**
238 * If set, Piwik will use the hostname config no matter if it exists or not. Useful for instance if you want to
239 * create a new hostname config:
240 *
241 * $config = Config::getInstance();
242 * $config->forceUsageOfHostnameConfig('piwik.example.com');
243 * $config->save();
244 *
245 * @param string $hostname eg piwik.example.com
246 * @param string $preferredPath If there are different paths for the config that can be used, eg /config/* and /misc/user/*,
247 * and a preferred path is given, then the config path must contain the preferred path.
248 * @return string
249 * @throws \Exception In case the domain contains not allowed characters
250 * @internal
251 */
252 public function forceUsageOfLocalHostnameConfig($hostname, $preferredPath = null)
253 {
254 $hostConfigs = self::getLocalConfigInfoForHostname($hostname);
255 $fileNames = '';
256
257 foreach ($hostConfigs as $hostConfig) {
258 if (count($hostConfigs) > 1
259 && $preferredPath
260 && strpos($hostConfig['path'], $preferredPath) === false) {
261 continue;
262 }
263
264 $filename = $hostConfig['file'];
265 $fileNames .= $filename . ' ';
266
267 if (Filesystem::isValidFilename($filename)) {
268 $pathLocal = $hostConfig['path'];
269
270 try {
271 $this->reload($pathLocal);
272 } catch (Exception $ex) {
273 // pass (not required for local file to exist at this point)
274 }
275
276 return $pathLocal;
277 }
278 }
279
280 throw new Exception('Matomo domain is not a valid looking hostname (' . trim($fileNames) . ').');
281 }
282
283 /**
284 * Returns `true` if the local configuration file is writable.
285 *
286 * @return bool
287 */
288 public function isFileWritable()
289 {
290 return is_writable($this->settings->getPathLocal());
291 }
292
293 /**
294 * Reloads config data from disk.
295 *
296 * @throws \Exception if the global config file is not found and this is a tracker request, or
297 * if the local config file is not found and this is NOT a tracker request.
298 */
299 protected function reload($pathLocal = null, $pathGlobal = null, $pathCommon = null)
300 {
301 $this->settings->reload($pathGlobal, $pathLocal, $pathCommon);
302 }
303
304 public function existsLocalConfig()
305 {
306 return is_readable($this->getLocalPath());
307 }
308
309 public function deleteLocalConfig()
310 {
311 $configLocal = $this->getLocalPath();
312
313 if(file_exists($configLocal)){
314 @unlink($configLocal);
315 }
316 }
317
318 /**
319 * Returns a configuration value or section by name.
320 *
321 * @param string $name The value or section name.
322 * @return string|array The requested value requested. Returned by reference.
323 * @throws Exception If the value requested not found in either `config.ini.php` or
324 * `global.ini.php`.
325 * @api
326 */
327 public function &__get($name)
328 {
329 $section =& $this->settings->getIniFileChain()->get($name);
330 return $section;
331 }
332
333 /**
334 * @api
335 */
336 public function getFromGlobalConfig($name)
337 {
338 return $this->settings->getIniFileChain()->getFrom($this->getGlobalPath(), $name);
339 }
340
341 /**
342 * @api
343 */
344 public function getFromCommonConfig($name)
345 {
346 return $this->settings->getIniFileChain()->getFrom($this->getCommonPath(), $name);
347 }
348
349 /**
350 * @api
351 */
352 public function getFromLocalConfig($name)
353 {
354 return $this->settings->getIniFileChain()->getFrom($this->getLocalPath(), $name);
355 }
356
357 /**
358 * Sets a configuration value or section.
359 *
360 * @param string $name This section name or value name to set.
361 * @param mixed $value
362 * @api
363 */
364 public function __set($name, $value)
365 {
366 $this->settings->getIniFileChain()->set($name, $value);
367 }
368
369 /**
370 * Dump config
371 *
372 * @return string|null
373 * @throws \Exception
374 */
375 public function dumpConfig()
376 {
377 $chain = $this->settings->getIniFileChain();
378
379 $header = "; <?php exit; ?> DO NOT REMOVE THIS LINE\n";
380 $header .= "; file automatically generated or modified by Matomo; you can manually override the default values in global.ini.php by redefining them in this file.\n";
381 return $chain->dumpChanges($header);
382 }
383
384 /**
385 * Write user configuration file
386 *
387 * @throws \Exception if config file not writable
388 */
389 protected function writeConfig()
390 {
391 $output = $this->dumpConfig();
392 if ($output !== null
393 && $output !== false
394 ) {
395 $localPath = $this->getLocalPath();
396
397 if ($this->doNotWriteConfigInTests) {
398 // simulate whether it would be successful
399 $success = is_writable($localPath);
400 } else {
401 $success = @file_put_contents($localPath, $output, LOCK_EX);
402 }
403
404 if ($success === false) {
405 throw $this->getConfigNotWritableException();
406 }
407
408 $this->settings->getIniFileChain()->deleteConfigCache();
409
410 /**
411 * Triggered when a INI config file is changed on disk.
412 *
413 * @param string $localPath Absolute path to the changed file on the server.
414 */
415 Piwik::postEvent('Core.configFileChanged', [$localPath]);
416 }
417 }
418
419 /**
420 * Writes the current configuration to the **config.ini.php** file. Only writes options whose
421 * values are different from the default.
422 *
423 * @api
424 */
425 public function forceSave()
426 {
427 $this->writeConfig();
428 }
429
430 /**
431 * @throws \Exception
432 */
433 public function getConfigNotWritableException()
434 {
435 $path = "config/" . basename($this->getLocalPath());
436 return new MissingFilePermissionException(Piwik::translate('General_ConfigFileIsNotWritable', array("(" . $path . ")", "")));
437 }
438
439 /**
440 * Convenience method for setting settings in a single section. Will set them in a new array first
441 * to be compatible with certain PHP versions.
442 *
443 * @param string $sectionName Section name.
444 * @param string $name The setting name.
445 * @param mixed $value The setting value to set.
446 */
447 public static function setSetting($sectionName, $name, $value)
448 {
449 $section = self::getInstance()->$sectionName;
450 $section[$name] = $value;
451 self::getInstance()->$sectionName = $section;
452 }
453 }
454