summaryrefslogtreecommitdiffstats
path: root/RecurringType.php
diff options
context:
space:
mode:
authorEgor <elazarovich@xbsoftware.com>2015-03-06 16:29:38 +0300
committerEgor <elazarovich@xbsoftware.com>2015-03-06 16:29:38 +0300
commit9e85bca1edfaf801d4f0ebf5dcd06eb73cf7f5bb (patch)
treed80182897de5e5c13ea3f42b43875e50299d6bbe /RecurringType.php
parentc84f7d0038fa9bc1c6569bc7e4d73da17fb414fd (diff)
downloadscheduler-helper-php-9e85bca1edfaf801d4f0ebf5dcd06eb73cf7f5bb.zip
scheduler-helper-php-9e85bca1edfaf801d4f0ebf5dcd06eb73cf7f5bb.tar.gz
scheduler-helper-php-9e85bca1edfaf801d4f0ebf5dcd06eb73cf7f5bb.tar.bz2
Updated structure.
Diffstat (limited to 'RecurringType.php')
-rw-r--r--RecurringType.php383
1 files changed, 0 insertions, 383 deletions
diff --git a/RecurringType.php b/RecurringType.php
deleted file mode 100644
index b5ff1de..0000000
--- a/RecurringType.php
+++ /dev/null
@@ -1,383 +0,0 @@
-<?php
-namespace Scheduler;
-use Exception;
-
-class RecurringType {
-
- //RECURRING DATA FIELDS
- const FLD_REC_TYPE = "type";
- const FLD_REC_TYPE_STEP = "count";
- const FLD_WEEK_DAY = "day";
- const FLD_WEEK_NUMBER = "count2";
- const FLD_WEEK_DAYS_LIST = "days";
- const FLD_REPEAT = "repeat";
-
- //RECURRING TYPES
- const REC_TYPE_DAY = "day";
- const REC_TYPE_WEEK = "week";
- const REC_TYPE_MONTH = "month";
- const REC_TYPE_YEAR = "year";
-
- //RECURRING VALUES
- const IS_RECURRING_EXCEPTION = "";
- const IS_RECURRING_BREAK = "none";
-
- private $_fields_values = array();
- private $_recurring_start_date_stamp;
- private $_recurring_end_date_stamp;
-
- public function __construct($recurringType, $recurringStartDateStamp, $recurringEndDateStamp)
- {
- if(is_array($recurringType))
- $recurringType = self::parseRecurringDataArrayToString($recurringType);
-
- $this->_fields_values = self::_parseRecurringDataString($recurringType);
- $this->_recurring_start_date_stamp = $recurringStartDateStamp;
- $this->_recurring_end_date_stamp = $recurringEndDateStamp;
- }
-
- public static function getInstance($recurringTypeString, $recurringStartDateStamp, $recurringEndDateStamp) {
- return new self($recurringTypeString, $recurringStartDateStamp, $recurringEndDateStamp);
- }
-
- /**
- * Get field value.
- * @param $fieldName
- * @return mixed
- * @throws Exception
- */
- private function _getFieldValue($fieldName)
- {
- if(!isset($this->_fields_values[$fieldName]))
- throw new Exception("Field '{$fieldName}' not found.");
-
- return $this->_fields_values[$fieldName];
- }
-
- /**
- * Parse recurring data from array to string.
- * @param $dataArray
- * @return string
- * @throws Exception
- */
- static function parseRecurringDataArrayToString($dataArray)
- {
- $dataFields = array(
- self::FLD_REC_TYPE => "each",
- self::FLD_REC_TYPE_STEP => "step",
-// self::FLD_WEEK_DAY => "day_of_week",//ToDo: delete.
- self::FLD_WEEK_NUMBER => "week_number",
- self::FLD_WEEK_DAYS_LIST => "days_of_week",
- self::FLD_REPEAT => "repeat"
- );
-
- $recurringTypes = array(self::REC_TYPE_DAY, self::REC_TYPE_WEEK, self::REC_TYPE_MONTH, self::REC_TYPE_YEAR);
- $daysOfWeek = array("sunday" => 0, "monday" => 1, "tuesday" => 2, "wednesday" => 3, "thursday" => 4, "friday" => 5, "saturday" => 6);
- $dataFieldsValues = array();
-
- foreach($dataArray as $field => $value) {
- switch($field) {
- case $dataFields[self::FLD_REC_TYPE_STEP]:
- case $dataFields[self::FLD_REPEAT]:
- $value = str_replace(" ", "", $value);
- $dataFieldsValues[$field] = $value;
- break;
-
- case $dataFields[self::FLD_REC_TYPE]:
- $value = str_replace(" ", "", $value);
- if(!in_array($value, $recurringTypes))
- throw new Exception("Field '{$field}' will contains value of ".join(", ", $recurringTypes));
-
- $dataFieldsValues[$field] = $value;
- break;
-
-
- case $dataFields[self::FLD_WEEK_NUMBER]:
- $value = str_replace(" ", "", $value);
- if(count(explode(",", $dataArray[$dataFields[self::FLD_WEEK_DAYS_LIST]])) > 1)
- throw new Exception("If field {$field} not null, then field ".$dataFields[self::FLD_WEEK_DAYS_LIST]." will contains only one value of ".join(", ", array_keys($daysOfWeek)));
-
- if(!in_array($value, $daysOfWeek))
- throw new Exception("Field {$field} will contains value of ".join(",", array_keys($daysOfWeek)));
-
- $dataFieldsValues[$field] = $value;
- break;
-
- case $dataFields[self::FLD_WEEK_DAYS_LIST]:
- $weekDaysToRecurring = explode(",", $value);
- $days = array();
- foreach($weekDaysToRecurring as $day) {
- $day = str_replace(" ", "", $day);
- if(!in_array($day, $daysOfWeek))
- throw new Exception("Field {$field} will contains data like 'monday,tuesday,wednesday'.");
-
- array_push($days, $daysOfWeek[$day]);
- }
-
- $dataFieldsValues[$field] = join("," ,$days);
- break;
-
- default:
- $dataFieldsValues[$field] = "";
- break;
- }
- }
-
- //Check required data and fill gaps of data.
- $requiredFields = array(
- self::FLD_REC_TYPE,
- self::FLD_REC_TYPE_STEP
- );
-
- foreach($dataFields as $fieldKey => $fieldName) {
- if(isset($dataFieldsValues[$fieldName]))
- continue;
-
- if(in_array($fieldKey, $requiredFields))
- throw new Exception("Field '{$fieldName}' is required");
-
- $dataFieldsValues[$fieldName] = "";
- }
-
- $recurringFormat = "%s_%s_%s_%s_%s#%s";
- return sprintf(
- $recurringFormat,
- $dataFieldsValues[$dataFields[self::FLD_REC_TYPE]],
- $dataFieldsValues[$dataFields[self::FLD_REC_TYPE_STEP]],
- (!empty($dataFieldsValues[$dataFields[self::FLD_WEEK_NUMBER]])) ? $dataFieldsValues[$dataFields[self::FLD_WEEK_DAYS_LIST]] : "",
- $dataFieldsValues[$dataFields[self::FLD_WEEK_NUMBER]],
- (empty($dataFieldsValues[$dataFields[self::FLD_WEEK_NUMBER]])) ? $dataFieldsValues[$dataFields[self::FLD_WEEK_DAYS_LIST]] : "",
- $dataFieldsValues[$dataFields[self::FLD_REPEAT]]
- );
- }
-
- /**
- * Parse recurring data from string.
- * @param $dataStr
- * @return array
- */
- static private function _parseRecurringDataString($dataStr)
- {
- $formatPartsReg = "/(_|#)/";
- $formatDaysListPartReg = "/,/";
- $parsedData = array();
-
- list(
- $parsedData[self::FLD_REC_TYPE],
- $parsedData[self::FLD_REC_TYPE_STEP],
- $parsedData[self::FLD_WEEK_DAY],
- $parsedData[self::FLD_WEEK_NUMBER],
- $parsedData[self::FLD_WEEK_DAYS_LIST],
- $parsedData[self::FLD_REPEAT]
- ) = preg_split($formatPartsReg, $dataStr);
-
- $parsedData[self::FLD_WEEK_DAYS_LIST] = ($parsedData[self::FLD_WEEK_DAYS_LIST]) ?
- preg_split($formatDaysListPartReg, $parsedData[self::FLD_WEEK_DAYS_LIST]) : array();
-
- return $parsedData;
- }
-
- public function getRecurringTypeValue()
- {
- return $this->_getFieldValue(self::FLD_REC_TYPE);
- }
-
- public function getRecurringTypeStepValue()
- {
- return $this->_getFieldValue(self::FLD_REC_TYPE_STEP);
- }
-
- public function getWeekNumberValue()
- {
- return $this->_getFieldValue(self::FLD_WEEK_NUMBER);
- }
-
- public function getWeekDayValue()
- {
- return $this->_getFieldValue(self::FLD_WEEK_DAY);
- }
-
- public function getWeekDaysListValue()
- {
- return $this->_getFieldValue(self::FLD_WEEK_DAYS_LIST);
- }
-
- public function getRepeatValue()
- {
- return $this->_getFieldValue(self::FLD_REPEAT);
- }
-
- /**
- * Correcting interval by recurring start($this->_recurring_start_date_stamp)
- * and end($this->_recurring_end_date_stamp) dates.
- * @param $intervalStartDateStamp
- * @param $intervalEndDateStamp
- * @return array
- */
- private function _getCorrectedRecurringInterval($intervalStartDateStamp, $intervalEndDateStamp)
- {
- $recurringStartDateStamp = $this->_recurring_start_date_stamp;
- $recurringEndDateStamp = $this->_recurring_end_date_stamp;
-
- $recurringInterval = array(
- "start_date_stamp" => $intervalStartDateStamp,
- "end_date_stamp" => $intervalEndDateStamp
- );
-
- //Return recurring interval without correcting if it not belongs to assigned interval.
- if(($intervalStartDateStamp >= $recurringEndDateStamp) || ($intervalEndDateStamp <= $recurringStartDateStamp))
- return $recurringInterval;
-
- //Correct start date interval if it smaller then recurring start date.
- if($intervalStartDateStamp < $recurringStartDateStamp)
- $intervalStartDateStamp = $recurringStartDateStamp;
-
- //Correct end date interval if it smaller then recurring end date.
- if($intervalEndDateStamp > $recurringEndDateStamp)
- $intervalEndDateStamp = $recurringEndDateStamp;
-
- $differenceStartDates = SchedulerDate::differenceBetweenDates($intervalStartDateStamp, $recurringStartDateStamp);
- $differenceEndDates = SchedulerDate::differenceBetweenDates($intervalEndDateStamp, $recurringEndDateStamp);
- $dateUnits = SchedulerDate::$DATE_UNITS;
-
- //Add years.
- $recurringInterval["start_date_stamp"] = SchedulerDate::addYears($recurringStartDateStamp, $differenceStartDates[$dateUnits["year"]]);
- $recurringInterval["end_date_stamp"] = SchedulerDate::addYears($recurringEndDateStamp, -$differenceEndDates[$dateUnits["year"]]);
-
- //If recurring type is "year" then exit, else add months.
- if($this->getRecurringTypeValue() == self::REC_TYPE_YEAR)
- return $recurringInterval;
-
- //Add months.
- $recurringInterval["start_date_stamp"] = SchedulerDate::addMonths($recurringInterval["start_date_stamp"], $differenceStartDates[$dateUnits["month"]]);
- $recurringInterval["end_date_stamp"] = SchedulerDate::addMonths($recurringInterval["end_date_stamp"], -$differenceEndDates[$dateUnits["month"]]);
- return $recurringInterval;
- }
-
- /**
- * Get step to recurring day from current day of week in date.
- * @param $dateStamp
- * @param $recurringWeekDay
- * @return int
- */
- private function _getRecurringDayStep($dateStamp, $recurringWeekDay)
- {
- $weekDay = SchedulerDate::getDayOfWeek($dateStamp);
- $dayStep = $recurringWeekDay - $weekDay;
- $dayStep = ($dayStep < 0) ? (SchedulerDate::DAYS_IN_WEEK - (-$dayStep)) : $dayStep;
- return $dayStep;
- }
-
- /**
- * Get recurring days for date.
- * @param $dateStamp
- * @return array
- */
- private function _getRecurringDays($dateStamp)
- {
- $recurringDays = array();
-
- //If recurring type has list of days, then get those days.
- $recurringWeekDays = $this->getWeekDaysListValue();
- if($recurringWeekDays) {
- for($i = 0; $i < count($recurringWeekDays); $i++) {
- $dayStep = $this->_getRecurringDayStep($dateStamp, $recurringWeekDays[$i]);
- array_push($recurringDays, SchedulerDate::addDays($dateStamp, $dayStep));
- }
- }
- //Else if recurring type has day of week and step for it, then get this day.
- elseif($this->getWeekDayValue() && $this->getWeekNumberValue()) {
- $dayStep = $this->_getRecurringDayStep($dateStamp, $this->getWeekDayValue());
- $dayStep += (SchedulerDate::DAYS_IN_WEEK * ($this->getWeekNumberValue() - 1));
- array_push($recurringDays, SchedulerDate::addDays($dateStamp, $dayStep));
- }
- //Else return recurring date without change.
- else
- array_push($recurringDays, $dateStamp);
-
- return $recurringDays;
- }
-
- /**
- * Get recurring dates by interval or $intervalStartDateStamp and $countDates.
- * @param $intervalStartDateStamp
- * @param $intervalEndDateStamp
- * @param null $countDates
- * @return array|bool
- */
- public function getRecurringDates($intervalStartDateStamp, $intervalEndDateStamp, $countDates = NULL)
- {
- if(!($this->getRecurringTypeStepValue() && $this->getRecurringTypeValue()))
- return false;
-
- //Correct interval by recurring interval.
- $correctedInterval = $this->_getCorrectedRecurringInterval($intervalStartDateStamp, $intervalEndDateStamp);
- $intervalStartDateStamp = $correctedInterval["start_date_stamp"];
- $intervalEndDateStamp = $correctedInterval["end_date_stamp"];
- $currentRecurringStartDateStamp = $intervalStartDateStamp;
- $recurringDates = array();
-
- //Generate dates wile next recurring date belongs to interval.
- $countRecurringCycles = 0;
- while(
- (!is_null($countDates) && ($countRecurringCycles <= $countDates))
- || (
- ($intervalStartDateStamp <= $currentRecurringStartDateStamp)
- && ($currentRecurringStartDateStamp <= $intervalEndDateStamp)
- )
- ) {
- $countRecurringCycles++;
- $recurringDays = $this->_getRecurringDays($currentRecurringStartDateStamp);
- $recurringDates = array_merge($recurringDates, $recurringDays);
-
- $recurringTypeStep = $this->getRecurringTypeStepValue();
- switch($this->getRecurringTypeValue()) {
- case self::REC_TYPE_DAY:
- $currentRecurringStartDateStamp = SchedulerDate::addDays($currentRecurringStartDateStamp, $recurringTypeStep);
- break;
-
- case self::REC_TYPE_WEEK:
- $currentRecurringStartDateStamp = SchedulerDate::addWeeks($currentRecurringStartDateStamp, $recurringTypeStep);
- break;
-
- case self::REC_TYPE_MONTH:
- $currentRecurringStartDateStamp = SchedulerDate::addMonths($currentRecurringStartDateStamp, $recurringTypeStep);
- break;
-
- case self::REC_TYPE_YEAR:
- $currentRecurringStartDateStamp = SchedulerDate::addYears($currentRecurringStartDateStamp, $recurringTypeStep);
- break;
- }
- }
-
- return (!is_null($countDates))
- ? array_splice($recurringDates, (count($recurringDates) - $countDates))
- : $recurringDates;
- }
-
- /**
- * @param $recurringType
- * @param $startDateStamp
- * @param $eventLength
- * @return int|NULL
- */
- public static function getRecurringEndDate($recurringType, $startDateStamp, $eventLength)
- {
- $recurringTypeObj = self::getInstance($recurringType, $startDateStamp, NULL);
-
- $repeatValue = $recurringTypeObj->getRepeatValue();
- if(empty($repeatValue))
- return ($startDateStamp + $eventLength);
-
- $recurringStartDatesStamps = $recurringTypeObj->getRecurringDates($startDateStamp, NULL, $repeatValue);
-
- $maxEndDateStamp = NULL;
- foreach($recurringStartDatesStamps as $startDateStamp) {
- $endDateStamp = $startDateStamp + $eventLength;
- $maxEndDateStamp = ($endDateStamp > $maxEndDateStamp) ? $endDateStamp : $maxEndDateStamp;
- }
-
- return $maxEndDateStamp;
- }
-
-} \ No newline at end of file