1
0
Fork 0
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:
epriestley 2015-05-07 18:57:28 -07:00
parent 57e22e3ce5
commit f3d76a90f0
6 changed files with 142 additions and 2 deletions

View file

@ -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)

View file

@ -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) {

View file

@ -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) {

View file

@ -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();
} }

View file

@ -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();
} }

View file

@ -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) {