mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-23 22:10:55 +01:00
Translate "All Day" events into the viewer's time
Summary: Ref T8021. - When "All Day" events are loaded, convert them into the viewer's time. - When "All Day" events are saved, convert them into a +24 hour range. Test Plan: - Created and updated "All Day" events. - Created and updated normal events. - Changed timezones, edited and viewed "All Day" events and normal events. - In all cases, "All Day" events appeared to be 12:00AM - 11:59:59PM to the viewer, on the correct day. - Normal events shifted around properly according to timezones. Reviewers: lpriestley Reviewed By: lpriestley Subscribers: epriestley Maniphest Tasks: T8021 Differential Revision: https://secure.phabricator.com/D12765
This commit is contained in:
parent
57e22e3ce5
commit
f3d76a90f0
6 changed files with 142 additions and 2 deletions
|
@ -74,6 +74,7 @@ final class PhabricatorCalendarEventEditController
|
||||||
$name = $event->getName();
|
$name = $event->getName();
|
||||||
$description = $event->getDescription();
|
$description = $event->getDescription();
|
||||||
$type = $event->getStatus();
|
$type = $event->getStatus();
|
||||||
|
$is_all_day = $event->getIsAllDay();
|
||||||
|
|
||||||
$current_policies = id(new PhabricatorPolicyQuery())
|
$current_policies = id(new PhabricatorPolicyQuery())
|
||||||
->setViewer($user)
|
->setViewer($user)
|
||||||
|
@ -95,6 +96,7 @@ final class PhabricatorCalendarEventEditController
|
||||||
$subscribers = $request->getArr('subscribers');
|
$subscribers = $request->getArr('subscribers');
|
||||||
$edit_policy = $request->getStr('editPolicy');
|
$edit_policy = $request->getStr('editPolicy');
|
||||||
$view_policy = $request->getStr('viewPolicy');
|
$view_policy = $request->getStr('viewPolicy');
|
||||||
|
$is_all_day = $request->getStr('isAllDay');
|
||||||
|
|
||||||
$invitees = $request->getArr('invitees');
|
$invitees = $request->getArr('invitees');
|
||||||
$new_invitees = $this->getNewInviteeList($invitees, $event);
|
$new_invitees = $this->getNewInviteeList($invitees, $event);
|
||||||
|
@ -111,6 +113,11 @@ final class PhabricatorCalendarEventEditController
|
||||||
PhabricatorCalendarEventTransaction::TYPE_NAME)
|
PhabricatorCalendarEventTransaction::TYPE_NAME)
|
||||||
->setNewValue($name);
|
->setNewValue($name);
|
||||||
|
|
||||||
|
$xactions[] = id(new PhabricatorCalendarEventTransaction())
|
||||||
|
->setTransactionType(
|
||||||
|
PhabricatorCalendarEventTransaction::TYPE_ALL_DAY)
|
||||||
|
->setNewValue($is_all_day);
|
||||||
|
|
||||||
$xactions[] = id(new PhabricatorCalendarEventTransaction())
|
$xactions[] = id(new PhabricatorCalendarEventTransaction())
|
||||||
->setTransactionType(
|
->setTransactionType(
|
||||||
PhabricatorCalendarEventTransaction::TYPE_START_DATE)
|
PhabricatorCalendarEventTransaction::TYPE_START_DATE)
|
||||||
|
@ -184,6 +191,13 @@ final class PhabricatorCalendarEventEditController
|
||||||
->setValue($type)
|
->setValue($type)
|
||||||
->setOptions($event->getStatusOptions());
|
->setOptions($event->getStatusOptions());
|
||||||
|
|
||||||
|
$all_day_select = id(new AphrontFormCheckboxControl())
|
||||||
|
->addCheckbox(
|
||||||
|
'isAllDay',
|
||||||
|
1,
|
||||||
|
pht('All Day Event'),
|
||||||
|
$is_all_day);
|
||||||
|
|
||||||
$start_control = id(new AphrontFormDateControl())
|
$start_control = id(new AphrontFormDateControl())
|
||||||
->setUser($user)
|
->setUser($user)
|
||||||
->setName('start')
|
->setName('start')
|
||||||
|
@ -234,6 +248,7 @@ final class PhabricatorCalendarEventEditController
|
||||||
->setUser($user)
|
->setUser($user)
|
||||||
->appendChild($name)
|
->appendChild($name)
|
||||||
->appendChild($status_select)
|
->appendChild($status_select)
|
||||||
|
->appendChild($all_day_select)
|
||||||
->appendChild($start_control)
|
->appendChild($start_control)
|
||||||
->appendChild($end_control)
|
->appendChild($end_control)
|
||||||
->appendControl($view_policies)
|
->appendControl($view_policies)
|
||||||
|
|
|
@ -183,6 +183,16 @@ final class PhabricatorCalendarEventEditor
|
||||||
return parent::applyCustomExternalTransaction($object, $xaction);
|
return parent::applyCustomExternalTransaction($object, $xaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function didApplyInternalEffects(
|
||||||
|
PhabricatorLiskDAO $object,
|
||||||
|
array $xactions) {
|
||||||
|
|
||||||
|
$object->removeViewerTimezone($this->requireActor());
|
||||||
|
|
||||||
|
return $xactions;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
protected function validateAllTransactions(
|
protected function validateAllTransactions(
|
||||||
PhabricatorLiskDAO $object,
|
PhabricatorLiskDAO $object,
|
||||||
array $xactions) {
|
array $xactions) {
|
||||||
|
|
|
@ -56,7 +56,13 @@ final class PhabricatorCalendarEventQuery
|
||||||
$this->buildOrderClause($conn_r),
|
$this->buildOrderClause($conn_r),
|
||||||
$this->buildLimitClause($conn_r));
|
$this->buildLimitClause($conn_r));
|
||||||
|
|
||||||
return $table->loadAllFromArray($data);
|
$events = $table->loadAllFromArray($data);
|
||||||
|
|
||||||
|
foreach ($events as $event) {
|
||||||
|
$event->applyViewerTimezone($this->getViewer());
|
||||||
|
}
|
||||||
|
|
||||||
|
return $events;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function buildJoinClauseParts(AphrontDatabaseConnection $conn_r) {
|
protected function buildJoinClauseParts(AphrontDatabaseConnection $conn_r) {
|
||||||
|
|
|
@ -24,6 +24,7 @@ final class PhabricatorCalendarEvent extends PhabricatorCalendarDAO
|
||||||
protected $editPolicy;
|
protected $editPolicy;
|
||||||
|
|
||||||
private $invitees = self::ATTACHABLE;
|
private $invitees = self::ATTACHABLE;
|
||||||
|
private $appliedViewer;
|
||||||
|
|
||||||
const STATUS_AWAY = 1;
|
const STATUS_AWAY = 1;
|
||||||
const STATUS_SPORADIC = 2;
|
const STATUS_SPORADIC = 2;
|
||||||
|
@ -37,15 +38,112 @@ final class PhabricatorCalendarEvent extends PhabricatorCalendarDAO
|
||||||
return id(new PhabricatorCalendarEvent())
|
return id(new PhabricatorCalendarEvent())
|
||||||
->setUserPHID($actor->getPHID())
|
->setUserPHID($actor->getPHID())
|
||||||
->setIsCancelled(0)
|
->setIsCancelled(0)
|
||||||
|
->setIsAllDay(0)
|
||||||
->setViewPolicy($actor->getPHID())
|
->setViewPolicy($actor->getPHID())
|
||||||
->setEditPolicy($actor->getPHID())
|
->setEditPolicy($actor->getPHID())
|
||||||
->attachInvitees(array());
|
->attachInvitees(array())
|
||||||
|
->applyViewerTimezone($actor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function applyViewerTimezone(PhabricatorUser $viewer) {
|
||||||
|
if ($this->appliedViewer) {
|
||||||
|
throw new Exception(pht('Viewer timezone is already applied!'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->appliedViewer = $viewer;
|
||||||
|
|
||||||
|
if (!$this->getIsAllDay()) {
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
$zone = $viewer->getTimeZone();
|
||||||
|
|
||||||
|
|
||||||
|
$this->setDateFrom(
|
||||||
|
$this->getDateEpochForTimeZone(
|
||||||
|
$this->getDateFrom(),
|
||||||
|
new DateTimeZone('GMT+12'),
|
||||||
|
'Y-m-d',
|
||||||
|
null,
|
||||||
|
$zone));
|
||||||
|
|
||||||
|
$this->setDateTo(
|
||||||
|
$this->getDateEpochForTimeZone(
|
||||||
|
$this->getDateTo(),
|
||||||
|
new DateTimeZone('GMT-12'),
|
||||||
|
'Y-m-d 23:59:59',
|
||||||
|
'-1 day',
|
||||||
|
$zone));
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function removeViewerTimezone(PhabricatorUser $viewer) {
|
||||||
|
if (!$this->appliedViewer) {
|
||||||
|
throw new Exception(pht('Viewer timezone is not applied!'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($viewer->getPHID() != $this->appliedViewer->getPHID()) {
|
||||||
|
throw new Exception(pht('Removed viewer must match applied viewer!'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->appliedViewer = null;
|
||||||
|
|
||||||
|
if (!$this->getIsAllDay()) {
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
$zone = $viewer->getTimeZone();
|
||||||
|
|
||||||
|
$this->setDateFrom(
|
||||||
|
$this->getDateEpochForTimeZone(
|
||||||
|
$this->getDateFrom(),
|
||||||
|
$zone,
|
||||||
|
'Y-m-d',
|
||||||
|
null,
|
||||||
|
new DateTimeZone('GMT+12')));
|
||||||
|
|
||||||
|
$this->setDateTo(
|
||||||
|
$this->getDateEpochForTimeZone(
|
||||||
|
$this->getDateTo(),
|
||||||
|
$zone,
|
||||||
|
'Y-m-d',
|
||||||
|
'+1 day',
|
||||||
|
new DateTimeZone('GMT-12')));
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getDateEpochForTimeZone(
|
||||||
|
$epoch,
|
||||||
|
$src_zone,
|
||||||
|
$format,
|
||||||
|
$adjust,
|
||||||
|
$dst_zone) {
|
||||||
|
|
||||||
|
$src = new DateTime('@'.$epoch);
|
||||||
|
$src->setTimeZone($src_zone);
|
||||||
|
|
||||||
|
if (strlen($adjust)) {
|
||||||
|
$adjust = ' '.$adjust;
|
||||||
|
}
|
||||||
|
|
||||||
|
$dst = new DateTime($src->format($format).$adjust, $dst_zone);
|
||||||
|
return $dst->format('U');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function save() {
|
public function save() {
|
||||||
|
if ($this->appliedViewer) {
|
||||||
|
throw new Exception(
|
||||||
|
pht(
|
||||||
|
'Can not save event with viewer timezone still applied!'));
|
||||||
|
}
|
||||||
|
|
||||||
if (!$this->mailKey) {
|
if (!$this->mailKey) {
|
||||||
$this->mailKey = Filesystem::readRandomCharacters(20);
|
$this->mailKey = Filesystem::readRandomCharacters(20);
|
||||||
}
|
}
|
||||||
|
|
||||||
return parent::save();
|
return parent::save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -682,6 +682,10 @@ EOBODY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getTimeZone() {
|
||||||
|
return new DateTimeZone($this->getTimezoneIdentifier());
|
||||||
|
}
|
||||||
|
|
||||||
public function __toString() {
|
public function __toString() {
|
||||||
return $this->getUsername();
|
return $this->getUsername();
|
||||||
}
|
}
|
||||||
|
|
|
@ -569,6 +569,11 @@ abstract class PhabricatorApplicationTransactionEditor
|
||||||
return $xaction;
|
return $xaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function didApplyInternalEffects(
|
||||||
|
PhabricatorLiskDAO $object,
|
||||||
|
array $xactions) {
|
||||||
|
return $xactions;
|
||||||
|
}
|
||||||
|
|
||||||
protected function applyFinalEffects(
|
protected function applyFinalEffects(
|
||||||
PhabricatorLiskDAO $object,
|
PhabricatorLiskDAO $object,
|
||||||
|
@ -731,6 +736,8 @@ abstract class PhabricatorApplicationTransactionEditor
|
||||||
$this->applyInternalEffects($object, $xaction);
|
$this->applyInternalEffects($object, $xaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$xactions = $this->didApplyInternalEffects($object, $xactions);
|
||||||
|
|
||||||
$object->save();
|
$object->save();
|
||||||
|
|
||||||
foreach ($xactions as $xaction) {
|
foreach ($xactions as $xaction) {
|
||||||
|
|
Loading…
Reference in a new issue