diff --git a/src/applications/calendar/controller/PhabricatorCalendarController.php b/src/applications/calendar/controller/PhabricatorCalendarController.php --- a/src/applications/calendar/controller/PhabricatorCalendarController.php +++ b/src/applications/calendar/controller/PhabricatorCalendarController.php @@ -30,6 +30,15 @@ return $crumbs; } + protected function getEventAtIndexForGhostEvent($viewer, $event, $index) { + $phid = $event->getInstanceOfEventPHID(); + + if (!$phid) { + $phid = $event->getPHID(); + } + return $this->getEventAtIndexForGhostPHID($viewer, $phid, $index); + } + protected function getEventAtIndexForGhostPHID($viewer, $phid, $index) { $result = id(new PhabricatorCalendarEventQuery()) ->setViewer($viewer) diff --git a/src/applications/calendar/controller/PhabricatorCalendarEventViewController.php b/src/applications/calendar/controller/PhabricatorCalendarEventViewController.php --- a/src/applications/calendar/controller/PhabricatorCalendarEventViewController.php +++ b/src/applications/calendar/controller/PhabricatorCalendarEventViewController.php @@ -23,9 +23,9 @@ } if ($sequence) { - $result = $this->getEventAtIndexForGhostPHID( + $result = $this->getEventAtIndexForGhostEvent( $viewer, - $event->getPHID(), + $event, $sequence); if ($result) { @@ -116,7 +116,7 @@ $icon = $is_cancelled ? ('fa-ban') : ('fa-check'); $color = $is_cancelled ? ('red') : ('bluegrey'); $status = $is_cancelled ? pht('Cancelled') : pht('Active'); - + $is_recurring = $event->getIsRecurring(); $invite_status = $event->getUserInviteStatus($viewer->getPHID()); $status_invited = PhabricatorCalendarEventInvitee::STATUS_INVITED; $is_invite_pending = ($invite_status == $status_invited); @@ -128,6 +128,43 @@ ->setPolicyObject($event) ->setHeaderIcon('fa-calendar'); + if ($is_recurring) { + + $index = $event->getSequenceIndex(); + $prev_index = $index - 1; + $next_index = $index + 1; + $prev_uri = "/E{$id}/{$prev_index}"; + $next_uri = "/E{$id}/{$next_index}"; + $button_bar = new PHUIButtonBarView(); + + $left_icon = id(new PHUIIconView()) + ->setIcon('fa-chevron-left bluegrey'); + $left = id(new PHUIButtonView()) + ->setTag('a') + ->setColor(PHUIButtonView::GREY) + ->setHref($prev_uri) + ->setTitle(pht('Previous Recurrence')) + ->setIcon($left_icon); + if ($prev_index < 1) { + $left->setDisabled(true) + ->setHref(''); + + } + + $right_icon = id(new PHUIIconView()) + ->setIcon('fa-chevron-right bluegrey'); + $right = id(new PHUIButtonView()) + ->setTag('a') + ->setColor(PHUIButtonView::GREY) + ->setHref($next_uri) + ->setTitle(pht('Next Recurrence')) + ->setIcon($right_icon); + + $button_bar->addButton($left); + $button_bar->addButton($right); + $header->setButtonBar($button_bar); + } + if ($is_invite_pending) { $decline_button = id(new PHUIButtonView()) ->setTag('a') diff --git a/src/applications/calendar/storage/PhabricatorCalendarEvent.php b/src/applications/calendar/storage/PhabricatorCalendarEvent.php --- a/src/applications/calendar/storage/PhabricatorCalendarEvent.php +++ b/src/applications/calendar/storage/PhabricatorCalendarEvent.php @@ -292,8 +292,21 @@ $frequency = $this->getFrequencyUnit(); $modify_key = '+'.$sequence_index.' '.$frequency; - $instance_of = ($this->getPHID()) ? - $this->getPHID() : $this->instanceOfEventPHID; + if ($this->instanceOfEventPHID) { + $event = id(new PhabricatorCalendarEventQuery()) + ->setViewer($actor) + ->withPHIDs(array($this->instanceOfEventPHID)) + ->requireCapabilities( + array( + PhabricatorPolicyCapability::CAN_VIEW, + PhabricatorPolicyCapability::CAN_EDIT, + )) + ->executeOne(); + return $event->generateNthGhost($sequence_index, $actor); + } + $instance_of = ($this->instanceOfEventPHID) ? + $this->instanceOfEventPHID : $this->getPHID(); + $date = $this->dateFrom; $date_time = PhabricatorTime::getDateTimeFromEpoch($date, $actor); @@ -317,6 +330,34 @@ return $ghost_event; } + protected function getEventAtIndexForGhostEvent($viewer, $event, $index) { + $phid = $event->getInstanceOfEventPHID(); + if (!$phid) { + $phid = $event->getPHID(); + } + return $this->getEventAtIndexForGhostPHID($viewer, $phid, $index); + } + + protected function getEventAtIndexForGhostPHID($viewer, $phid, $index) { + $result = id(new PhabricatorCalendarEventQuery()) + ->setViewer($viewer) + ->withInstanceSequencePairs( + array( + array( + $phid, + $index, + ), + )) + ->requireCapabilities( + array( + PhabricatorPolicyCapability::CAN_VIEW, + PhabricatorPolicyCapability::CAN_EDIT, + )) + ->executeOne(); + + return $result; + } + public function getFrequencyUnit() { $frequency = idx($this->recurrenceFrequency, 'rule');