From 43ab0e879fd92445422ae7bc2e72ca1f6425e780 Mon Sep 17 00:00:00 2001 From: lkassianik Date: Tue, 28 Apr 2015 08:34:26 -0700 Subject: [PATCH] Calendar events should now have a 'Name' field. Summary: Closes T7953, Calendar events should now have a 'Name' field. Test Plan: Create or edit event with no title, save event, should get error requiring name, event detail view timeline should reflect name changes. Reviewers: epriestley, #blessed_reviewers Reviewed By: epriestley, #blessed_reviewers Subscribers: Korvin, epriestley Maniphest Tasks: T7953 Differential Revision: https://secure.phabricator.com/D12591 --- .../autopatches/20150428.calendar.1.name.sql | 2 + ...PhabricatorCalendarEventEditController.php | 109 +++++++++--------- ...PhabricatorCalendarEventViewController.php | 9 +- .../editor/PhabricatorCalendarEventEditor.php | 37 ++++++ .../storage/PhabricatorCalendarEvent.php | 2 + .../PhabricatorCalendarEventTransaction.php | 27 +++++ 6 files changed, 128 insertions(+), 58 deletions(-) create mode 100644 resources/sql/autopatches/20150428.calendar.1.name.sql diff --git a/resources/sql/autopatches/20150428.calendar.1.name.sql b/resources/sql/autopatches/20150428.calendar.1.name.sql new file mode 100644 index 0000000000..7e5e8da6c9 --- /dev/null +++ b/resources/sql/autopatches/20150428.calendar.1.name.sql @@ -0,0 +1,2 @@ +ALTER TABLE {$NAMESPACE}_calendar.calendar_event + ADD name LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL; diff --git a/src/applications/calendar/controller/PhabricatorCalendarEventEditController.php b/src/applications/calendar/controller/PhabricatorCalendarEventEditController.php index a966afb8d3..378b27d5ce 100644 --- a/src/applications/calendar/controller/PhabricatorCalendarEventEditController.php +++ b/src/applications/calendar/controller/PhabricatorCalendarEventEditController.php @@ -14,8 +14,11 @@ final class PhabricatorCalendarEventEditController } public function processRequest() { - $request = $this->getRequest(); - $user = $request->getUser(); + $request = $this->getRequest(); + $user = $request->getUser(); + $error_name = true; + $validation_exception = null; + $start_time = id(new AphrontFormDateControl()) ->setUser($user) @@ -30,15 +33,15 @@ final class PhabricatorCalendarEventEditController ->setInitialTime(AphrontFormDateControl::TIME_END_OF_DAY); if ($this->isCreate()) { - $status = PhabricatorCalendarEvent::initializeNewCalendarEvent($user); + $event = PhabricatorCalendarEvent::initializeNewCalendarEvent($user); $end_value = $end_time->readValueFromRequest($request); $start_value = $start_time->readValueFromRequest($request); $submit_label = pht('Create'); - $filter = 'status/create/'; + $filter = 'event/create/'; $page_title = pht('Create Event'); $redirect = 'created'; } else { - $status = id(new PhabricatorCalendarEventQuery()) + $event = id(new PhabricatorCalendarEventQuery()) ->setViewer($user) ->withIDs(array($this->id)) ->requireCapabilities( @@ -47,24 +50,25 @@ final class PhabricatorCalendarEventEditController PhabricatorPolicyCapability::CAN_EDIT, )) ->executeOne(); - if (!$status) { + if (!$event) { return new Aphront404Response(); } - $end_time->setValue($status->getDateTo()); - $start_time->setValue($status->getDateFrom()); + $end_time->setValue($event->getDateTo()); + $start_time->setValue($event->getDateFrom()); $submit_label = pht('Update'); - $filter = 'event/edit/'.$status->getID().'/'; + $filter = 'event/edit/'.$event->getID().'/'; $page_title = pht('Update Event'); $redirect = 'updated'; } $errors = array(); if ($request->isFormPost()) { - $xactions = array(); - $type = $request->getInt('status'); + $xactions = array(); + $name = $request->getStr('name'); + $type = $request->getInt('status'); $start_value = $start_time->readValueFromRequest($request); - $end_value = $end_time->readValueFromRequest($request); + $end_value = $end_time->readValueFromRequest($request); $description = $request->getStr('description'); if ($start_time->getError()) { @@ -74,6 +78,11 @@ final class PhabricatorCalendarEventEditController $errors[] = pht('Invalid end time; reset to default.'); } if (!$errors) { + $xactions[] = id(new PhabricatorCalendarEventTransaction()) + ->setTransactionType( + PhabricatorCalendarEventTransaction::TYPE_NAME) + ->setNewValue($name); + $xactions[] = id(new PhabricatorCalendarEventTransaction()) ->setTransactionType( PhabricatorCalendarEventTransaction::TYPE_START_DATE) @@ -99,8 +108,15 @@ final class PhabricatorCalendarEventEditController ->setContentSourceFromRequest($request) ->setContinueOnNoEffect(true); - $xactions = $editor->applyTransactions($status, $xactions); - return id(new AphrontRedirectResponse())->setURI('/E'.$status->getID()); + try { + $xactions = $editor->applyTransactions($event, $xactions); + $response = id(new AphrontRedirectResponse()); + return $response->setURI('/E'.$event->getID()); + } catch (PhabricatorApplicationTransactionValidationException $ex) { + $validation_exception = $ex; + $error_name = $ex + ->getShortMessage(PhabricatorCalendarEventTransaction::TYPE_NAME); + } } } @@ -111,85 +127,66 @@ final class PhabricatorCalendarEventEditController ->setErrors($errors); } + $name = id(new AphrontFormTextControl()) + ->setLabel(pht('Name')) + ->setName('name') + ->setValue($event->getName()) + ->setError($error_name); + $status_select = id(new AphrontFormSelectControl()) ->setLabel(pht('Status')) ->setName('status') - ->setValue($status->getStatus()) - ->setOptions($status->getStatusOptions()); + ->setValue($event->getStatus()) + ->setOptions($event->getStatusOptions()); $description = id(new AphrontFormTextAreaControl()) ->setLabel(pht('Description')) ->setName('description') - ->setValue($status->getDescription()); + ->setValue($event->getDescription()); - if ($request->isAjax()) { - $dialog = id(new AphrontDialogView()) - ->setUser($user) - ->setTitle($page_title) - ->setWidth(AphrontDialogView::WIDTH_FORM); - if ($this->isCreate()) { - $dialog->setSubmitURI($this->getApplicationURI('event/create/')); - } else { - $dialog->setSubmitURI( - $this->getApplicationURI('event/edit/'.$status->getID().'/')); - } - $form = new PHUIFormLayoutView(); - if ($error_view) { - $form->appendChild($error_view); - } - } else { - $form = id(new AphrontFormView()) - ->setUser($user); - } - - $form + $form = id(new AphrontFormView()) + ->setUser($user) + ->appendChild($name) ->appendChild($status_select) ->appendChild($start_time) ->appendChild($end_time) ->appendChild($description); - if ($request->isAjax()) { - $dialog->addSubmitButton($submit_label); - $submit = $dialog; - } else { - $submit = id(new AphrontFormSubmitControl()) - ->setValue($submit_label); - } + $submit = id(new AphrontFormSubmitControl()) + ->setValue($submit_label); if ($this->isCreate()) { $submit->addCancelButton($this->getApplicationURI()); } else { - $submit->addCancelButton('/E'.$status->getID()); + $submit->addCancelButton('/E'.$event->getID()); } - if ($request->isAjax()) { - $dialog->appendChild($form); - return id(new AphrontDialogResponse()) - ->setDialog($dialog); - } $form->appendChild($submit); - - $form_box = id(new PHUIObjectBoxView()) ->setHeaderText($page_title) ->setFormErrors($errors) ->setForm($form); - $nav = $this->buildSideNavView($status); + $nav = $this->buildSideNavView($event); $nav->selectFilter($filter); $crumbs = $this->buildApplicationCrumbs(); if (!$this->isCreate()) { - $crumbs->addTextCrumb('E'.$status->getId(), '/E'.$status->getId()); + $crumbs->addTextCrumb('E'.$event->getId(), '/E'.$event->getId()); } $crumbs->addTextCrumb($page_title); + $object_box = id(new PHUIObjectBoxView()) + ->setHeaderText($page_title) + ->setValidationException($validation_exception) + ->appendChild($form); + $nav->appendChild( array( $crumbs, - $form_box, + $object_box, )); return $this->buildApplicationPage( diff --git a/src/applications/calendar/controller/PhabricatorCalendarEventViewController.php b/src/applications/calendar/controller/PhabricatorCalendarEventViewController.php index adb2542db7..0cf3d7401b 100644 --- a/src/applications/calendar/controller/PhabricatorCalendarEventViewController.php +++ b/src/applications/calendar/controller/PhabricatorCalendarEventViewController.php @@ -26,6 +26,7 @@ final class PhabricatorCalendarEventViewController } $title = 'E'.$event->getID(); + $page_title = $title.' '.$event->getName(); $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb($title, '/E'.$event->getID()); @@ -49,7 +50,7 @@ final class PhabricatorCalendarEventViewController $timeline, ), array( - 'title' => $title, + 'title' => $page_title, )); } @@ -58,7 +59,7 @@ final class PhabricatorCalendarEventViewController return id(new PHUIHeaderView()) ->setUser($viewer) - ->setHeader($event->getTerseSummary($viewer)) + ->setHeader($event->getName()) ->setPolicyObject($event); } @@ -101,6 +102,10 @@ final class PhabricatorCalendarEventViewController ->setUser($viewer) ->setObject($event); + // $properties->addProperty( + // pht('Name'), + // $event->getName()); + $properties->addProperty( pht('Starts'), phabricator_datetime($event->getDateFrom(), $viewer)); diff --git a/src/applications/calendar/editor/PhabricatorCalendarEventEditor.php b/src/applications/calendar/editor/PhabricatorCalendarEventEditor.php index e58a8df15d..b865bb85ac 100644 --- a/src/applications/calendar/editor/PhabricatorCalendarEventEditor.php +++ b/src/applications/calendar/editor/PhabricatorCalendarEventEditor.php @@ -14,6 +14,7 @@ final class PhabricatorCalendarEventEditor public function getTransactionTypes() { $types = parent::getTransactionTypes(); + $types[] = PhabricatorCalendarEventTransaction::TYPE_NAME; $types[] = PhabricatorCalendarEventTransaction::TYPE_START_DATE; $types[] = PhabricatorCalendarEventTransaction::TYPE_END_DATE; $types[] = PhabricatorCalendarEventTransaction::TYPE_STATUS; @@ -29,6 +30,8 @@ final class PhabricatorCalendarEventEditor PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction) { switch ($xaction->getTransactionType()) { + case PhabricatorCalendarEventTransaction::TYPE_NAME: + return $object->getName(); case PhabricatorCalendarEventTransaction::TYPE_START_DATE: return $object->getDateFrom(); case PhabricatorCalendarEventTransaction::TYPE_END_DATE: @@ -51,6 +54,7 @@ final class PhabricatorCalendarEventEditor PhabricatorApplicationTransaction $xaction) { switch ($xaction->getTransactionType()) { + case PhabricatorCalendarEventTransaction::TYPE_NAME: case PhabricatorCalendarEventTransaction::TYPE_START_DATE: case PhabricatorCalendarEventTransaction::TYPE_END_DATE: case PhabricatorCalendarEventTransaction::TYPE_DESCRIPTION: @@ -67,6 +71,9 @@ final class PhabricatorCalendarEventEditor PhabricatorApplicationTransaction $xaction) { switch ($xaction->getTransactionType()) { + case PhabricatorCalendarEventTransaction::TYPE_NAME: + $object->setName($xaction->getNewValue()); + return; case PhabricatorCalendarEventTransaction::TYPE_START_DATE: $object->setDateFrom($xaction->getNewValue()); return; @@ -93,6 +100,7 @@ final class PhabricatorCalendarEventEditor PhabricatorApplicationTransaction $xaction) { switch ($xaction->getTransactionType()) { + case PhabricatorCalendarEventTransaction::TYPE_NAME: case PhabricatorCalendarEventTransaction::TYPE_START_DATE: case PhabricatorCalendarEventTransaction::TYPE_END_DATE: case PhabricatorCalendarEventTransaction::TYPE_STATUS: @@ -105,4 +113,33 @@ final class PhabricatorCalendarEventEditor return parent::applyCustomExternalTransaction($object, $xaction); } + + protected function validateTransaction( + PhabricatorLiskDAO $object, + $type, + array $xactions) { + + $errors = parent::validateTransaction($object, $type, $xactions); + + switch ($type) { + case PhabricatorCalendarEventTransaction::TYPE_NAME: + $missing = $this->validateIsEmptyTextField( + $object->getName(), + $xactions); + + if ($missing) { + $error = new PhabricatorApplicationTransactionValidationError( + $type, + pht('Required'), + pht('Event name is required.'), + nonempty(last($xactions), null)); + + $error->setIsMissingFieldError(true); + $errors[] = $error; + } + break; + } + + return $errors; + } } diff --git a/src/applications/calendar/storage/PhabricatorCalendarEvent.php b/src/applications/calendar/storage/PhabricatorCalendarEvent.php index 6e277fedac..8d6ab918d2 100644 --- a/src/applications/calendar/storage/PhabricatorCalendarEvent.php +++ b/src/applications/calendar/storage/PhabricatorCalendarEvent.php @@ -5,6 +5,7 @@ final class PhabricatorCalendarEvent extends PhabricatorCalendarDAO PhabricatorMarkupInterface, PhabricatorApplicationTransactionInterface { + protected $name; protected $userPHID; protected $dateFrom; protected $dateTo; @@ -49,6 +50,7 @@ final class PhabricatorCalendarEvent extends PhabricatorCalendarDAO return array( self::CONFIG_AUX_PHID => true, self::CONFIG_COLUMN_SCHEMA => array( + 'name' => 'text', 'dateFrom' => 'epoch', 'dateTo' => 'epoch', 'status' => 'uint32', diff --git a/src/applications/calendar/storage/PhabricatorCalendarEventTransaction.php b/src/applications/calendar/storage/PhabricatorCalendarEventTransaction.php index 4f5892a24b..c17bf0905f 100644 --- a/src/applications/calendar/storage/PhabricatorCalendarEventTransaction.php +++ b/src/applications/calendar/storage/PhabricatorCalendarEventTransaction.php @@ -3,6 +3,7 @@ final class PhabricatorCalendarEventTransaction extends PhabricatorApplicationTransaction { + const TYPE_NAME = 'calendar.name'; const TYPE_START_DATE = 'calendar.startdate'; const TYPE_END_DATE = 'calendar.enddate'; const TYPE_STATUS = 'calendar.status'; @@ -27,6 +28,7 @@ final class PhabricatorCalendarEventTransaction $phids = parent::getRequiredHandlePHIDs(); switch ($this->getTransactionType()) { + case self::TYPE_NAME: case self::TYPE_START_DATE: case self::TYPE_END_DATE: case self::TYPE_STATUS: @@ -41,6 +43,7 @@ final class PhabricatorCalendarEventTransaction public function shouldHide() { $old = $this->getOldValue(); switch ($this->getTransactionType()) { + case self::TYPE_NAME: case self::TYPE_START_DATE: case self::TYPE_END_DATE: case self::TYPE_STATUS: @@ -52,6 +55,7 @@ final class PhabricatorCalendarEventTransaction public function getIcon() { switch ($this->getTransactionType()) { + case self::TYPE_NAME: case self::TYPE_START_DATE: case self::TYPE_END_DATE: case self::TYPE_STATUS: @@ -71,6 +75,15 @@ final class PhabricatorCalendarEventTransaction $type = $this->getTransactionType(); switch ($type) { + case self::TYPE_NAME: + if ($old) { + return pht( + '%s changed the name of this event from %s to %s.', + $this->renderHandleLink($author_phid), + $old, + $new); + } + break; case self::TYPE_START_DATE: if ($old) { return pht( @@ -113,6 +126,16 @@ final class PhabricatorCalendarEventTransaction $type = $this->getTransactionType(); switch ($type) { + case self::TYPE_NAME: + if ($old) { + return pht( + '%s changed the name of %s from %s to %s.', + $this->renderHandleLink($author_phid), + $this->renderHandleLink($object_phid), + $old, + $new); + } + break; case self::TYPE_START_DATE: if ($old) { return pht( @@ -153,6 +176,7 @@ final class PhabricatorCalendarEventTransaction $new = $this->getNewValue(); switch ($this->getTransactionType()) { + case self::TYPE_NAME: case self::TYPE_START_DATE: case self::TYPE_END_DATE: case self::TYPE_STATUS: @@ -191,6 +215,9 @@ final class PhabricatorCalendarEventTransaction public function getMailTags() { $tags = array(); switch ($this->getTransactionType()) { + case self::TYPE_NAME: + $tags[] = self::MAILTAG_CONTENT; + break; case self::TYPE_START_DATE: $tags[] = self::MAILTAG_CONTENT; break;