Path: blob/master/src/applications/calendar/xaction/PhabricatorCalendarEventFrequencyTransaction.php
12256 views
<?php12final class PhabricatorCalendarEventFrequencyTransaction3extends PhabricatorCalendarEventTransactionType {45const TRANSACTIONTYPE = 'calendar.frequency';67public function generateOldValue($object) {8$rrule = $object->newRecurrenceRule();910if (!$rrule) {11return null;12}1314return $rrule->getFrequency();15}1617public function applyInternalEffects($object, $value) {18$rrule = id(new PhutilCalendarRecurrenceRule())19->setFrequency($value);2021// If the user creates a monthly event on the 29th, 30th or 31st of a22// month, it means "the 30th of every month" as far as the RRULE is23// concerned. Such an event will not occur on months with fewer days.2425// This is surprising, and probably not what the user wants. Instead,26// schedule these events relative to the end of the month: on the "-1st",27// "-2nd" or "-3rd" day of the month. For example, a monthly event on28// the 31st of a 31-day month translates to "every month, on the last29// day of the month".30if ($value == PhutilCalendarRecurrenceRule::FREQUENCY_MONTHLY) {31$start_datetime = $object->newStartDateTime();3233$y = $start_datetime->getYear();34$m = $start_datetime->getMonth();35$d = $start_datetime->getDay();36if ($d >= 29) {37$year_map = PhutilCalendarRecurrenceRule::getYearMap(38$y,39PhutilCalendarRecurrenceRule::WEEKDAY_MONDAY);4041$month_days = $year_map['monthDays'][$m];42$schedule_on = -(($month_days + 1) - $d);4344$rrule->setByMonthDay(array($schedule_on));45}46}4748$object->setRecurrenceRule($rrule);49}5051public function validateTransactions($object, array $xactions) {52$errors = array();5354$valid = array(55PhutilCalendarRecurrenceRule::FREQUENCY_DAILY,56PhutilCalendarRecurrenceRule::FREQUENCY_WEEKLY,57PhutilCalendarRecurrenceRule::FREQUENCY_MONTHLY,58PhutilCalendarRecurrenceRule::FREQUENCY_YEARLY,59);60$valid = array_fuse($valid);6162foreach ($xactions as $xaction) {63$value = $xaction->getNewValue();6465if (!isset($valid[$value])) {66$errors[] = $this->newInvalidError(67pht(68'Event frequency "%s" is not valid. Valid frequencies are: %s.',69$value,70implode(', ', $valid)),71$xaction);72}73}7475return $errors;76}7778public function getTitle() {79$frequency = $this->getFrequency($this->getNewValue());80switch ($frequency) {81case PhutilCalendarRecurrenceRule::FREQUENCY_DAILY:82return pht(83'%s set this event to repeat daily.',84$this->renderAuthor());85case PhutilCalendarRecurrenceRule::FREQUENCY_WEEKLY:86return pht(87'%s set this event to repeat weekly.',88$this->renderAuthor());89case PhutilCalendarRecurrenceRule::FREQUENCY_MONTHLY:90return pht(91'%s set this event to repeat monthly.',92$this->renderAuthor());93case PhutilCalendarRecurrenceRule::FREQUENCY_YEARLY:94return pht(95'%s set this event to repeat yearly.',96$this->renderAuthor());97}98}99100public function getTitleForFeed() {101$frequency = $this->getFrequency($this->getNewValue());102switch ($frequency) {103case PhutilCalendarRecurrenceRule::FREQUENCY_DAILY:104return pht(105'%s set %s to repeat daily.',106$this->renderAuthor(),107$this->renderObject());108case PhutilCalendarRecurrenceRule::FREQUENCY_WEEKLY:109return pht(110'%s set %s to repeat weekly.',111$this->renderAuthor(),112$this->renderObject());113case PhutilCalendarRecurrenceRule::FREQUENCY_MONTHLY:114return pht(115'%s set %s to repeat monthly.',116$this->renderAuthor(),117$this->renderObject());118case PhutilCalendarRecurrenceRule::FREQUENCY_YEARLY:119return pht(120'%s set %s to repeat yearly.',121$this->renderAuthor(),122$this->renderObject());123}124}125126private function getFrequency($value) {127// NOTE: This is normalizing three generations of these transactions128// to use RRULE constants. It would be vaguely nice to migrate them129// for consistency.130131if (is_array($value)) {132$value = idx($value, 'rule');133} else {134$value = $value;135}136137return phutil_utf8_strtoupper($value);138}139140}141142143