PluginProbe ʕ •ᴥ•ʔ
Matomo Analytics – Powerful, Privacy-First Insights for WordPress / 5.12.1
Matomo Analytics – Powerful, Privacy-First Insights for WordPress v5.12.1
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 / Period / Factory.php
matomo / app / core / Period Last commit date
Day.php 2 months ago Factory.php 2 weeks ago Month.php 2 months ago PeriodValidator.php 2 years ago Range.php 2 months ago Week.php 2 months ago Year.php 2 weeks ago
Factory.php
195 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\Period;
10
11 use Exception;
12 use Piwik\Container\StaticContainer;
13 use Piwik\Date;
14 use Piwik\Period;
15 use Piwik\Piwik;
16 use Piwik\Plugin;
17 /**
18 * Creates Period instances using the values used for the 'period' and 'date'
19 * query parameters.
20 *
21 * ## Custom Periods
22 *
23 * Plugins can define their own period factories to define new period types, in addition
24 * to "day", "week", "month", "year" and "range".
25 *
26 * To define a new period type:
27 *
28 * 1. create a new period class that derives from {@see \Piwik\Period}.
29 * 2. extend this class in a new PeriodFactory class and put it in /path/to/piwik/plugins/MyPlugin/PeriodFactory.php
30 *
31 * Period name collisions:
32 *
33 * If two plugins try to handle the same period label, the first one encountered will
34 * be used. In other words, avoid using another plugin's period label.
35 */
36 abstract class Factory
37 {
38 public function __construct()
39 {
40 // empty
41 }
42 /**
43 * Returns true if this factory should handle the period/date string combination.
44 *
45 * @return bool
46 */
47 public abstract function shouldHandle($strPeriod, $strDate);
48 /**
49 * Creates a period using the value of the 'date' query parameter.
50 *
51 * @param string $strPeriod
52 * @param string|Date $date
53 * @param string $timezone
54 * @return Period
55 */
56 public abstract function make($strPeriod, $date, $timezone);
57 /**
58 * Creates a new Period instance with a period ID and {@link Date} instance.
59 *
60 * @param string $period `"day"`, `"week"`, `"month"`, `"year"`, `"range"`.
61 * @param Date|string $date A date within the period or the range of dates.
62 * @param string $timezone Optional timezone that will be used only when $period is 'range' or $date is 'last|previous'
63 * @return \Piwik\Period
64 */
65 public static function build($period, $date, $timezone = 'UTC')
66 {
67 self::checkPeriodIsEnabled($period);
68 if (is_string($date)) {
69 [$period, $date] = self::convertRangeToDateIfNeeded($period, $date);
70 if (Period::isMultiplePeriod($date, $period) || $period == 'range') {
71 return new \Piwik\Period\Range($period, $date, $timezone);
72 }
73 $dateObject = Date::factory($date);
74 } elseif ($date instanceof Date) {
75 $dateObject = $date;
76 } else {
77 throw new \Exception("Invalid date supplied to Period\\Factory::build(): " . gettype($date));
78 }
79 switch ($period) {
80 case 'day':
81 return new \Piwik\Period\Day($dateObject);
82 case 'week':
83 return new \Piwik\Period\Week($dateObject);
84 case 'month':
85 return new \Piwik\Period\Month($dateObject);
86 case 'year':
87 return new \Piwik\Period\Year($dateObject);
88 }
89 $customPeriodFactories = Plugin\Manager::getInstance()->findComponents('PeriodFactory', self::class);
90 foreach ($customPeriodFactories as $customPeriodFactoryClass) {
91 $customPeriodFactory = StaticContainer::get($customPeriodFactoryClass);
92 if ($customPeriodFactory->shouldHandle($period, $date)) {
93 return $customPeriodFactory->make($period, $date, $timezone);
94 }
95 }
96 throw new \Exception("Don't know how to create a '{$period}' period! (date = {$date})");
97 }
98 public static function checkPeriodIsEnabled($period)
99 {
100 if (!self::isPeriodEnabledForAPI($period)) {
101 self::throwExceptionInvalidPeriod($period);
102 }
103 }
104 /**
105 * @param $strPeriod
106 * @throws \Exception
107 */
108 private static function throwExceptionInvalidPeriod($strPeriod)
109 {
110 $periods = self::getPeriodsEnabledForAPI();
111 $periods = implode(", ", $periods);
112 $message = Piwik::translate('General_ExceptionInvalidPeriod', array($strPeriod, $periods));
113 throw new Exception($message);
114 }
115 private static function convertRangeToDateIfNeeded($period, $date)
116 {
117 if (is_string($period) && is_string($date) && $period === 'range') {
118 $dates = explode(',', $date);
119 if (count($dates) === 2 && $dates[0] === $dates[1]) {
120 $period = 'day';
121 $date = $dates[0];
122 }
123 }
124 return array($period, $date);
125 }
126 /**
127 * Creates a Period instance using a period, date and timezone.
128 *
129 * @param string $timezone The timezone of the date. Only used if `$date` is `'now'`, `'today'`,
130 * `'yesterday'` or `'yesterdaySameTime'`.
131 * @param string $period The period string: `"day"`, `"week"`, `"month"`, `"year"`, `"range"`.
132 * @param string|Date $date The date or date range string. Can be a special value including
133 * `'now'`, `'today'`, `'yesterday'`, `'yesterdaySameTime'`.
134 * @return \Piwik\Period
135 */
136 public static function makePeriodFromQueryParams($timezone, $period, $date)
137 {
138 if (empty($timezone)) {
139 $timezone = 'UTC';
140 }
141 [$period, $date] = self::convertRangeToDateIfNeeded($period, $date);
142 if ($period == 'range') {
143 self::checkPeriodIsEnabled('range');
144 $oPeriod = new \Piwik\Period\Range('range', $date, $timezone, Date::factory('today', $timezone));
145 } else {
146 if (!$date instanceof Date) {
147 if (preg_match('/^(now|today|yesterday|yesterdaySameTime|last[ -]?(?:week|month|year))$/i', $date)) {
148 $date = Date::factoryInTimezone($date, $timezone);
149 }
150 $date = Date::factory($date);
151 }
152 $oPeriod = \Piwik\Period\Factory::build($period, $date);
153 }
154 return $oPeriod;
155 }
156 /**
157 * @param $period
158 * @return bool
159 */
160 public static function isPeriodEnabledForAPI($period)
161 {
162 $periodValidator = new \Piwik\Period\PeriodValidator();
163 return $periodValidator->isPeriodAllowedForAPI($period);
164 }
165 /**
166 * @return array
167 */
168 public static function getPeriodsEnabledForAPI()
169 {
170 $periodValidator = new \Piwik\Period\PeriodValidator();
171 return $periodValidator->getPeriodsAllowedForAPI();
172 }
173 public static function isAnyLowerPeriodDisabledForAPI($periodLabel)
174 {
175 $parentPeriod = null;
176 switch ($periodLabel) {
177 case 'week':
178 $parentPeriod = 'day';
179 break;
180 case 'month':
181 $parentPeriod = 'week';
182 break;
183 case 'year':
184 $parentPeriod = 'month';
185 break;
186 default:
187 break;
188 }
189 if ($parentPeriod === null) {
190 return \false;
191 }
192 return !self::isPeriodEnabledForAPI($parentPeriod) || self::isAnyLowerPeriodDisabledForAPI($parentPeriod);
193 }
194 }
195