Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/matomo-org/matomo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'core/Period/Range.php')
-rw-r--r--core/Period/Range.php760
1 files changed, 360 insertions, 400 deletions
diff --git a/core/Period/Range.php b/core/Period/Range.php
index b77ffec9fa..38dd9b350e 100644
--- a/core/Period/Range.php
+++ b/core/Period/Range.php
@@ -1,10 +1,10 @@
<?php
/**
* Piwik - Open source web analytics
- *
+ *
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
- *
+ *
* @category Piwik
* @package Piwik
*/
@@ -17,402 +17,362 @@
*/
class Piwik_Period_Range extends Piwik_Period
{
- protected $label = 'range';
-
- public function __construct( $strPeriod, $strDate, $timezone = 'UTC', $today = false )
- {
- $this->strPeriod = $strPeriod;
- $this->strDate = $strDate;
- $this->defaultEndDate = null;
- $this->timezone = $timezone;
- if($today === false)
- {
- $today = Piwik_Date::factory('today', $this->timezone);
- }
- $this->today = $today;
- }
-
- /**
- * Returns the current period as a localized short string
- *
- * @return string
- */
- public function getLocalizedShortString()
- {
- //"30 Dec 08 - 26 Feb 09"
- $dateStart = $this->getDateStart();
- $dateEnd = $this->getDateEnd();
- $template = Piwik_Translate('CoreHome_ShortDateFormatWithYear');
- $shortDateStart = $dateStart->getLocalized($template);
- $shortDateEnd = $dateEnd->getLocalized($template);
- $out = "$shortDateStart - $shortDateEnd";
- return $out;
- }
-
- /**
- * Returns the current period as a localized long string
- *
- * @return string
- */
- public function getLocalizedLongString()
- {
- return $this->getLocalizedShortString();
- }
-
- /**
- * Returns the start date of the period
- *
- * @return Piwik_Date
- * @throws Exception
- */
- public function getDateStart()
- {
- $dateStart = parent::getDateStart();
- if(empty($dateStart))
- {
- throw new Exception("Specified date range is invalid.");
- }
- return $dateStart;
- }
-
- /**
- * Returns the current period as a string
- *
- * @return string
- */
- public function getPrettyString()
- {
- $out = Piwik_Translate('General_DateRangeFromTo', array($this->getDateStart()->toString(), $this->getDateEnd()->toString()));
- return $out;
- }
-
- /**
- *
- * @param string $period
- * @param Piwik_Date $date
- * @param int $n
- * @throws Exception
- * @return Piwik_Date
- */
- static public function removePeriod( $period, Piwik_Date $date, $n )
- {
- switch($period)
- {
- case 'day':
- $startDate = $date->subDay( $n );
- break;
-
- case 'week':
- $startDate = $date->subDay( $n * 7 );
- break;
-
- case 'month':
- $startDate = $date->subMonth( $n );
- break;
-
- case 'year':
- $startDate = $date->subMonth( 12 * $n );
- break;
- default:
- throw new Exception('The period parameter is invalid');
- break;
- }
- return $startDate;
- }
-
- protected function getMaxN($lastN)
- {
- switch($this->strPeriod)
- {
- case 'day':
- $lastN = min( $lastN, 5*365 );
- break;
-
- case 'week':
- $lastN = min( $lastN, 10*52 );
- break;
-
- case 'month':
- $lastN = min( $lastN, 10*12 );
- break;
-
- case 'year':
- $lastN = min( $lastN, 10 );
- break;
- }
- return $lastN;
- }
-
- /**
- * Sets the default end date of the period
- *
- * @param Piwik_Date $oDate
- */
- public function setDefaultEndDate( Piwik_Date $oDate)
- {
- $this->defaultEndDate = $oDate;
- }
-
- /**
- * Generates the subperiods
- *
- * @throws Exception
- */
- protected function generate()
- {
- if($this->subperiodsProcessed)
- {
- return;
- }
- parent::generate();
-
- if(preg_match('/(last|previous)([0-9]*)/', $this->strDate, $regs))
- {
- $lastN = $regs[2];
- $lastOrPrevious = $regs[1];
- if(!is_null($this->defaultEndDate))
- {
- $defaultEndDate = $this->defaultEndDate;
- }
- else
- {
- $defaultEndDate = Piwik_Date::factory('now', $this->timezone);
- }
-
- $period = $this->strPeriod;
- if($period == 'range')
- {
- $period = 'day';
- }
-
- if($lastOrPrevious == 'last')
- {
- $endDate = $defaultEndDate;
- }
- elseif($lastOrPrevious == 'previous')
- {
- $endDate = self::removePeriod($period, $defaultEndDate, 1);
- }
-
- $lastN = $this->getMaxN($lastN);
-
- // last1 means only one result ; last2 means 2 results so we remove only 1 to the days/weeks/etc
- $lastN--;
- $lastN = abs($lastN);
-
- $startDate = self::removePeriod($period, $endDate, $lastN);
- }
- elseif( $dateRange = Piwik_Period_Range::parseDateRange($this->strDate) )
- {
- $strDateStart = $dateRange[1];
- $strDateEnd = $dateRange[2];
- $startDate = Piwik_Date::factory($strDateStart);
-
- if($strDateEnd == 'today')
- {
- $strDateEnd = 'now';
- }
- elseif($strDateEnd == 'yesterday')
- {
- $strDateEnd = 'yesterdaySameTime';
- }
- // we set the timezone in the Date object only if the date is relative eg. 'today', 'yesterday', 'now'
- $timezone = null;
- if(strpos($strDateEnd, '-') === false)
- {
- $timezone = $this->timezone;
- }
- $endDate = Piwik_Date::factory($strDateEnd, $timezone);
- }
- else
- {
- throw new Exception(Piwik_TranslateException('General_ExceptionInvalidDateRange', array($this->strDate, ' \'lastN\', \'previousN\', \'YYYY-MM-DD,YYYY-MM-DD\'')));
- }
- if($this->strPeriod != 'range')
- {
- $this->fillArraySubPeriods($startDate, $endDate, $this->strPeriod);
- return;
- }
- $this->processOptimalSubperiods($startDate, $endDate);
- // When period=range, we want End Date to be the actual specified end date,
- // rather than the end of the month / week / whatever is used for processing this range
- $this->endDate = $endDate;
- }
-
- /**
- * Given a date string, returns false if not a date range,
- * or returns the array containing date start, date end
- *
- * @param string $dateString
- * @return mixed array(1 => dateStartString, 2 => dateEndString ) or false if the input was not a date range
- */
- static public function parseDateRange($dateString)
- {
- $matched = preg_match('/^([0-9]{4}-[0-9]{1,2}-[0-9]{1,2}),(([0-9]{4}-[0-9]{1,2}-[0-9]{1,2})|today|now|yesterday)$/D', trim($dateString), $regs);
- if(empty($matched))
- {
- return false;
- }
- return $regs;
- }
-
- protected $endDate = null;
-
- /**
- * Returns the end date of the period
- *
- * @return null|Piwik_Date
- */
- public function getDateEnd()
- {
- if(!is_null($this->endDate))
- {
- return $this->endDate;
- }
- return parent::getDateEnd();
- }
-
- /**
- * Determine which kind of period is best to use
- * See Range.test.php
- *
- * @param $startDate
- * @param $endDate
- */
- protected function processOptimalSubperiods($startDate, $endDate)
- {
- while($startDate->isEarlier($endDate)
- || $startDate == $endDate)
- {
- $endOfPeriod = null;
-
- $month = new Piwik_Period_Month($startDate);
- $endOfMonth = $month->getDateEnd();
- $startOfMonth = $month->getDateStart();
- if($startDate == $startOfMonth
- && ($endOfMonth->isEarlier($endDate)
- || $endOfMonth == $endDate
- || $endOfMonth->isLater($this->today)
- )
- // We don't use the month if
- // the end day is in this month, is before today, and month not finished
- && !($endDate->isEarlier($this->today)
- && $this->today->toString('Y') == $endOfMonth->toString('Y')
- && $this->today->compareMonth($endOfMonth) == 0)
- )
- {
- $this->addSubperiod($month);
- $endOfPeriod = $endOfMonth;
- }
- else
- {
- // From start date,
- // Process end of week
- $week = new Piwik_Period_Week($startDate);
- $startOfWeek = $week->getDateStart();
- $endOfWeek = $week->getDateEnd();
-
- $useMonthsNextIteration = $startDate->addPeriod(2, 'month')->setDay(1)->isEarlier($endDate);
- if($useMonthsNextIteration
- && $endOfWeek->isLater($endOfMonth))
- {
- $this->fillArraySubPeriods($startDate, $endOfMonth, 'day');
- $endOfPeriod = $endOfMonth;
- }
- // If end of this week is later than end date, we use days
- elseif($endOfWeek->isLater($endDate)
- && ($endOfWeek->isEarlier($this->today)
- || $endDate->isEarlier($this->today))
- )
- {
- $this->fillArraySubPeriods($startDate, $endDate, 'day');
- break 1;
- }
- elseif($startOfWeek->isEarlier($startDate)
- && $endOfWeek->isEarlier($this->today))
- {
- $this->fillArraySubPeriods($startDate, $endOfWeek, 'day');
- $endOfPeriod = $endOfWeek;
- }
- else
- {
- $this->addSubperiod($week);
- $endOfPeriod = $endOfWeek;
- }
- }
- $startDate = $endOfPeriod->addDay(1);
- }
- }
-
- /**
- * Adds new subperiods
- *
- * @param Piwik_Date $startDate
- * @param Piwik_Date $endDate
- * @param string $period
- */
- protected function fillArraySubPeriods($startDate, $endDate, $period)
- {
- $arrayPeriods= array();
- $endSubperiod = Piwik_Period::factory($period, $endDate);
- $arrayPeriods[] = $endSubperiod;
-
- // set end date to start of end period since we're comparing against start date.
- $endDate = $endSubperiod->getDateStart();
- while($endDate->isLater($startDate) )
- {
- $endDate = self::removePeriod($period, $endDate, 1);
- $subPeriod = Piwik_Period::factory($period, $endDate);
- $arrayPeriods[] = $subPeriod;
- }
- $arrayPeriods = array_reverse($arrayPeriods);
- foreach($arrayPeriods as $period)
- {
- $this->addSubperiod($period);
- }
- }
-
- /**
- * Returns the date that is one period before the supplied date.
- *
- * @param string $date The date to get the last date of.
- * @param string $period The period to use (either 'day', 'week', 'month', 'year');
- * @return array An array with two elements, a string for the date before $date and
- * a Piwik_Period instance for the period before $date.
- */
- public static function getLastDate( $date = false, $period = false )
- {
- if ($date === false)
- {
- $date = Piwik_Common::getRequestVar('date');
- }
-
- if ($period === false)
- {
- $period = Piwik_Common::getRequestVar('period');
- }
-
- // can't get the last date for range periods & dates that use lastN/previousN
- $strLastDate = false;
- $lastPeriod = false;
- if ($period != 'range' && !preg_match('/(last|previous)([0-9]*)/', $date, $regs))
- {
- if (strpos($date, ',')) // date in the form of 2011-01-01,2011-02-02
- {
- $rangePeriod = new Piwik_Period_Range($period, $date);
-
- $lastStartDate = Piwik_Period_Range::removePeriod($period, $rangePeriod->getDateStart(), $n = 1);
- $lastEndDate = Piwik_Period_Range::removePeriod($period, $rangePeriod->getDateEnd(), $n = 1);
-
- $strLastDate = "$lastStartDate,$lastEndDate";
- }
- else
- {
- $lastPeriod = Piwik_Period_Range::removePeriod($period, Piwik_Date::factory($date), $n = 1);
- $strLastDate = $lastPeriod->toString();
- }
- }
-
- return array($strLastDate, $lastPeriod);
- }
+ protected $label = 'range';
+
+ public function __construct($strPeriod, $strDate, $timezone = 'UTC', $today = false)
+ {
+ $this->strPeriod = $strPeriod;
+ $this->strDate = $strDate;
+ $this->defaultEndDate = null;
+ $this->timezone = $timezone;
+ if ($today === false) {
+ $today = Piwik_Date::factory('today', $this->timezone);
+ }
+ $this->today = $today;
+ }
+
+ /**
+ * Returns the current period as a localized short string
+ *
+ * @return string
+ */
+ public function getLocalizedShortString()
+ {
+ //"30 Dec 08 - 26 Feb 09"
+ $dateStart = $this->getDateStart();
+ $dateEnd = $this->getDateEnd();
+ $template = Piwik_Translate('CoreHome_ShortDateFormatWithYear');
+ $shortDateStart = $dateStart->getLocalized($template);
+ $shortDateEnd = $dateEnd->getLocalized($template);
+ $out = "$shortDateStart - $shortDateEnd";
+ return $out;
+ }
+
+ /**
+ * Returns the current period as a localized long string
+ *
+ * @return string
+ */
+ public function getLocalizedLongString()
+ {
+ return $this->getLocalizedShortString();
+ }
+
+ /**
+ * Returns the start date of the period
+ *
+ * @return Piwik_Date
+ * @throws Exception
+ */
+ public function getDateStart()
+ {
+ $dateStart = parent::getDateStart();
+ if (empty($dateStart)) {
+ throw new Exception("Specified date range is invalid.");
+ }
+ return $dateStart;
+ }
+
+ /**
+ * Returns the current period as a string
+ *
+ * @return string
+ */
+ public function getPrettyString()
+ {
+ $out = Piwik_Translate('General_DateRangeFromTo', array($this->getDateStart()->toString(), $this->getDateEnd()->toString()));
+ return $out;
+ }
+
+ /**
+ *
+ * @param string $period
+ * @param Piwik_Date $date
+ * @param int $n
+ * @throws Exception
+ * @return Piwik_Date
+ */
+ static public function removePeriod($period, Piwik_Date $date, $n)
+ {
+ switch ($period) {
+ case 'day':
+ $startDate = $date->subDay($n);
+ break;
+
+ case 'week':
+ $startDate = $date->subDay($n * 7);
+ break;
+
+ case 'month':
+ $startDate = $date->subMonth($n);
+ break;
+
+ case 'year':
+ $startDate = $date->subMonth(12 * $n);
+ break;
+ default:
+ throw new Exception('The period parameter is invalid');
+ break;
+ }
+ return $startDate;
+ }
+
+ protected function getMaxN($lastN)
+ {
+ switch ($this->strPeriod) {
+ case 'day':
+ $lastN = min($lastN, 5 * 365);
+ break;
+
+ case 'week':
+ $lastN = min($lastN, 10 * 52);
+ break;
+
+ case 'month':
+ $lastN = min($lastN, 10 * 12);
+ break;
+
+ case 'year':
+ $lastN = min($lastN, 10);
+ break;
+ }
+ return $lastN;
+ }
+
+ /**
+ * Sets the default end date of the period
+ *
+ * @param Piwik_Date $oDate
+ */
+ public function setDefaultEndDate(Piwik_Date $oDate)
+ {
+ $this->defaultEndDate = $oDate;
+ }
+
+ /**
+ * Generates the subperiods
+ *
+ * @throws Exception
+ */
+ protected function generate()
+ {
+ if ($this->subperiodsProcessed) {
+ return;
+ }
+ parent::generate();
+
+ if (preg_match('/(last|previous)([0-9]*)/', $this->strDate, $regs)) {
+ $lastN = $regs[2];
+ $lastOrPrevious = $regs[1];
+ if (!is_null($this->defaultEndDate)) {
+ $defaultEndDate = $this->defaultEndDate;
+ } else {
+ $defaultEndDate = Piwik_Date::factory('now', $this->timezone);
+ }
+
+ $period = $this->strPeriod;
+ if ($period == 'range') {
+ $period = 'day';
+ }
+
+ if ($lastOrPrevious == 'last') {
+ $endDate = $defaultEndDate;
+ } elseif ($lastOrPrevious == 'previous') {
+ $endDate = self::removePeriod($period, $defaultEndDate, 1);
+ }
+
+ $lastN = $this->getMaxN($lastN);
+
+ // last1 means only one result ; last2 means 2 results so we remove only 1 to the days/weeks/etc
+ $lastN--;
+ $lastN = abs($lastN);
+
+ $startDate = self::removePeriod($period, $endDate, $lastN);
+ } elseif ($dateRange = Piwik_Period_Range::parseDateRange($this->strDate)) {
+ $strDateStart = $dateRange[1];
+ $strDateEnd = $dateRange[2];
+ $startDate = Piwik_Date::factory($strDateStart);
+
+ if ($strDateEnd == 'today') {
+ $strDateEnd = 'now';
+ } elseif ($strDateEnd == 'yesterday') {
+ $strDateEnd = 'yesterdaySameTime';
+ }
+ // we set the timezone in the Date object only if the date is relative eg. 'today', 'yesterday', 'now'
+ $timezone = null;
+ if (strpos($strDateEnd, '-') === false) {
+ $timezone = $this->timezone;
+ }
+ $endDate = Piwik_Date::factory($strDateEnd, $timezone);
+ } else {
+ throw new Exception(Piwik_TranslateException('General_ExceptionInvalidDateRange', array($this->strDate, ' \'lastN\', \'previousN\', \'YYYY-MM-DD,YYYY-MM-DD\'')));
+ }
+ if ($this->strPeriod != 'range') {
+ $this->fillArraySubPeriods($startDate, $endDate, $this->strPeriod);
+ return;
+ }
+ $this->processOptimalSubperiods($startDate, $endDate);
+ // When period=range, we want End Date to be the actual specified end date,
+ // rather than the end of the month / week / whatever is used for processing this range
+ $this->endDate = $endDate;
+ }
+
+ /**
+ * Given a date string, returns false if not a date range,
+ * or returns the array containing date start, date end
+ *
+ * @param string $dateString
+ * @return mixed array(1 => dateStartString, 2 => dateEndString ) or false if the input was not a date range
+ */
+ static public function parseDateRange($dateString)
+ {
+ $matched = preg_match('/^([0-9]{4}-[0-9]{1,2}-[0-9]{1,2}),(([0-9]{4}-[0-9]{1,2}-[0-9]{1,2})|today|now|yesterday)$/D', trim($dateString), $regs);
+ if (empty($matched)) {
+ return false;
+ }
+ return $regs;
+ }
+
+ protected $endDate = null;
+
+ /**
+ * Returns the end date of the period
+ *
+ * @return null|Piwik_Date
+ */
+ public function getDateEnd()
+ {
+ if (!is_null($this->endDate)) {
+ return $this->endDate;
+ }
+ return parent::getDateEnd();
+ }
+
+ /**
+ * Determine which kind of period is best to use
+ * See Range.test.php
+ *
+ * @param $startDate
+ * @param $endDate
+ */
+ protected function processOptimalSubperiods($startDate, $endDate)
+ {
+ while ($startDate->isEarlier($endDate)
+ || $startDate == $endDate) {
+ $endOfPeriod = null;
+
+ $month = new Piwik_Period_Month($startDate);
+ $endOfMonth = $month->getDateEnd();
+ $startOfMonth = $month->getDateStart();
+ if ($startDate == $startOfMonth
+ && ($endOfMonth->isEarlier($endDate)
+ || $endOfMonth == $endDate
+ || $endOfMonth->isLater($this->today)
+ )
+ // We don't use the month if
+ // the end day is in this month, is before today, and month not finished
+ && !($endDate->isEarlier($this->today)
+ && $this->today->toString('Y') == $endOfMonth->toString('Y')
+ && $this->today->compareMonth($endOfMonth) == 0)
+ ) {
+ $this->addSubperiod($month);
+ $endOfPeriod = $endOfMonth;
+ } else {
+ // From start date,
+ // Process end of week
+ $week = new Piwik_Period_Week($startDate);
+ $startOfWeek = $week->getDateStart();
+ $endOfWeek = $week->getDateEnd();
+
+ $useMonthsNextIteration = $startDate->addPeriod(2, 'month')->setDay(1)->isEarlier($endDate);
+ if ($useMonthsNextIteration
+ && $endOfWeek->isLater($endOfMonth)
+ ) {
+ $this->fillArraySubPeriods($startDate, $endOfMonth, 'day');
+ $endOfPeriod = $endOfMonth;
+ } // If end of this week is later than end date, we use days
+ elseif ($endOfWeek->isLater($endDate)
+ && ($endOfWeek->isEarlier($this->today)
+ || $endDate->isEarlier($this->today))
+ ) {
+ $this->fillArraySubPeriods($startDate, $endDate, 'day');
+ break 1;
+ } elseif ($startOfWeek->isEarlier($startDate)
+ && $endOfWeek->isEarlier($this->today)
+ ) {
+ $this->fillArraySubPeriods($startDate, $endOfWeek, 'day');
+ $endOfPeriod = $endOfWeek;
+ } else {
+ $this->addSubperiod($week);
+ $endOfPeriod = $endOfWeek;
+ }
+ }
+ $startDate = $endOfPeriod->addDay(1);
+ }
+ }
+
+ /**
+ * Adds new subperiods
+ *
+ * @param Piwik_Date $startDate
+ * @param Piwik_Date $endDate
+ * @param string $period
+ */
+ protected function fillArraySubPeriods($startDate, $endDate, $period)
+ {
+ $arrayPeriods = array();
+ $endSubperiod = Piwik_Period::factory($period, $endDate);
+ $arrayPeriods[] = $endSubperiod;
+
+ // set end date to start of end period since we're comparing against start date.
+ $endDate = $endSubperiod->getDateStart();
+ while ($endDate->isLater($startDate)) {
+ $endDate = self::removePeriod($period, $endDate, 1);
+ $subPeriod = Piwik_Period::factory($period, $endDate);
+ $arrayPeriods[] = $subPeriod;
+ }
+ $arrayPeriods = array_reverse($arrayPeriods);
+ foreach ($arrayPeriods as $period) {
+ $this->addSubperiod($period);
+ }
+ }
+
+ /**
+ * Returns the date that is one period before the supplied date.
+ *
+ * @param string $date The date to get the last date of.
+ * @param string $period The period to use (either 'day', 'week', 'month', 'year');
+ * @return array An array with two elements, a string for the date before $date and
+ * a Piwik_Period instance for the period before $date.
+ */
+ public static function getLastDate($date = false, $period = false)
+ {
+ if ($date === false) {
+ $date = Piwik_Common::getRequestVar('date');
+ }
+
+ if ($period === false) {
+ $period = Piwik_Common::getRequestVar('period');
+ }
+
+ // can't get the last date for range periods & dates that use lastN/previousN
+ $strLastDate = false;
+ $lastPeriod = false;
+ if ($period != 'range' && !preg_match('/(last|previous)([0-9]*)/', $date, $regs)) {
+ if (strpos($date, ',')) // date in the form of 2011-01-01,2011-02-02
+ {
+ $rangePeriod = new Piwik_Period_Range($period, $date);
+
+ $lastStartDate = Piwik_Period_Range::removePeriod($period, $rangePeriod->getDateStart(), $n = 1);
+ $lastEndDate = Piwik_Period_Range::removePeriod($period, $rangePeriod->getDateEnd(), $n = 1);
+
+ $strLastDate = "$lastStartDate,$lastEndDate";
+ } else {
+ $lastPeriod = Piwik_Period_Range::removePeriod($period, Piwik_Date::factory($date), $n = 1);
+ $strLastDate = $lastPeriod->toString();
+ }
+ }
+
+ return array($strLastDate, $lastPeriod);
+ }
}