public static function filterEventsInDateRange(\Phidias\Db\Orm\Collection $events, $startDate, $endDate) { if ($endDate < $startDate) { $endDate = $startDate; } //First, condition the query to return only events that ocurr in the specified date range $conditions = []; //non repeating events ocurring within the date range $conditions[] = "(repetition.id IS NULL AND startDate >= {$startDate} AND endDate <= {$endDate})"; //Repetition conditions for each day in the date range for ($date = $startDate; $date <= $endDate; $date = $date + 86400) { $day = date('j', $date); $month = date('n', $date); $year = date('Y', $date); $weekDay = date('N', $date); $weekDayN = ceil($day / 7); $weekDayIsLast = $day + 7 > date('t', $date); $seqDay = self::daysSinceEpoch($date); $seqMonth = $month + ($year - 1970) * 12; $dayConditions = []; $dayConditions[] = "(repetition.frequency = " . Repetition::FREQUENCY_DAILY . " AND ({$seqDay} - repetition.seqDay) % repetition.interval = 0)"; $dayConditions[] = "(repetition.frequency = " . Repetition::FREQUENCY_WEEKLY . " AND repetition.weekDay = {$weekDay} AND ({$seqDay}-repetition.seqDay)/7 % repetition.interval = 0)"; $dayConditions[] = "(repetition.frequency = " . Repetition::FREQUENCY_MONTHLY_DAY . " AND repetition.day = {$day} AND ({$seqMonth} - repetition.seqMonth) % repetition.interval = 0)"; $dayConditions[] = "(repetition.frequency = " . Repetition::FREQUENCY_MONTHLY_WEEKDAY . " AND repetition.weekDay = {$weekDay} AND IF(repetition.weekDayN = 5, repetition.weekDayIsLast, repetition.weekDayN = {$weekDayN}) AND ({$seqMonth}-repetition.seqMonth) % repetition.interval = 0)"; $dayConditions[] = "(repetition.frequency = " . Repetition::FREQUENCY_YEARLY . " AND repetition.day = {$day} AND repetition.month = {$month} AND ({$year} - repetition.year) % repetition.interval = 0)"; $conditions[] = "(" . implode(" OR ", $dayConditions) . ")"; } $events->where("startDate <= :endDate", ["endDate" => $endDate]); $events->where(implode(" OR ", $conditions)); //Fetch all repetition data for each event $events->attribute("repetition", Repetition::collection()->allAttributes()); //Now, in post-processing, determine in which day in the date range the event ocurred, and create //an entry in the "occurrences" attribute $events->addFilter(function ($event) use($startDate, $endDate) { if (!isset($event->occurrences)) { $event->occurrences = array(); } for ($date = $startDate; $date <= $endDate; $date = $date + 86400) { $eventDay = mktime(0, 0, 0, date("m", $event->startDate), date("d", $event->startDate), date("Y", $event->startDate)); if ($eventDay > $date) { continue; } foreach ($event->repetition as $repetition) { $day = date('j', $date); $month = date('n', $date); $year = date('Y', $date); $weekDay = date('N', $date); $weekDayN = ceil($day / 7); $weekDayIsLast = $day + 7 > date('t', $date); $seqDay = self::daysSinceEpoch($date); $seqMonth = $month + ($year - 1970) * 12; if ($repetition->frequency == Repetition::FREQUENCY_DAILY && ($seqDay - $repetition->seqDay) % $repetition->interval == 0 || $repetition->frequency == Repetition::FREQUENCY_WEEKLY && $repetition->weekDay == $weekDay && ($seqDay - $repetition->seqDay) / 7 % $repetition->interval == 0 || $repetition->frequency == Repetition::FREQUENCY_MONTHLY_DAY && $repetition->day == $day && ($seqMonth - $repetition->seqMonth) % $repetition->interval == 0 || $repetition->frequency == Repetition::FREQUENCY_MONTHLY_WEEKDAY && $repetition->weekDay == $weekDay && ($repetition->weekDayN == 5 ? $repetition->weekDayIsLast : $repetition->weekDayN == $weekDayN) && ($seqMonth - $repetition->seqMonth) % $repetition->interval == 0 || $repetition->frequency == Repetition::FREQUENCY_YEARLY && $repetition->day == $day && $repetition->month == $month && ($year - $repetition->year) % $repetition->interval == 0) { $childEvent = clone $event; $childEvent->startDate = mktime(date('h', $event->startDate), date('i', $event->startDate), date('s', $event->startDate), date('m', $date), date('d', $date), date('y', $date)); $childEvent->endDate = $childEvent->startDate + ($event->endDate - $event->startDate); unset($childEvent->occurrences); unset($childEvent->repetition); $event->occurrences[] = $childEvent; } } } }); }
public static function collection($attributesObject = null) { $className = get_called_class(); $schema = $className::getSchema(); $collection = new Collection($schema); $collection->className($className); //Set the collection attributes from the given object if ($attributesObject !== null) { foreach (get_object_vars($attributesObject) as $attributeName => $value) { if (!$schema->hasAttribute($attributeName)) { continue; } if (is_a($value, "Phidias\\Db\\Orm\\Entity")) { $collection->attribute($attributeName, $value::collection($value)); } elseif (is_scalar($value) || is_null($value)) { $collection->attribute($attributeName); } } } return $collection; }