Page MenuHomePhabricator

D13039.id31482.diff
No OneTemporary

D13039.id31482.diff

diff --git a/resources/sql/autopatches/20150527.calendar.recurringevents.sql b/resources/sql/autopatches/20150527.calendar.recurringevents.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20150527.calendar.recurringevents.sql
@@ -0,0 +1,17 @@
+ALTER TABLE {$NAMESPACE}_calendar.calendar_event
+ ADD isRecurring BOOL NOT NULL;
+
+ALTER TABLE {$NAMESPACE}_calendar.calendar_event
+ ADD recurrenceFrequency LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL;
+
+ALTER TABLE {$NAMESPACE}_calendar.calendar_event
+ ADD recurrenceEndDate INT UNSIGNED;
+
+ALTER TABLE {$NAMESPACE}_calendar.calendar_event
+ ADD instanceOfEventPHID varbinary(64);
+
+ALTER TABLE {$NAMESPACE}_calendar.calendar_event
+ ADD sequenceIndex INT UNSIGNED;
+
+UPDATE {$NAMESPACE}_calendar.calendar_event
+ SET recurrenceFrequency = '[]' WHERE recurrenceFrequency = '';
diff --git a/src/applications/calendar/controller/PhabricatorCalendarEventEditController.php b/src/applications/calendar/controller/PhabricatorCalendarEventEditController.php
--- a/src/applications/calendar/controller/PhabricatorCalendarEventEditController.php
+++ b/src/applications/calendar/controller/PhabricatorCalendarEventEditController.php
@@ -21,9 +21,10 @@
$error_end_date = true;
$validation_exception = null;
+ $is_recurring_id = celerity_generate_unique_node_id();
$all_day_id = celerity_generate_unique_node_id();
$start_date_id = celerity_generate_unique_node_id();
- $end_date_id = null;
+ $end_date_id = celerity_generate_unique_node_id();
$next_workflow = $request->getStr('next');
$uri_query = $request->getStr('query');
@@ -70,7 +71,6 @@
$subscribers = array();
$invitees = array($user_phid);
$cancel_uri = $this->getApplicationURI();
- $end_date_id = celerity_generate_unique_node_id();
} else {
$event = id(new PhabricatorCalendarEventQuery())
->setViewer($viewer)
@@ -113,6 +113,7 @@
$name = $event->getName();
$description = $event->getDescription();
$is_all_day = $event->getIsAllDay();
+ $is_recurring = $event->getIsRecurring();
$icon = $event->getIcon();
$current_policies = id(new PhabricatorPolicyQuery())
@@ -134,6 +135,7 @@
$subscribers = $request->getArr('subscribers');
$edit_policy = $request->getStr('editPolicy');
$view_policy = $request->getStr('viewPolicy');
+ $is_recurring = $request->getStr('isRecurring') ? 1 : 0;
$is_all_day = $request->getStr('isAllDay');
$icon = $request->getStr('icon');
@@ -154,6 +156,11 @@
$xactions[] = id(new PhabricatorCalendarEventTransaction())
->setTransactionType(
+ PhabricatorCalendarEventTransaction::TYPE_RECURRING)
+ ->setNewValue($is_recurring);
+
+ $xactions[] = id(new PhabricatorCalendarEventTransaction())
+ ->setTransactionType(
PhabricatorCalendarEventTransaction::TYPE_ALL_DAY)
->setNewValue($is_all_day);
@@ -233,18 +240,26 @@
}
}
- Javelin::initBehavior('event-all-day', array(
- 'allDayID' => $all_day_id,
- 'startDateID' => $start_date_id,
- 'endDateID' => $end_date_id,
- ));
-
$name = id(new AphrontFormTextControl())
->setLabel(pht('Name'))
->setName('name')
->setValue($name)
->setError($error_name);
+ $is_recurring_checkbox = id(new AphrontFormCheckboxControl())
+ ->addCheckbox(
+ 'isRecurring',
+ 1,
+ pht('Recurring Event'),
+ $is_recurring,
+ $is_recurring_id);
+
+ Javelin::initBehavior('event-all-day', array(
+ 'allDayID' => $all_day_id,
+ 'startDateID' => $start_date_id,
+ 'endDateID' => $end_date_id,
+ ));
+
$all_day_checkbox = id(new AphrontFormCheckboxControl())
->addCheckbox(
'isAllDay',
@@ -323,6 +338,7 @@
->addHiddenInput('query', $uri_query)
->setUser($viewer)
->appendChild($name)
+ ->appendChild($is_recurring_checkbox)
->appendChild($all_day_checkbox)
->appendChild($start_control)
->appendChild($end_control)
diff --git a/src/applications/calendar/editor/PhabricatorCalendarEventEditor.php b/src/applications/calendar/editor/PhabricatorCalendarEventEditor.php
--- a/src/applications/calendar/editor/PhabricatorCalendarEventEditor.php
+++ b/src/applications/calendar/editor/PhabricatorCalendarEventEditor.php
@@ -23,6 +23,12 @@
$types[] = PhabricatorCalendarEventTransaction::TYPE_ALL_DAY;
$types[] = PhabricatorCalendarEventTransaction::TYPE_ICON;
+ $types[] = PhabricatorCalendarEventTransaction::TYPE_RECURRING;
+ $types[] = PhabricatorCalendarEventTransaction::TYPE_FREQUENCY;
+ $types[] = PhabricatorCalendarEventTransaction::TYPE_RECURRENCE_END_DATE;
+ $types[] = PhabricatorCalendarEventTransaction::TYPE_INSTANCE_OF_EVENT;
+ $types[] = PhabricatorCalendarEventTransaction::TYPE_SEQUENCE_INDEX;
+
$types[] = PhabricatorTransactions::TYPE_COMMENT;
$types[] = PhabricatorTransactions::TYPE_VIEW_POLICY;
$types[] = PhabricatorTransactions::TYPE_EDIT_POLICY;
@@ -34,6 +40,16 @@
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
+ case PhabricatorCalendarEventTransaction::TYPE_RECURRING:
+ return $object->getIsRecurring();
+ case PhabricatorCalendarEventTransaction::TYPE_FREQUENCY:
+ return $object->getRecurrenceFrequency();
+ case PhabricatorCalendarEventTransaction::TYPE_RECURRENCE_END_DATE:
+ return $object->getRecurrenceEndDate();
+ case PhabricatorCalendarEventTransaction::TYPE_INSTANCE_OF_EVENT:
+ return $object->getInstanceOfEventPHID();
+ case PhabricatorCalendarEventTransaction::TYPE_SEQUENCE_INDEX:
+ return $object->getSequenceIndex();
case PhabricatorCalendarEventTransaction::TYPE_NAME:
return $object->getName();
case PhabricatorCalendarEventTransaction::TYPE_START_DATE:
@@ -72,6 +88,11 @@
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
+ case PhabricatorCalendarEventTransaction::TYPE_RECURRING:
+ case PhabricatorCalendarEventTransaction::TYPE_FREQUENCY:
+ case PhabricatorCalendarEventTransaction::TYPE_RECURRENCE_END_DATE:
+ case PhabricatorCalendarEventTransaction::TYPE_INSTANCE_OF_EVENT:
+ case PhabricatorCalendarEventTransaction::TYPE_SEQUENCE_INDEX:
case PhabricatorCalendarEventTransaction::TYPE_NAME:
case PhabricatorCalendarEventTransaction::TYPE_DESCRIPTION:
case PhabricatorCalendarEventTransaction::TYPE_CANCEL:
@@ -93,8 +114,18 @@
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
+ case PhabricatorCalendarEventTransaction::TYPE_RECURRING:
+ return $object->setIsRecurring($xaction->getNewValue());
+ case PhabricatorCalendarEventTransaction::TYPE_FREQUENCY:
+ return $object->setRecurrenceFrequency($xaction->getNewValue());
+ case PhabricatorCalendarEventTransaction::TYPE_RECURRENCE_END_DATE:
+ return $object->setRecurrenceEndDate($xaction->getNewValue());
+ case PhabricatorCalendarEventTransaction::TYPE_INSTANCE_OF_EVENT:
+ return $object->setInstanceOfEventPHID($xaction->getNewValue());
+ case PhabricatorCalendarEventTransaction::TYPE_SEQUENCE_INDEX:
+ return $object->setSequenceIndex($xaction->getNewValue());
case PhabricatorCalendarEventTransaction::TYPE_NAME:
- $object->setName($xaction->getNewValue());
+ $object->setName($xaction->getNewValue($xaction->getNewValue()));
return;
case PhabricatorCalendarEventTransaction::TYPE_START_DATE:
$object->setDateFrom($xaction->getNewValue());
@@ -126,6 +157,11 @@
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
+ case PhabricatorCalendarEventTransaction::TYPE_RECURRING:
+ case PhabricatorCalendarEventTransaction::TYPE_FREQUENCY:
+ case PhabricatorCalendarEventTransaction::TYPE_RECURRENCE_END_DATE:
+ case PhabricatorCalendarEventTransaction::TYPE_INSTANCE_OF_EVENT:
+ case PhabricatorCalendarEventTransaction::TYPE_SEQUENCE_INDEX:
case PhabricatorCalendarEventTransaction::TYPE_NAME:
case PhabricatorCalendarEventTransaction::TYPE_START_DATE:
case PhabricatorCalendarEventTransaction::TYPE_END_DATE:
@@ -181,6 +217,11 @@
switch ($xaction->getTransactionType()) {
case PhabricatorCalendarEventTransaction::TYPE_ICON:
break;
+ case PhabricatorCalendarEventTransaction::TYPE_RECURRING:
+ case PhabricatorCalendarEventTransaction::TYPE_FREQUENCY:
+ case PhabricatorCalendarEventTransaction::TYPE_RECURRENCE_END_DATE:
+ case PhabricatorCalendarEventTransaction::TYPE_INSTANCE_OF_EVENT:
+ case PhabricatorCalendarEventTransaction::TYPE_SEQUENCE_INDEX:
case PhabricatorCalendarEventTransaction::TYPE_START_DATE:
case PhabricatorCalendarEventTransaction::TYPE_END_DATE:
case PhabricatorCalendarEventTransaction::TYPE_CANCEL:
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
@@ -20,6 +20,13 @@
protected $icon;
protected $mailKey;
+ protected $isRecurring = 0;
+ protected $recurrenceFrequency = array();
+ protected $recurrenceEndDate;
+
+ protected $instanceOfEventPHID;
+ protected $sequenceIndex;
+
protected $viewPolicy;
protected $editPolicy;
@@ -36,8 +43,13 @@
->withClasses(array('PhabricatorCalendarApplication'))
->executeOne();
+ $view_policy = null;
+ $is_recurring = 0;
+
if ($mode == 'public') {
$view_policy = PhabricatorPolicies::getMostOpenPolicy();
+ } else if ($mode == 'recurring') {
+ $is_recurring = true;
} else {
$view_policy = $actor->getPHID();
}
@@ -46,6 +58,7 @@
->setUserPHID($actor->getPHID())
->setIsCancelled(0)
->setIsAllDay(0)
+ ->setIsRecurring($is_recurring)
->setIcon(self::DEFAULT_ICON)
->setViewPolicy($view_policy)
->setEditPolicy($actor->getPHID())
@@ -180,12 +193,19 @@
'isAllDay' => 'bool',
'icon' => 'text32',
'mailKey' => 'bytes20',
+ 'isRecurring' => 'bool',
+ 'recurrenceEndDate' => 'epoch?',
+ 'instanceOfEventPHID' => 'phid?',
+ 'sequenceIndex' => 'uint32?',
),
self::CONFIG_KEY_SCHEMA => array(
'userPHID_dateFrom' => array(
'columns' => array('userPHID', 'dateTo'),
),
),
+ self::CONFIG_SERIALIZATION => array(
+ 'recurrenceFrequency' => self::SERIALIZATION_JSON,
+ ),
) + parent::getConfiguration();
}
diff --git a/src/applications/calendar/storage/PhabricatorCalendarEventTransaction.php b/src/applications/calendar/storage/PhabricatorCalendarEventTransaction.php
--- a/src/applications/calendar/storage/PhabricatorCalendarEventTransaction.php
+++ b/src/applications/calendar/storage/PhabricatorCalendarEventTransaction.php
@@ -12,6 +12,13 @@
const TYPE_ICON = 'calendar.icon';
const TYPE_INVITE = 'calendar.invite';
+ const TYPE_RECURRING = 'calendar.recurring';
+ const TYPE_FREQUENCY = 'calendar.frequency';
+ const TYPE_RECURRENCE_END_DATE = 'calendar.recurrenceenddate';
+
+ const TYPE_INSTANCE_OF_EVENT = 'calendar.instanceofevent';
+ const TYPE_SEQUENCE_INDEX = 'calendar.sequenceindex';
+
const MAILTAG_RESCHEDULE = 'calendar-reschedule';
const MAILTAG_CONTENT = 'calendar-content';
const MAILTAG_OTHER = 'calendar-other';
@@ -38,6 +45,11 @@
case self::TYPE_DESCRIPTION:
case self::TYPE_CANCEL:
case self::TYPE_ALL_DAY:
+ case self::TYPE_RECURRING:
+ case self::TYPE_FREQUENCY:
+ case self::TYPE_RECURRENCE_END_DATE:
+ case self::TYPE_INSTANCE_OF_EVENT:
+ case self::TYPE_SEQUENCE_INDEX:
$phids[] = $this->getObjectPHID();
break;
case self::TYPE_INVITE:
@@ -60,6 +72,11 @@
case self::TYPE_CANCEL:
case self::TYPE_ALL_DAY:
case self::TYPE_INVITE:
+ case self::TYPE_RECURRING:
+ case self::TYPE_FREQUENCY:
+ case self::TYPE_RECURRENCE_END_DATE:
+ case self::TYPE_INSTANCE_OF_EVENT:
+ case self::TYPE_SEQUENCE_INDEX:
return ($old === null);
}
return parent::shouldHide();
@@ -75,6 +92,11 @@
case self::TYPE_DESCRIPTION:
case self::TYPE_ALL_DAY:
case self::TYPE_CANCEL:
+ case self::TYPE_RECURRING:
+ case self::TYPE_FREQUENCY:
+ case self::TYPE_RECURRENCE_END_DATE:
+ case self::TYPE_INSTANCE_OF_EVENT:
+ case self::TYPE_SEQUENCE_INDEX:
return 'fa-pencil';
break;
case self::TYPE_INVITE:
@@ -231,6 +253,12 @@
}
}
return $text;
+ case self::TYPE_RECURRING:
+ case self::TYPE_FREQUENCY:
+ case self::TYPE_RECURRENCE_END_DATE:
+ case self::TYPE_INSTANCE_OF_EVENT:
+ case self::TYPE_SEQUENCE_INDEX:
+ return pht('Recurring event has been updated');
}
return parent::getTitle();
}
@@ -411,6 +439,12 @@
}
}
return $text;
+ case self::TYPE_RECURRING:
+ case self::TYPE_FREQUENCY:
+ case self::TYPE_RECURRENCE_END_DATE:
+ case self::TYPE_INSTANCE_OF_EVENT:
+ case self::TYPE_SEQUENCE_INDEX:
+ return pht('Recurring event has been updated');
}
return parent::getTitleForFeed();

File Metadata

Mime Type
text/plain
Expires
Sun, Mar 30, 10:09 PM (3 w, 2 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7727578
Default Alt Text
D13039.id31482.diff (13 KB)

Event Timeline