mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-20 05:42:40 +01:00
Fix datepicker to show correct error messages on Calendar event edit view
Summary: Ref T8024, Fix datepicker to show correct error messages on Calendar event edit view. Test Plan: Edit Calendar event, set blank title, and valid new end time, error page should correctly point out invalid title, but reflec the updated time. Reviewers: #blessed_reviewers, epriestley Reviewed By: #blessed_reviewers, epriestley Subscribers: Korvin, epriestley Maniphest Tasks: T8024 Differential Revision: https://secure.phabricator.com/D12647
This commit is contained in:
parent
aa68cc8830
commit
bd0eef3594
5 changed files with 211 additions and 89 deletions
|
@ -114,6 +114,7 @@ phutil_register_library_map(array(
|
||||||
'AphrontFormChooseButtonControl' => 'view/form/control/AphrontFormChooseButtonControl.php',
|
'AphrontFormChooseButtonControl' => 'view/form/control/AphrontFormChooseButtonControl.php',
|
||||||
'AphrontFormControl' => 'view/form/control/AphrontFormControl.php',
|
'AphrontFormControl' => 'view/form/control/AphrontFormControl.php',
|
||||||
'AphrontFormDateControl' => 'view/form/control/AphrontFormDateControl.php',
|
'AphrontFormDateControl' => 'view/form/control/AphrontFormDateControl.php',
|
||||||
|
'AphrontFormDateControlValue' => 'view/form/control/AphrontFormDateControlValue.php',
|
||||||
'AphrontFormDividerControl' => 'view/form/control/AphrontFormDividerControl.php',
|
'AphrontFormDividerControl' => 'view/form/control/AphrontFormDividerControl.php',
|
||||||
'AphrontFormFileControl' => 'view/form/control/AphrontFormFileControl.php',
|
'AphrontFormFileControl' => 'view/form/control/AphrontFormFileControl.php',
|
||||||
'AphrontFormMarkupControl' => 'view/form/control/AphrontFormMarkupControl.php',
|
'AphrontFormMarkupControl' => 'view/form/control/AphrontFormMarkupControl.php',
|
||||||
|
@ -3360,6 +3361,7 @@ phutil_register_library_map(array(
|
||||||
'AphrontFormChooseButtonControl' => 'AphrontFormControl',
|
'AphrontFormChooseButtonControl' => 'AphrontFormControl',
|
||||||
'AphrontFormControl' => 'AphrontView',
|
'AphrontFormControl' => 'AphrontView',
|
||||||
'AphrontFormDateControl' => 'AphrontFormControl',
|
'AphrontFormDateControl' => 'AphrontFormControl',
|
||||||
|
'AphrontFormDateControlValue' => 'Phobject',
|
||||||
'AphrontFormDividerControl' => 'AphrontFormControl',
|
'AphrontFormDividerControl' => 'AphrontFormControl',
|
||||||
'AphrontFormFileControl' => 'AphrontFormControl',
|
'AphrontFormFileControl' => 'AphrontFormControl',
|
||||||
'AphrontFormMarkupControl' => 'AphrontFormControl',
|
'AphrontFormMarkupControl' => 'AphrontFormControl',
|
||||||
|
|
|
@ -18,24 +18,14 @@ final class PhabricatorCalendarEventEditController
|
||||||
$user = $request->getUser();
|
$user = $request->getUser();
|
||||||
$user_phid = $user->getPHID();
|
$user_phid = $user->getPHID();
|
||||||
$error_name = true;
|
$error_name = true;
|
||||||
|
$error_start_date = true;
|
||||||
|
$error_end_date = true;
|
||||||
$validation_exception = null;
|
$validation_exception = null;
|
||||||
|
|
||||||
$start_time = id(new AphrontFormDateControl())
|
|
||||||
->setUser($user)
|
|
||||||
->setName('start')
|
|
||||||
->setLabel(pht('Start'))
|
|
||||||
->setInitialTime(AphrontFormDateControl::TIME_START_OF_DAY);
|
|
||||||
|
|
||||||
$end_time = id(new AphrontFormDateControl())
|
|
||||||
->setUser($user)
|
|
||||||
->setName('end')
|
|
||||||
->setLabel(pht('End'))
|
|
||||||
->setInitialTime(AphrontFormDateControl::TIME_END_OF_DAY);
|
|
||||||
|
|
||||||
if ($this->isCreate()) {
|
if ($this->isCreate()) {
|
||||||
$event = PhabricatorCalendarEvent::initializeNewCalendarEvent($user);
|
$event = PhabricatorCalendarEvent::initializeNewCalendarEvent($user);
|
||||||
$end_value = $end_time->readValueFromRequest($request);
|
$end_value = AphrontFormDateControlValue::newFromEpoch($user, time());
|
||||||
$start_value = $start_time->readValueFromRequest($request);
|
$start_value = AphrontFormDateControlValue::newFromEpoch($user, time());
|
||||||
$submit_label = pht('Create');
|
$submit_label = pht('Create');
|
||||||
$page_title = pht('Create Event');
|
$page_title = pht('Create Event');
|
||||||
$redirect = 'created';
|
$redirect = 'created';
|
||||||
|
@ -56,8 +46,13 @@ final class PhabricatorCalendarEventEditController
|
||||||
return new Aphront404Response();
|
return new Aphront404Response();
|
||||||
}
|
}
|
||||||
|
|
||||||
$end_time->setValue($event->getDateTo());
|
$end_value = AphrontFormDateControlValue::newFromEpoch(
|
||||||
$start_time->setValue($event->getDateFrom());
|
$user,
|
||||||
|
$event->getDateTo());
|
||||||
|
$start_value = AphrontFormDateControlValue::newFromEpoch(
|
||||||
|
$user,
|
||||||
|
$event->getDateFrom());
|
||||||
|
|
||||||
$submit_label = pht('Update');
|
$submit_label = pht('Update');
|
||||||
$page_title = pht('Update Event');
|
$page_title = pht('Update Event');
|
||||||
|
|
||||||
|
@ -76,7 +71,6 @@ final class PhabricatorCalendarEventEditController
|
||||||
$cancel_uri = '/'.$event->getMonogram();
|
$cancel_uri = '/'.$event->getMonogram();
|
||||||
}
|
}
|
||||||
|
|
||||||
$errors = array();
|
|
||||||
$name = $event->getName();
|
$name = $event->getName();
|
||||||
$description = $event->getDescription();
|
$description = $event->getDescription();
|
||||||
$type = $event->getStatus();
|
$type = $event->getStatus();
|
||||||
|
@ -90,8 +84,13 @@ final class PhabricatorCalendarEventEditController
|
||||||
$xactions = array();
|
$xactions = array();
|
||||||
$name = $request->getStr('name');
|
$name = $request->getStr('name');
|
||||||
$type = $request->getInt('status');
|
$type = $request->getInt('status');
|
||||||
$start_value = $start_time->readValueFromRequest($request);
|
|
||||||
$end_value = $end_time->readValueFromRequest($request);
|
$start_value = AphrontFormDateControlValue::newFromRequest(
|
||||||
|
$request,
|
||||||
|
'start');
|
||||||
|
$end_value = AphrontFormDateControlValue::newFromRequest(
|
||||||
|
$request,
|
||||||
|
'end');
|
||||||
$description = $request->getStr('description');
|
$description = $request->getStr('description');
|
||||||
$subscribers = $request->getArr('subscribers');
|
$subscribers = $request->getArr('subscribers');
|
||||||
$edit_policy = $request->getStr('editPolicy');
|
$edit_policy = $request->getStr('editPolicy');
|
||||||
|
@ -107,13 +106,6 @@ final class PhabricatorCalendarEventEditController
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($start_time->getError()) {
|
|
||||||
$errors[] = pht('Invalid start time; reset to default.');
|
|
||||||
}
|
|
||||||
if ($end_time->getError()) {
|
|
||||||
$errors[] = pht('Invalid end time; reset to default.');
|
|
||||||
}
|
|
||||||
if (!$errors) {
|
|
||||||
$xactions[] = id(new PhabricatorCalendarEventTransaction())
|
$xactions[] = id(new PhabricatorCalendarEventTransaction())
|
||||||
->setTransactionType(
|
->setTransactionType(
|
||||||
PhabricatorCalendarEventTransaction::TYPE_NAME)
|
PhabricatorCalendarEventTransaction::TYPE_NAME)
|
||||||
|
@ -168,23 +160,16 @@ final class PhabricatorCalendarEventEditController
|
||||||
return $response->setURI('/E'.$event->getID());
|
return $response->setURI('/E'.$event->getID());
|
||||||
} catch (PhabricatorApplicationTransactionValidationException $ex) {
|
} catch (PhabricatorApplicationTransactionValidationException $ex) {
|
||||||
$validation_exception = $ex;
|
$validation_exception = $ex;
|
||||||
$error_name = $ex
|
$error_name = $ex->getShortMessage(
|
||||||
->getShortMessage(PhabricatorCalendarEventTransaction::TYPE_NAME);
|
PhabricatorCalendarEventTransaction::TYPE_NAME);
|
||||||
|
$error_start_date = $ex->getShortMessage(
|
||||||
|
PhabricatorCalendarEventTransaction::TYPE_START_DATE);
|
||||||
|
$error_end_date = $ex->getShortMessage(
|
||||||
|
PhabricatorCalendarEventTransaction::TYPE_END_DATE);
|
||||||
|
|
||||||
$event->setViewPolicy($view_policy);
|
$event->setViewPolicy($view_policy);
|
||||||
$event->setEditPolicy($edit_policy);
|
$event->setEditPolicy($edit_policy);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
$event->setViewPolicy($view_policy);
|
|
||||||
$event->setEditPolicy($edit_policy);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$error_view = null;
|
|
||||||
if ($errors) {
|
|
||||||
$error_view = id(new PHUIInfoView())
|
|
||||||
->setTitle(pht('Status can not be set!'))
|
|
||||||
->setErrors($errors);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$name = id(new AphrontFormTextControl())
|
$name = id(new AphrontFormTextControl())
|
||||||
|
@ -199,6 +184,20 @@ final class PhabricatorCalendarEventEditController
|
||||||
->setValue($type)
|
->setValue($type)
|
||||||
->setOptions($event->getStatusOptions());
|
->setOptions($event->getStatusOptions());
|
||||||
|
|
||||||
|
$start_control = id(new AphrontFormDateControl())
|
||||||
|
->setUser($user)
|
||||||
|
->setName('start')
|
||||||
|
->setLabel(pht('Start'))
|
||||||
|
->setError($error_start_date)
|
||||||
|
->setValue($start_value);
|
||||||
|
|
||||||
|
$end_control = id(new AphrontFormDateControl())
|
||||||
|
->setUser($user)
|
||||||
|
->setName('end')
|
||||||
|
->setLabel(pht('End'))
|
||||||
|
->setError($error_end_date)
|
||||||
|
->setValue($end_value);
|
||||||
|
|
||||||
$description = id(new AphrontFormTextAreaControl())
|
$description = id(new AphrontFormTextAreaControl())
|
||||||
->setLabel(pht('Description'))
|
->setLabel(pht('Description'))
|
||||||
->setName('description')
|
->setName('description')
|
||||||
|
@ -235,8 +234,8 @@ final class PhabricatorCalendarEventEditController
|
||||||
->setUser($user)
|
->setUser($user)
|
||||||
->appendChild($name)
|
->appendChild($name)
|
||||||
->appendChild($status_select)
|
->appendChild($status_select)
|
||||||
->appendChild($start_time)
|
->appendChild($start_control)
|
||||||
->appendChild($end_time)
|
->appendChild($end_control)
|
||||||
->appendControl($view_policies)
|
->appendControl($view_policies)
|
||||||
->appendControl($edit_policies)
|
->appendControl($edit_policies)
|
||||||
->appendControl($subscribers)
|
->appendControl($subscribers)
|
||||||
|
@ -261,7 +260,6 @@ final class PhabricatorCalendarEventEditController
|
||||||
|
|
||||||
$form_box = id(new PHUIObjectBoxView())
|
$form_box = id(new PHUIObjectBoxView())
|
||||||
->setHeaderText($page_title)
|
->setHeaderText($page_title)
|
||||||
->setFormErrors($errors)
|
|
||||||
->setForm($form);
|
->setForm($form);
|
||||||
|
|
||||||
$crumbs = $this->buildApplicationCrumbs();
|
$crumbs = $this->buildApplicationCrumbs();
|
||||||
|
|
|
@ -83,14 +83,15 @@ final class PhabricatorCalendarEventEditor
|
||||||
PhabricatorApplicationTransaction $xaction) {
|
PhabricatorApplicationTransaction $xaction) {
|
||||||
switch ($xaction->getTransactionType()) {
|
switch ($xaction->getTransactionType()) {
|
||||||
case PhabricatorCalendarEventTransaction::TYPE_NAME:
|
case PhabricatorCalendarEventTransaction::TYPE_NAME:
|
||||||
case PhabricatorCalendarEventTransaction::TYPE_START_DATE:
|
|
||||||
case PhabricatorCalendarEventTransaction::TYPE_END_DATE:
|
|
||||||
case PhabricatorCalendarEventTransaction::TYPE_DESCRIPTION:
|
case PhabricatorCalendarEventTransaction::TYPE_DESCRIPTION:
|
||||||
case PhabricatorCalendarEventTransaction::TYPE_CANCEL:
|
case PhabricatorCalendarEventTransaction::TYPE_CANCEL:
|
||||||
case PhabricatorCalendarEventTransaction::TYPE_INVITE:
|
case PhabricatorCalendarEventTransaction::TYPE_INVITE:
|
||||||
return $xaction->getNewValue();
|
return $xaction->getNewValue();
|
||||||
case PhabricatorCalendarEventTransaction::TYPE_STATUS:
|
case PhabricatorCalendarEventTransaction::TYPE_STATUS:
|
||||||
return (int)$xaction->getNewValue();
|
return (int)$xaction->getNewValue();
|
||||||
|
case PhabricatorCalendarEventTransaction::TYPE_START_DATE:
|
||||||
|
case PhabricatorCalendarEventTransaction::TYPE_END_DATE:
|
||||||
|
return $xaction->getNewValue()->getEpoch();
|
||||||
}
|
}
|
||||||
|
|
||||||
return parent::getCustomTransactionNewValue($object, $xaction);
|
return parent::getCustomTransactionNewValue($object, $xaction);
|
||||||
|
@ -204,6 +205,19 @@ final class PhabricatorCalendarEventEditor
|
||||||
$errors[] = $error;
|
$errors[] = $error;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case PhabricatorCalendarEventTransaction::TYPE_START_DATE:
|
||||||
|
case PhabricatorCalendarEventTransaction::TYPE_END_DATE:
|
||||||
|
foreach ($xactions as $xaction) {
|
||||||
|
$date_value = $xaction->getNewValue();
|
||||||
|
if (!$date_value->isValid()) {
|
||||||
|
$errors[] = new PhabricatorApplicationTransactionValidationError(
|
||||||
|
$type,
|
||||||
|
pht('Invalid'),
|
||||||
|
pht('Invalid date.'),
|
||||||
|
$xaction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $errors;
|
return $errors;
|
||||||
|
|
|
@ -10,6 +10,7 @@ final class AphrontFormDateControl extends AphrontFormControl {
|
||||||
private $valueYear;
|
private $valueYear;
|
||||||
private $valueTime;
|
private $valueTime;
|
||||||
private $allowNull;
|
private $allowNull;
|
||||||
|
private $continueOnInvalidDate = false;
|
||||||
|
|
||||||
public function setAllowNull($allow_null) {
|
public function setAllowNull($allow_null) {
|
||||||
$this->allowNull = $allow_null;
|
$this->allowNull = $allow_null;
|
||||||
|
@ -84,6 +85,16 @@ final class AphrontFormDateControl extends AphrontFormControl {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setValue($epoch) {
|
public function setValue($epoch) {
|
||||||
|
if ($epoch instanceof AphrontFormDateControlValue) {
|
||||||
|
$this->continueOnInvalidDate = true;
|
||||||
|
$this->valueYear = $epoch->getValueYear();
|
||||||
|
$this->valueMonth = $epoch->getValueMonth();
|
||||||
|
$this->valueDay = $epoch->getValueDay();
|
||||||
|
$this->valueTime = $epoch->getValueTime();
|
||||||
|
|
||||||
|
return parent::setValue($epoch->getEpoch());
|
||||||
|
}
|
||||||
|
|
||||||
$result = parent::setValue($epoch);
|
$result = parent::setValue($epoch);
|
||||||
|
|
||||||
if ($epoch === null) {
|
if ($epoch === null) {
|
||||||
|
@ -165,7 +176,7 @@ final class AphrontFormDateControl extends AphrontFormControl {
|
||||||
protected function renderInput() {
|
protected function renderInput() {
|
||||||
|
|
||||||
$disabled = null;
|
$disabled = null;
|
||||||
if ($this->getValue() === null) {
|
if ($this->getValue() === null && !$this->continueOnInvalidDate) {
|
||||||
$this->setValue($this->getInitialValue());
|
$this->setValue($this->getInitialValue());
|
||||||
if ($this->allowNull) {
|
if ($this->allowNull) {
|
||||||
$disabled = 'disabled';
|
$disabled = 'disabled';
|
||||||
|
|
97
src/view/form/control/AphrontFormDateControlValue.php
Normal file
97
src/view/form/control/AphrontFormDateControlValue.php
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class AphrontFormDateControlValue extends Phobject {
|
||||||
|
|
||||||
|
private $valueDay;
|
||||||
|
private $valueMonth;
|
||||||
|
private $valueYear;
|
||||||
|
private $valueTime;
|
||||||
|
|
||||||
|
private $viewer;
|
||||||
|
private $zone;
|
||||||
|
|
||||||
|
public function getValueDay() {
|
||||||
|
return $this->valueDay;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getValueMonth() {
|
||||||
|
return $this->valueMonth;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getValueYear() {
|
||||||
|
return $this->valueYear;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getValueTime() {
|
||||||
|
return $this->valueTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isValid() {
|
||||||
|
return ($this->getEpoch() !== null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function newFromRequest($request, $key) {
|
||||||
|
$value = new AphrontFormDateControlValue();
|
||||||
|
$value->viewer = $request->getViewer();
|
||||||
|
|
||||||
|
$value->valueDay = $request->getInt($key.'_d');
|
||||||
|
$value->valueMonth = $request->getInt($key.'_m');
|
||||||
|
$value->valueYear = $request->getInt($key.'_y');
|
||||||
|
$value->valueTime = $request->getStr($key.'_t');
|
||||||
|
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function newFromEpoch(PhabricatorUser $viewer, $epoch) {
|
||||||
|
$value = new AphrontFormDateControlValue();
|
||||||
|
$value->viewer = $viewer;
|
||||||
|
$readable = $value->formatTime($epoch, 'Y!m!d!g:i A');
|
||||||
|
$readable = explode('!', $readable, 4);
|
||||||
|
|
||||||
|
$value->valueYear = $readable[0];
|
||||||
|
$value->valueMonth = $readable[1];
|
||||||
|
$value->valueDay = $readable[2];
|
||||||
|
$value->valueTime = $readable[3];
|
||||||
|
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function formatTime($epoch, $format) {
|
||||||
|
return phabricator_format_local_time(
|
||||||
|
$epoch,
|
||||||
|
$this->viewer,
|
||||||
|
$format);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getEpoch() {
|
||||||
|
$year = $this->valueYear;
|
||||||
|
$month = $this->valueMonth;
|
||||||
|
$day = $this->valueDay;
|
||||||
|
$time = $this->valueTime;
|
||||||
|
$zone = $this->getTimezone();
|
||||||
|
|
||||||
|
if (!strlen($time)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$date = new DateTime("{$year}-{$month}-{$day} {$time}", $zone);
|
||||||
|
$value = $date->format('U');
|
||||||
|
} catch (Exception $ex) {
|
||||||
|
$value = null;
|
||||||
|
}
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getTimezone() {
|
||||||
|
if ($this->zone) {
|
||||||
|
return $this->zone;
|
||||||
|
}
|
||||||
|
|
||||||
|
$viewer_zone = $this->viewer->getTimezoneIdentifier();
|
||||||
|
$this->zone = new DateTimeZone($viewer_zone);
|
||||||
|
return $this->zone;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue