Page MenuHomePhabricator

D12586.id30220.diff
No OneTemporary

D12586.id30220.diff

diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -1484,16 +1484,20 @@
'PhabricatorCalendarEvent' => 'applications/calendar/storage/PhabricatorCalendarEvent.php',
'PhabricatorCalendarEventDeleteController' => 'applications/calendar/controller/PhabricatorCalendarEventDeleteController.php',
'PhabricatorCalendarEventEditController' => 'applications/calendar/controller/PhabricatorCalendarEventEditController.php',
+ 'PhabricatorCalendarEventEditor' => 'applications/calendar/editor/PhabricatorCalendarEventEditor.php',
'PhabricatorCalendarEventInvalidEpochException' => 'applications/calendar/exception/PhabricatorCalendarEventInvalidEpochException.php',
'PhabricatorCalendarEventListController' => 'applications/calendar/controller/PhabricatorCalendarEventListController.php',
'PhabricatorCalendarEventPHIDType' => 'applications/calendar/phid/PhabricatorCalendarEventPHIDType.php',
'PhabricatorCalendarEventQuery' => 'applications/calendar/query/PhabricatorCalendarEventQuery.php',
'PhabricatorCalendarEventSearchEngine' => 'applications/calendar/query/PhabricatorCalendarEventSearchEngine.php',
+ 'PhabricatorCalendarEventTransaction' => 'applications/calendar/storage/PhabricatorCalendarEventTransaction.php',
+ 'PhabricatorCalendarEventTransactionQuery' => 'applications/calendar/query/PhabricatorCalendarEventTransactionQuery.php',
'PhabricatorCalendarEventViewController' => 'applications/calendar/controller/PhabricatorCalendarEventViewController.php',
'PhabricatorCalendarHoliday' => 'applications/calendar/storage/PhabricatorCalendarHoliday.php',
'PhabricatorCalendarHolidayTestCase' => 'applications/calendar/storage/__tests__/PhabricatorCalendarHolidayTestCase.php',
'PhabricatorCalendarRemarkupRule' => 'applications/calendar/remarkup/PhabricatorCalendarRemarkupRule.php',
'PhabricatorCalendarSchemaSpec' => 'applications/calendar/storage/PhabricatorCalendarSchemaSpec.php',
+ 'PhabricatorCalendarTransactionComment' => 'applications/calendar/storage/PhabricatorCalendarTransactionComment.php',
'PhabricatorCalendarViewController' => 'applications/calendar/controller/PhabricatorCalendarViewController.php',
'PhabricatorCampfireProtocolAdapter' => 'infrastructure/daemon/bot/adapter/PhabricatorCampfireProtocolAdapter.php',
'PhabricatorCelerityApplication' => 'applications/celerity/application/PhabricatorCelerityApplication.php',
@@ -4802,19 +4806,24 @@
'PhabricatorCalendarDAO',
'PhabricatorPolicyInterface',
'PhabricatorMarkupInterface',
+ 'PhabricatorApplicationTransactionInterface',
),
'PhabricatorCalendarEventDeleteController' => 'PhabricatorCalendarController',
'PhabricatorCalendarEventEditController' => 'PhabricatorCalendarController',
+ 'PhabricatorCalendarEventEditor' => 'PhabricatorApplicationTransactionEditor',
'PhabricatorCalendarEventInvalidEpochException' => 'Exception',
'PhabricatorCalendarEventListController' => 'PhabricatorCalendarController',
'PhabricatorCalendarEventPHIDType' => 'PhabricatorPHIDType',
'PhabricatorCalendarEventQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorCalendarEventSearchEngine' => 'PhabricatorApplicationSearchEngine',
+ 'PhabricatorCalendarEventTransaction' => 'PhabricatorApplicationTransaction',
+ 'PhabricatorCalendarEventTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'PhabricatorCalendarEventViewController' => 'PhabricatorCalendarController',
'PhabricatorCalendarHoliday' => 'PhabricatorCalendarDAO',
'PhabricatorCalendarHolidayTestCase' => 'PhabricatorTestCase',
'PhabricatorCalendarRemarkupRule' => 'PhabricatorObjectRemarkupRule',
'PhabricatorCalendarSchemaSpec' => 'PhabricatorConfigSchemaSpec',
+ 'PhabricatorCalendarTransactionComment' => 'PhabricatorApplicationTransactionComment',
'PhabricatorCalendarViewController' => 'PhabricatorCalendarController',
'PhabricatorCampfireProtocolAdapter' => 'PhabricatorBotBaseStreamingProtocolAdapter',
'PhabricatorCelerityApplication' => 'PhabricatorApplication',
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
@@ -61,6 +61,7 @@
$errors = array();
if ($request->isFormPost()) {
+ $xactions = array();
$type = $request->getInt('status');
$start_value = $start_time->readValueFromRequest($request);
$end_value = $end_time->readValueFromRequest($request);
@@ -73,39 +74,33 @@
$errors[] = pht('Invalid end time; reset to default.');
}
if (!$errors) {
- try {
- $status
- ->setUserPHID($user->getPHID())
- ->setStatus($type)
- ->setDateFrom($start_value)
- ->setDateTo($end_value)
- ->setDescription($description)
- ->save();
- } catch (PhabricatorCalendarEventInvalidEpochException $e) {
- $errors[] = pht('Start must be before end.');
- }
- }
-
- if (!$errors) {
- $uri = new PhutilURI($this->getApplicationURI());
- $uri->setQueryParams(
- array(
- 'month' => phabricator_format_local_time($status->getDateFrom(),
- $user,
- 'm'),
- 'year' => phabricator_format_local_time($status->getDateFrom(),
- $user,
- 'Y'),
- $redirect => true,
- ));
- if ($request->isAjax()) {
- $response = id(new AphrontAjaxResponse())
- ->setContent(array('redirect_uri' => $uri));
- } else {
- $response = id(new AphrontRedirectResponse())
- ->setURI($uri);
- }
- return $response;
+ $xactions[] = id(new PhabricatorCalendarEventTransaction())
+ ->setTransactionType(
+ PhabricatorCalendarEventTransaction::TYPE_START_DATE)
+ ->setNewValue($start_value);
+
+ $xactions[] = id(new PhabricatorCalendarEventTransaction())
+ ->setTransactionType(
+ PhabricatorCalendarEventTransaction::TYPE_END_DATE)
+ ->setNewValue($end_value);
+
+ $xactions[] = id(new PhabricatorCalendarEventTransaction())
+ ->setTransactionType(
+ PhabricatorCalendarEventTransaction::TYPE_STATUS)
+ ->setNewValue($type);
+
+ $xactions[] = id(new PhabricatorCalendarEventTransaction())
+ ->setTransactionType(
+ PhabricatorCalendarEventTransaction::TYPE_DESCRIPTION)
+ ->setNewValue($description);
+
+ $editor = id(new PhabricatorCalendarEventEditor())
+ ->setActor($user)
+ ->setContentSourceFromRequest($request)
+ ->setContinueOnNoEffect(true);
+
+ $xactions = $editor->applyTransactions($status, $xactions);
+ return id(new AphrontRedirectResponse())->setURI('/E'.$status->getId());
}
}
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
@@ -29,6 +29,10 @@
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb($title, '/E'.$event->getID());
+ $timeline = $this->buildTransactionTimeline(
+ $event,
+ new PhabricatorCalendarEventTransactionQuery());
+
$header = $this->buildHeaderView($event);
$actions = $this->buildActionView($event);
$properties = $this->buildPropertyView($event);
@@ -42,6 +46,7 @@
array(
$crumbs,
$box,
+ $timeline,
),
array(
'title' => $title,
diff --git a/src/applications/calendar/editor/PhabricatorCalendarEventEditor.php b/src/applications/calendar/editor/PhabricatorCalendarEventEditor.php
new file mode 100644
--- /dev/null
+++ b/src/applications/calendar/editor/PhabricatorCalendarEventEditor.php
@@ -0,0 +1,172 @@
+<?php
+
+final class PhabricatorCalendarEventEditor
+ extends PhabricatorApplicationTransactionEditor {
+
+ public function getEditorApplicationClass() {
+ return 'PhabricatorCalendarApplication';
+ }
+
+ public function getEditorObjectsDescription() {
+ return pht('Calendar');
+ }
+
+ public function getTransactionTypes() {
+ $types = parent::getTransactionTypes();
+
+ $types[] = PhabricatorCalendarEventTransaction::TYPE_START_DATE;
+ $types[] = PhabricatorCalendarEventTransaction::TYPE_END_DATE;
+ $types[] = PhabricatorCalendarEventTransaction::TYPE_STATUS;
+ $types[] = PhabricatorCalendarEventTransaction::TYPE_DESCRIPTION;
+
+ $types[] = PhabricatorTransactions::TYPE_VIEW_POLICY;
+ $types[] = PhabricatorTransactions::TYPE_EDIT_POLICY;
+
+ return $types;
+ }
+
+ protected function getCustomTransactionOldValue(
+ PhabricatorLiskDAO $object,
+ PhabricatorApplicationTransaction $xaction) {
+ switch ($xaction->getTransactionType()) {
+ case PhabricatorCalendarEventTransaction::TYPE_START_DATE:
+ return $object->getDateFrom();
+ case PhabricatorCalendarEventTransaction::TYPE_END_DATE:
+ return $object->getDateTo();
+ case PhabricatorCalendarEventTransaction::TYPE_STATUS:
+ return $object->getStatus();
+ case PhabricatorCalendarEventTransaction::TYPE_DESCRIPTION:
+ return $object->getDescription();
+ }
+
+ return parent::getCustomTransactionOldValue($object, $xaction);
+ }
+
+ protected function getCustomTransactionNewValue(
+ PhabricatorLiskDAO $object,
+ PhabricatorApplicationTransaction $xaction) {
+
+ switch ($xaction->getTransactionType()) {
+ case PhabricatorCalendarEventTransaction::TYPE_START_DATE:
+ case PhabricatorCalendarEventTransaction::TYPE_END_DATE:
+ case PhabricatorCalendarEventTransaction::TYPE_STATUS:
+ case PhabricatorCalendarEventTransaction::TYPE_DESCRIPTION:
+ return $xaction->getNewValue();
+ }
+
+ return parent::getCustomTransactionNewValue($object, $xaction);
+ }
+
+ protected function applyCustomInternalTransaction(
+ PhabricatorLiskDAO $object,
+ PhabricatorApplicationTransaction $xaction) {
+
+ switch ($xaction->getTransactionType()) {
+ case PhabricatorCalendarEventTransaction::TYPE_START_DATE:
+ $object->setDateFrom($xaction->getNewValue());
+ return;
+ case PhabricatorCalendarEventTransaction::TYPE_END_DATE:
+ $object->setDateTo($xaction->getNewValue());
+ return;
+ case PhabricatorCalendarEventTransaction::TYPE_STATUS:
+ $object->setStatus($xaction->getNewValue());
+ return;
+ case PhabricatorCalendarEventTransaction::TYPE_DESCRIPTION:
+ $object->setDescription($xaction->getNewValue());
+ return;
+ case PhabricatorTransactions::TYPE_VIEW_POLICY:
+ case PhabricatorTransactions::TYPE_EDIT_POLICY:
+ case PhabricatorTransactions::TYPE_EDGE:
+ return;
+ }
+
+ return parent::applyCustomInternalTransaction($object, $xaction);
+ }
+
+ protected function applyCustomExternalTransaction(
+ PhabricatorLiskDAO $object,
+ PhabricatorApplicationTransaction $xaction) {
+
+ switch ($xaction->getTransactionType()) {
+ case PhabricatorCalendarEventTransaction::TYPE_START_DATE:
+ case PhabricatorCalendarEventTransaction::TYPE_END_DATE:
+ case PhabricatorCalendarEventTransaction::TYPE_STATUS:
+ case PhabricatorCalendarEventTransaction::TYPE_DESCRIPTION:
+ case PhabricatorTransactions::TYPE_VIEW_POLICY:
+ case PhabricatorTransactions::TYPE_EDIT_POLICY:
+ case PhabricatorTransactions::TYPE_EDGE:
+ return;
+ }
+
+ return parent::applyCustomExternalTransaction($object, $xaction);
+ }
+
+ // protected function validateTransaction(
+ // PhabricatorLiskDAO $object,
+ // $type,
+ // array $xactions) {
+
+ // $errors = parent::validateTransaction($object, $type, $xactions);
+
+ // switch ($type) {
+ // case PhabricatorCalendarEventTransaction::TYPE_START_DATE:
+ // $missing = $this->validateIsEmptyTextField(
+ // $object->getDateFrom(),
+ // $xactions);
+
+ // if ($missing) {
+ // $error = new PhabricatorApplicationTransactionValidationError(
+ // $type,
+ // pht('Required'),
+ // pht('Service name is required.'),
+ // nonempty(last($xactions), null));
+
+ // $error->setIsMissingFieldError(true);
+ // $errors[] = $error;
+ // } else {
+ // foreach ($xactions as $xaction) {
+ // $message = null;
+
+ // $name = $xaction->getNewValue();
+
+ // try {
+ // AlmanacNames::validateServiceOrDeviceName($name);
+ // } catch (Exception $ex) {
+ // $message = $ex->getMessage();
+ // }
+
+ // if ($message !== null) {
+ // $error = new PhabricatorApplicationTransactionValidationError(
+ // $type,
+ // pht('Invalid'),
+ // $message,
+ // $xaction);
+ // $errors[] = $error;
+ // }
+ // }
+ // }
+
+ // if ($xactions) {
+ // $duplicate = id(new AlmanacServiceQuery())
+ // ->setViewer(PhabricatorUser::getOmnipotentUser())
+ // ->withNames(array(last($xactions)->getNewValue()))
+ // ->executeOne();
+ // if ($duplicate && ($duplicate->getID() != $object->getID())) {
+ // $error = new PhabricatorApplicationTransactionValidationError(
+ // $type,
+ // pht('Not Unique'),
+ // pht('Almanac services must have unique names.'),
+ // last($xactions));
+ // $errors[] = $error;
+ // }
+ // }
+
+ // break;
+ // }
+
+ // return $errors;
+ // }
+
+
+
+}
diff --git a/src/applications/calendar/query/PhabricatorCalendarEventTransactionQuery.php b/src/applications/calendar/query/PhabricatorCalendarEventTransactionQuery.php
new file mode 100644
--- /dev/null
+++ b/src/applications/calendar/query/PhabricatorCalendarEventTransactionQuery.php
@@ -0,0 +1,10 @@
+<?php
+
+final class PhabricatorCalendarEventTransactionQuery
+ extends PhabricatorApplicationTransactionQuery {
+
+ public function getTemplateApplicationTransaction() {
+ return new PhabricatorCalendarEventTransaction();
+ }
+
+}
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
@@ -2,7 +2,8 @@
final class PhabricatorCalendarEvent extends PhabricatorCalendarDAO
implements PhabricatorPolicyInterface,
- PhabricatorMarkupInterface {
+ PhabricatorMarkupInterface,
+ PhabricatorApplicationTransactionInterface {
protected $userPHID;
protected $dateFrom;
@@ -86,6 +87,17 @@
return mpull($statuses, null, 'getUserPHID');
}
+ public static function getNameForStatus($value) {
+ switch ($value) {
+ case self::STATUS_AWAY:
+ return pht('Away');
+ case self::STATUS_SPORADIC:
+ return pht('Sporadic');
+ default:
+ return pht('Unknown');
+ }
+ }
+
/**
* Validates data and throws exceptions for non-sensical status
* windows
@@ -173,4 +185,26 @@
return null;
}
+/* -( PhabricatorApplicationTransactionInterface )------------------------- */
+
+
+ public function getApplicationTransactionEditor() {
+ return new PhabricatorCalendarEventEditor();
+ }
+
+ public function getApplicationTransactionObject() {
+ return $this;
+ }
+
+ public function getApplicationTransactionTemplate() {
+ return new PhabricatorCalendarEventTransaction();
+ }
+
+ public function willRenderTimeline(
+ PhabricatorApplicationTransactionView $timeline,
+ AphrontRequest $request) {
+
+ return $timeline;
+ }
+
}
diff --git a/src/applications/calendar/storage/PhabricatorCalendarEventTransaction.php b/src/applications/calendar/storage/PhabricatorCalendarEventTransaction.php
new file mode 100644
--- /dev/null
+++ b/src/applications/calendar/storage/PhabricatorCalendarEventTransaction.php
@@ -0,0 +1,212 @@
+<?php
+
+final class PhabricatorCalendarEventTransaction
+ extends PhabricatorApplicationTransaction {
+
+ const TYPE_START_DATE = 'calendar.startdate';
+ const TYPE_END_DATE = 'calendar.enddate';
+ const TYPE_STATUS = 'calendar.status';
+ const TYPE_DESCRIPTION = 'calendar.description';
+
+ const MAILTAG_START_DATE = 'calendar-startdate';
+ const MAILTAG_END_DATE = 'calendar-enddate';
+ const MAILTAG_STATUS = 'calendar-status';
+ const MAILTAG_DESCRIPTION = 'calendar-description';
+
+ public function getApplicationName() {
+ return 'calendar';
+ }
+
+ public function getApplicationTransactionType() {
+ return PhabricatorCalendarEventPHIDType::TYPECONST;
+ }
+
+ public function getApplicationTransactionCommentObject() {
+ return new PhrictionTransactionComment();
+ }
+
+ public function getRequiredHandlePHIDs() {
+ $phids = parent::getRequiredHandlePHIDs();
+
+ switch ($this->getTransactionType()) {
+ case self::TYPE_START_DATE:
+ case self::TYPE_END_DATE:
+ case self::TYPE_STATUS:
+ case self::TYPE_DESCRIPTION:
+ $phids[] = $this->getObjectPHID();
+ break;
+ }
+
+ return $phids;
+ }
+
+ public function shouldHide() {
+ $old = $this->getOldValue();
+ switch ($this->getTransactionType()) {
+ case self::TYPE_START_DATE:
+ case self::TYPE_END_DATE:
+ case self::TYPE_STATUS:
+ case self::TYPE_DESCRIPTION:
+ return ($old === null);
+ }
+ return parent::shouldHide();
+ }
+
+ public function getIcon() {
+ switch ($this->getTransactionType()) {
+ case self::TYPE_START_DATE:
+ case self::TYPE_END_DATE:
+ case self::TYPE_STATUS:
+ case self::TYPE_DESCRIPTION:
+ return 'fa-pencil';
+ break;
+ }
+ return parent::getIcon();
+ }
+
+ public function getTitle() {
+ $author_phid = $this->getAuthorPHID();
+ $object_phid = $this->getObjectPHID();
+
+ $old = $this->getOldValue();
+ $new = $this->getNewValue();
+
+ $type = $this->getTransactionType();
+ switch ($type) {
+ case self::TYPE_START_DATE:
+ if ($old) {
+ return pht(
+ '%s edited the start date of this event.',
+ $this->renderHandleLink($author_phid));
+ }
+ break;
+ case self::TYPE_END_DATE:
+ if ($old) {
+ return pht(
+ '%s edited the end date of this event.',
+ $this->renderHandleLink($author_phid));
+ }
+ break;
+ case self::TYPE_STATUS:
+ $old_name = PhabricatorCalendarEvent::getNameForStatus($old);
+ $new_name = PhabricatorCalendarEvent::getNameForStatus($new);
+ return pht(
+ '%s updated the event status from %s to %s.',
+ $this->renderHandleLink($author_phid),
+ $old_name,
+ $new_name);
+ break;
+ case self::TYPE_DESCRIPTION:
+ return pht(
+ "%s updated the event's description.",
+ $this->renderHandleLink($author_phid));
+ break;
+ }
+
+ return parent::getTitle();
+ }
+
+ public function getTitleForFeed() {
+ $author_phid = $this->getAuthorPHID();
+ $object_phid = $this->getObjectPHID();
+
+ $old = $this->getOldValue();
+ $new = $this->getNewValue();
+
+ $type = $this->getTransactionType();
+ switch ($type) {
+ case self::TYPE_START_DATE:
+ if ($old) {
+ return pht(
+ '%s edited the start date of this event from %s to %s.',
+ $this->renderHandleLink($author_phid),
+ $old,
+ $new);
+ }
+ break;
+ case self::TYPE_END_DATE:
+ if ($old) {
+ return pht(
+ '%s edited the end date of this event from %s to %s.',
+ $this->renderHandleLink($author_phid),
+ $old,
+ $new);
+ }
+ break;
+ case self::TYPE_STATUS:
+ return pht(
+ '%s updated the event status from %s to %s.',
+ $this->renderHandleLink($author_phid),
+ $old,
+ $new);
+ break;
+ case self::TYPE_DESCRIPTION:
+ return pht(
+ "%s updated the event's description.",
+ $this->renderHandleLink($author_phid));
+ break;
+ }
+
+ return parent::getTitleForFeed();
+ }
+
+ public function getColor() {
+ $old = $this->getOldValue();
+ $new = $this->getNewValue();
+
+ switch ($this->getTransactionType()) {
+ case self::TYPE_START_DATE:
+ case self::TYPE_END_DATE:
+ case self::TYPE_STATUS:
+ case self::TYPE_DESCRIPTION:
+ return PhabricatorTransactions::COLOR_GREEN;
+ }
+
+ return parent::getColor();
+ }
+
+
+ public function hasChangeDetails() {
+ switch ($this->getTransactionType()) {
+ case self::TYPE_DESCRIPTION:
+ return ($this->getOldValue() !== null);
+ }
+
+ return parent::hasChangeDetails();
+ }
+
+ public function renderChangeDetails(PhabricatorUser $viewer) {
+ switch ($this->getTransactionType()) {
+ case self::TYPE_DESCRIPTION:
+ $old = $this->getOldValue();
+ $new = $this->getNewValue();
+
+ return $this->renderTextCorpusChangeDetails(
+ $viewer,
+ $old,
+ $new);
+ }
+
+ return parent::renderChangeDetails($viewer);
+ }
+
+ public function getMailTags() {
+ $tags = array();
+ switch ($this->getTransactionType()) {
+ case self::TYPE_START_DATE:
+ $tags[] = self::MAILTAG_START_DATE;
+ break;
+ case self::TYPE_END_DATE:
+ $tags[] = self::MAILTAG_END_DATE;
+ break;
+ case self::TYPE_STATUS:
+ $tags[] = self::MAILTAG_STATUS;
+ break;
+ case self::TYPE_DESCRIPTION:
+ $tags[] = self::MAILTAG_DESCRIPTION;
+ break;
+ }
+ return $tags;
+ }
+
+}
diff --git a/src/applications/calendar/storage/PhabricatorCalendarTransactionComment.php b/src/applications/calendar/storage/PhabricatorCalendarTransactionComment.php
new file mode 100644
--- /dev/null
+++ b/src/applications/calendar/storage/PhabricatorCalendarTransactionComment.php
@@ -0,0 +1,10 @@
+<?php
+
+final class PhabricatorCalendarTransactionComment
+ extends PhabricatorApplicationTransactionComment {
+
+ public function getApplicationTransactionObject() {
+ return new PhabricatorCalendarEventTransaction();
+ }
+
+}

File Metadata

Mime Type
text/plain
Expires
Sat, May 11, 3:34 AM (3 w, 3 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6284769
Default Alt Text
D12586.id30220.diff (22 KB)

Event Timeline