PluginProbe ʕ •ᴥ•ʔ
Matomo Analytics – Powerful, Privacy-First Insights for WordPress / 5.0.7
Matomo Analytics – Powerful, Privacy-First Insights for WordPress v5.0.7
5.13.0 5.12.1 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 / Tracker / Failures.php
matomo / app / core / Tracker Last commit date
Db 2 years ago Handler 2 years ago Visit 2 years ago Action.php 2 years ago ActionPageview.php 2 years ago Cache.php 2 years ago Db.php 2 years ago Failures.php 2 years ago FingerprintSalt.php 2 years ago GoalManager.php 2 years ago Handler.php 2 years ago IgnoreCookie.php 2 years ago LogTable.php 2 years ago Model.php 2 years ago PageUrl.php 2 years ago Request.php 2 years ago RequestProcessor.php 2 years ago RequestSet.php 2 years ago Response.php 2 years ago ScheduledTasksRunner.php 2 years ago Settings.php 2 years ago TableLogAction.php 2 years ago TrackerCodeGenerator.php 2 years ago TrackerConfig.php 2 years ago Visit.php 2 years ago VisitExcluded.php 2 years ago VisitInterface.php 2 years ago Visitor.php 2 years ago VisitorNotFoundInDb.php 2 years ago VisitorRecognizer.php 2 years ago
Failures.php
174 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 namespace Piwik\Tracker;
11
12 use Piwik\Common;
13 use Piwik\Date;
14 use Piwik\Exception\InvalidRequestParameterException;
15 use Piwik\Exception\UnexpectedWebsiteFoundException;
16 use Piwik\Piwik;
17 use Piwik\Site;
18 use Piwik\Db as PiwikDb;
19 use Piwik\Url;
20 class Failures
21 {
22 const CLEANUP_OLD_FAILURES_DAYS = 2;
23 const FAILURE_ID_INVALID_SITE = 1;
24 const FAILURE_ID_NOT_AUTHENTICATED = 2;
25 private $table = 'tracking_failure';
26 private $tablePrefixed;
27 private $now;
28 public function __construct()
29 {
30 $this->tablePrefixed = Common::prefixTable($this->table);
31 }
32 public function setNow(Date $now)
33 {
34 $this->now = $now;
35 }
36 private function getNow()
37 {
38 if (isset($this->now)) {
39 return $this->now;
40 }
41 return Date::now();
42 }
43 public function logFailure($idFailure, \Piwik\Tracker\Request $request)
44 {
45 $isVisitExcluded = $request->getMetadata('CoreHome', 'isVisitExcluded');
46 if ($isVisitExcluded === null) {
47 try {
48 $visitExcluded = new \Piwik\Tracker\VisitExcluded($request);
49 $isVisitExcluded = $visitExcluded->isExcluded();
50 } catch (InvalidRequestParameterException $e) {
51 // we ignore this error and assume visit is not excluded... happens eg when using `cip` and request was
52 // not authenticated...
53 $isVisitExcluded = false;
54 }
55 }
56 if ($isVisitExcluded) {
57 return;
58 }
59 $idSite = (int) $request->getIdSiteUnverified();
60 $idFailure = (int) $idFailure;
61 if ($idSite > 9999999 || $idSite < 0 || $this->hasLoggedFailure($idSite, $idFailure)) {
62 return;
63 // we prevent creating huge amount of entries in the cache
64 }
65 $params = $this->getParamsWithTokenAnonymized($request);
66 $sql = sprintf('INSERT INTO %s (`idsite`, `idfailure`, `date_first_occurred`, `request_url`) VALUES(?,?,?,?) ON DUPLICATE KEY UPDATE idsite=idsite;', $this->tablePrefixed);
67 PiwikDb::get()->query($sql, array($idSite, $idFailure, $this->getNow()->getDatetime(), http_build_query($params)));
68 }
69 private function hasLoggedFailure($idSite, $idFailure)
70 {
71 $sql = sprintf('SELECT idsite FROM %s WHERE idsite = ? and idfailure = ?', $this->tablePrefixed);
72 $row = PiwikDb::fetchRow($sql, array($idSite, $idFailure));
73 return !empty($row);
74 }
75 private function getParamsWithTokenAnonymized(\Piwik\Tracker\Request $request)
76 {
77 // eg if there is a typo in the token auth we want to replace it as well to not accidentally leak a token
78 // eg imagine a super user tries to issue an API request for a site and sending the wrong parameter for a token...
79 // an admin may have view access for this and can see the super users token
80 $token = $request->getTokenAuth();
81 $params = $request->getRawParams();
82 foreach (array('token_auth', 'token', 'tokenauth', 'token__auth') as $key) {
83 if (isset($params[$key])) {
84 $params[$key] = '__TOKEN_AUTH__';
85 }
86 }
87 foreach ($params as $key => $value) {
88 if (!empty($token) && $value === $token) {
89 $params[$key] = '__TOKEN_AUTH__';
90 // user accidentally posted the token in a wrong field
91 } elseif (!empty($value) && is_string($value) && mb_strlen($value) >= 29 && mb_strlen($value) <= 36 && ctype_xdigit($value)) {
92 $params[$key] = '__TOKEN_AUTH__';
93 // user maybe posted a token in a different field... it looks like it might be a token
94 }
95 }
96 return $params;
97 }
98 public function removeFailuresOlderThanDays($days)
99 {
100 $minutesAgo = $this->getNow()->subDay($days)->getDatetime();
101 PiwikDb::query(sprintf('DELETE FROM %s WHERE date_first_occurred < ?', $this->tablePrefixed), array($minutesAgo));
102 }
103 public function getAllFailures()
104 {
105 $failures = PiwikDb::fetchAll(sprintf('SELECT * FROM %s', $this->tablePrefixed));
106 return $this->enrichFailures($failures);
107 }
108 public function getFailuresForSites($idSites)
109 {
110 if (empty($idSites)) {
111 return array();
112 }
113 $idSites = array_map('intval', $idSites);
114 $idSites = implode(',', $idSites);
115 $failures = PiwikDb::fetchAll(sprintf('SELECT * FROM %s WHERE idsite IN (%s)', $this->tablePrefixed, $idSites));
116 return $this->enrichFailures($failures);
117 }
118 public function deleteTrackingFailure($idSite, $idFailure)
119 {
120 PiwikDb::query(sprintf('DELETE FROM %s WHERE idsite = ? and idfailure = ?', $this->tablePrefixed), array($idSite, $idFailure));
121 }
122 public function deleteTrackingFailures($idSites)
123 {
124 if (!empty($idSites)) {
125 $idSites = array_map('intval', $idSites);
126 $idSites = implode(',', $idSites);
127 PiwikDb::query(sprintf('DELETE FROM %s WHERE idsite IN(%s)', $this->tablePrefixed, $idSites));
128 }
129 }
130 public function deleteAllTrackingFailures()
131 {
132 PiwikDb::query(sprintf('DELETE FROM %s', $this->tablePrefixed));
133 }
134 private function enrichFailures($failures)
135 {
136 foreach ($failures as &$failure) {
137 try {
138 $failure['site_name'] = Site::getNameFor($failure['idsite']);
139 } catch (UnexpectedWebsiteFoundException $e) {
140 $failure['site_name'] = Piwik::translate('General_Unknown');
141 }
142 $failure['pretty_date_first_occurred'] = Date::factory($failure['date_first_occurred'])->getLocalized(Date::DATETIME_FORMAT_SHORT);
143 parse_str($failure['request_url'], $params);
144 if (empty($params['url'])) {
145 $params['url'] = ' ';
146 // workaround it using the default provider in request constructor
147 }
148 $request = new \Piwik\Tracker\Request($params);
149 $failure['url'] = trim($request->getParam('url'));
150 $failure['problem'] = '';
151 $failure['solution'] = '';
152 $failure['solution_url'] = '';
153 switch ($failure['idfailure']) {
154 case self::FAILURE_ID_INVALID_SITE:
155 $failure['problem'] = Piwik::translate('CoreAdminHome_TrackingFailureInvalidSiteProblem');
156 $failure['solution'] = Piwik::translate('CoreAdminHome_TrackingFailureInvalidSiteSolution');
157 $failure['solution_url'] = Url::addCampaignParametersToMatomoLink('https://matomo.org/faq/how-to/faq_30838/');
158 break;
159 case self::FAILURE_ID_NOT_AUTHENTICATED:
160 $failure['problem'] = Piwik::translate('CoreAdminHome_TrackingFailureAuthenticationProblem');
161 $failure['solution'] = Piwik::translate('CoreAdminHome_TrackingFailureAuthenticationSolution');
162 $failure['solution_url'] = Url::addCampaignParametersToMatomoLink('https://matomo.org/faq/how-to/faq_30835/');
163 break;
164 }
165 }
166 /**
167 * @ignore
168 * internal use only
169 */
170 Piwik::postEvent('Tracking.makeFailuresHumanReadable', array(&$failures));
171 return $failures;
172 }
173 }
174