Changeset View
Changeset View
Standalone View
Standalone View
src/applications/calendar/query/PhabricatorCalendarEventQuery.php
Show First 20 Lines • Show All 84 Lines • ▼ Show 20 Lines | return array( | ||||
'unique' => false, | 'unique' => false, | ||||
), | ), | ||||
) + parent::getOrderableColumns(); | ) + parent::getOrderableColumns(); | ||||
} | } | ||||
protected function getPagingValueMap($cursor, array $keys) { | protected function getPagingValueMap($cursor, array $keys) { | ||||
$event = $this->loadCursorObject($cursor); | $event = $this->loadCursorObject($cursor); | ||||
return array( | return array( | ||||
'start' => $event->getDateFrom(), | 'start' => $event->getViewerDateFrom(), | ||||
'id' => $event->getID(), | 'id' => $event->getID(), | ||||
); | ); | ||||
} | } | ||||
protected function loadPage() { | protected function loadPage() { | ||||
$events = $this->loadStandardPage($this->newResultObject()); | $events = $this->loadStandardPage($this->newResultObject()); | ||||
$viewer = $this->getViewer(); | $viewer = $this->getViewer(); | ||||
Show All 14 Lines | if (!$raw_limit && !$this->rangeEnd) { | ||||
'Event queries which generate ghost events must include either a '. | 'Event queries which generate ghost events must include either a '. | ||||
'result limit or an end date, because they may otherwise generate '. | 'result limit or an end date, because they may otherwise generate '. | ||||
'an infinite number of results. This query has neither.')); | 'an infinite number of results. This query has neither.')); | ||||
} | } | ||||
foreach ($events as $key => $event) { | foreach ($events as $key => $event) { | ||||
$sequence_start = 0; | $sequence_start = 0; | ||||
$sequence_end = null; | $sequence_end = null; | ||||
$duration = $event->getDateTo() - $event->getDateFrom(); | $duration = $event->getDuration(); | ||||
$end = null; | $end = null; | ||||
$instance_of = $event->getInstanceOfEventPHID(); | $instance_of = $event->getInstanceOfEventPHID(); | ||||
if ($instance_of == null && $this->isCancelled !== null) { | if ($instance_of == null && $this->isCancelled !== null) { | ||||
if ($event->getIsCancelled() != $this->isCancelled) { | if ($event->getIsCancelled() != $this->isCancelled) { | ||||
unset($events[$key]); | unset($events[$key]); | ||||
continue; | continue; | ||||
} | } | ||||
} | } | ||||
if ($event->getIsRecurring() && $instance_of == null) { | if ($event->getIsRecurring() && $instance_of == null) { | ||||
$frequency = $event->getFrequencyUnit(); | $frequency = $event->getFrequencyUnit(); | ||||
$modify_key = '+1 '.$frequency; | $modify_key = '+1 '.$frequency; | ||||
if ($this->rangeBegin && $this->rangeBegin > $event->getDateFrom()) { | if (($this->rangeBegin !== null) && | ||||
($this->rangeBegin > $event->getViewerDateFrom())) { | |||||
$max_date = $this->rangeBegin - $duration; | $max_date = $this->rangeBegin - $duration; | ||||
$date = $event->getDateFrom(); | $date = $event->getViewerDateFrom(); | ||||
$datetime = PhabricatorTime::getDateTimeFromEpoch($date, $viewer); | $datetime = PhabricatorTime::getDateTimeFromEpoch($date, $viewer); | ||||
while ($date < $max_date) { | while ($date < $max_date) { | ||||
// TODO: optimize this to not loop through all off-screen events | // TODO: optimize this to not loop through all off-screen events | ||||
$sequence_start++; | $sequence_start++; | ||||
$datetime = PhabricatorTime::getDateTimeFromEpoch($date, $viewer); | $datetime = PhabricatorTime::getDateTimeFromEpoch($date, $viewer); | ||||
$date = $datetime->modify($modify_key)->format('U'); | $date = $datetime->modify($modify_key)->format('U'); | ||||
} | } | ||||
$start = $this->rangeBegin; | $start = $this->rangeBegin; | ||||
} else { | } else { | ||||
$start = $event->getDateFrom() - $duration; | $start = $event->getViewerDateFrom() - $duration; | ||||
} | } | ||||
$date = $start; | $date = $start; | ||||
$datetime = PhabricatorTime::getDateTimeFromEpoch($date, $viewer); | $datetime = PhabricatorTime::getDateTimeFromEpoch($date, $viewer); | ||||
if (($this->rangeEnd && $event->getRecurrenceEndDate()) && | if (($this->rangeEnd && $event->getRecurrenceEndDate()) && | ||||
$this->rangeEnd < $event->getRecurrenceEndDate()) { | $this->rangeEnd < $event->getRecurrenceEndDate()) { | ||||
$end = $this->rangeEnd; | $end = $this->rangeEnd; | ||||
Show All 31 Lines | foreach ($events as $key => $event) { | ||||
// NOTE: We're slicing results every time because this makes it cheaper | // NOTE: We're slicing results every time because this makes it cheaper | ||||
// to generate future ghosts. If we already have 100 events that occur | // to generate future ghosts. If we already have 100 events that occur | ||||
// before July 1, we know we never need to generate ghosts after that | // before July 1, we know we never need to generate ghosts after that | ||||
// because they couldn't possibly ever appear in the result set. | // because they couldn't possibly ever appear in the result set. | ||||
if ($raw_limit) { | if ($raw_limit) { | ||||
if (count($events) >= $raw_limit) { | if (count($events) >= $raw_limit) { | ||||
$events = msort($events, 'getDateFrom'); | $events = msort($events, 'getViewerDateFrom'); | ||||
$events = array_slice($events, 0, $raw_limit, true); | $events = array_slice($events, 0, $raw_limit, true); | ||||
$enforced_end = last($events)->getDateFrom(); | $enforced_end = last($events)->getViewerDateFrom(); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
} | } | ||||
// Now that we're done generating ghost events, we're going to remove any | // Now that we're done generating ghost events, we're going to remove any | ||||
// ghosts that we have concrete events for (or which we can load the | // ghosts that we have concrete events for (or which we can load the | ||||
// concrete events for). These concrete events are generated when users | // concrete events for). These concrete events are generated when users | ||||
▲ Show 20 Lines • Show All 85 Lines • ▼ Show 20 Lines | protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) { | ||||
if ($this->phids) { | if ($this->phids) { | ||||
$where[] = qsprintf( | $where[] = qsprintf( | ||||
$conn, | $conn, | ||||
'event.phid IN (%Ls)', | 'event.phid IN (%Ls)', | ||||
$this->phids); | $this->phids); | ||||
} | } | ||||
// NOTE: The date ranges we query for are larger than the requested ranges | |||||
// because we need to catch all-day events. We'll refine this range later | |||||
// after adjusting the visible range of events we load. | |||||
if ($this->rangeBegin) { | if ($this->rangeBegin) { | ||||
$where[] = qsprintf( | $where[] = qsprintf( | ||||
$conn, | $conn, | ||||
'event.dateTo >= %d OR event.isRecurring = 1', | 'event.dateTo >= %d OR event.isRecurring = 1', | ||||
$this->rangeBegin); | $this->rangeBegin - phutil_units('16 hours in seconds')); | ||||
} | } | ||||
if ($this->rangeEnd) { | if ($this->rangeEnd) { | ||||
$where[] = qsprintf( | $where[] = qsprintf( | ||||
$conn, | $conn, | ||||
'event.dateFrom <= %d', | 'event.dateFrom <= %d', | ||||
$this->rangeEnd); | $this->rangeEnd + phutil_units('16 hours in seconds')); | ||||
} | } | ||||
if ($this->inviteePHIDs !== null) { | if ($this->inviteePHIDs !== null) { | ||||
$where[] = qsprintf( | $where[] = qsprintf( | ||||
$conn, | $conn, | ||||
'invitee.inviteePHID IN (%Ls)', | 'invitee.inviteePHID IN (%Ls)', | ||||
$this->inviteePHIDs); | $this->inviteePHIDs); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 68 Lines • ▼ Show 20 Lines | final class PhabricatorCalendarEventQuery | ||||
protected function willFilterPage(array $events) { | protected function willFilterPage(array $events) { | ||||
$range_start = $this->rangeBegin; | $range_start = $this->rangeBegin; | ||||
$range_end = $this->rangeEnd; | $range_end = $this->rangeEnd; | ||||
$instance_of_event_phids = array(); | $instance_of_event_phids = array(); | ||||
$recurring_events = array(); | $recurring_events = array(); | ||||
$viewer = $this->getViewer(); | $viewer = $this->getViewer(); | ||||
foreach ($events as $key => $event) { | foreach ($events as $key => $event) { | ||||
$event_start = $event->getDateFrom(); | $event_start = $event->getViewerDateFrom(); | ||||
$event_end = $event->getDateTo(); | $event_end = $event->getViewerDateTo(); | ||||
if ($range_start && $event_end < $range_start) { | if ($range_start && $event_end < $range_start) { | ||||
unset($events[$key]); | unset($events[$key]); | ||||
} | } | ||||
if ($range_end && $event_start > $range_end) { | if ($range_end && $event_start > $range_end) { | ||||
unset($events[$key]); | unset($events[$key]); | ||||
} | } | ||||
} | } | ||||
▲ Show 20 Lines • Show All 49 Lines • ▼ Show 20 Lines | foreach ($events as $key => $event) { | ||||
if ($this->isCancelled !== null) { | if ($this->isCancelled !== null) { | ||||
if ($event->getIsCancelled() != $this->isCancelled) { | if ($event->getIsCancelled() != $this->isCancelled) { | ||||
unset($events[$key]); | unset($events[$key]); | ||||
continue; | continue; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
$events = msort($events, 'getDateFrom'); | $events = msort($events, 'getViewerDateFrom'); | ||||
return $events; | return $events; | ||||
} | } | ||||
} | } |