1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-09-20 17:28:51 +02:00

Fix calendar display on profile.

Summary:
...maybe anyway because I can't reproduce it live. This diff does two things that should help with bugginess though - uses $viewer rather than $user (...$user is who we are looking at...) *AND* upgrades a Conpherence util class to Calendar, and said util class has unit tests and came about from fixing a similar bug in Conpherence back in the day.

Wrote some comments in the util class because I think it has a tendency to trip people up. These comments are not partciularly good however.

Test Plan: viewed user profile - looked good. viewed conpherence - looked good. ran unit tests - they passed. (note I would also like to push this live and verify Chad's profile is fixed on secure.phabricator.com)

Reviewers: epriestley, chad

Reviewed By: epriestley

CC: Korvin, epriestley, aran

Differential Revision: https://secure.phabricator.com/D8341
This commit is contained in:
Bob Trahan 2014-02-25 13:43:31 -08:00
parent 06fc82a3ee
commit b1e44239ba
6 changed files with 102 additions and 54 deletions

View file

@ -95,6 +95,8 @@ phutil_register_library_map(array(
'BuildStepImplementation' => 'applications/harbormaster/step/BuildStepImplementation.php',
'CalendarColors' => 'applications/calendar/constants/CalendarColors.php',
'CalendarConstants' => 'applications/calendar/constants/CalendarConstants.php',
'CalendarTimeUtil' => 'applications/calendar/util/CalendarTimeUtil.php',
'CalendarTimeUtilTestCase' => 'applications/calendar/__tests__/CalendarTimeUtilTestCase.php',
'CelerityAPI' => 'infrastructure/celerity/CelerityAPI.php',
'CelerityManagementMapWorkflow' => 'infrastructure/celerity/management/CelerityManagementMapWorkflow.php',
'CelerityManagementWorkflow' => 'infrastructure/celerity/management/CelerityManagementWorkflow.php',
@ -291,8 +293,6 @@ phutil_register_library_map(array(
'ConpherenceThreadListView' => 'applications/conpherence/view/ConpherenceThreadListView.php',
'ConpherenceThreadMailReceiver' => 'applications/conpherence/mail/ConpherenceThreadMailReceiver.php',
'ConpherenceThreadQuery' => 'applications/conpherence/query/ConpherenceThreadQuery.php',
'ConpherenceTimeUtil' => 'applications/conpherence/util/ConpherenceTimeUtil.php',
'ConpherenceTimeUtilTestCase' => 'applications/conpherence/__tests__/ConpherenceTimeUtilTestCase.php',
'ConpherenceTransaction' => 'applications/conpherence/storage/ConpherenceTransaction.php',
'ConpherenceTransactionComment' => 'applications/conpherence/storage/ConpherenceTransactionComment.php',
'ConpherenceTransactionQuery' => 'applications/conpherence/query/ConpherenceTransactionQuery.php',
@ -2658,6 +2658,7 @@ phutil_register_library_map(array(
'AphrontWebpageResponse' => 'AphrontHTMLResponse',
'AuditActionMenuEventListener' => 'PhabricatorEventListener',
'CalendarColors' => 'CalendarConstants',
'CalendarTimeUtilTestCase' => 'PhabricatorTestCase',
'CelerityManagementMapWorkflow' => 'CelerityManagementWorkflow',
'CelerityManagementWorkflow' => 'PhabricatorManagementWorkflow',
'CelerityPhabricatorResourceController' => 'CelerityResourceController',
@ -2852,7 +2853,6 @@ phutil_register_library_map(array(
'ConpherenceThreadListView' => 'AphrontView',
'ConpherenceThreadMailReceiver' => 'PhabricatorObjectMailReceiver',
'ConpherenceThreadQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'ConpherenceTimeUtilTestCase' => 'PhabricatorTestCase',
'ConpherenceTransaction' => 'PhabricatorApplicationTransaction',
'ConpherenceTransactionComment' => 'PhabricatorApplicationTransactionComment',
'ConpherenceTransactionQuery' => 'PhabricatorApplicationTransactionQuery',

View file

@ -1,13 +1,13 @@
<?php
final class ConpherenceTimeUtilTestCase extends PhabricatorTestCase {
final class CalendarTimeUtilTestCase extends PhabricatorTestCase {
public function testWidgetTimestampsAtMidnight() {
public function testTimestampsAtMidnight() {
$u = new PhabricatorUser();
$u->setTimezoneIdentifier('America/Los_Angeles');
$days = $this->getAllDays();
foreach ($days as $day) {
$data = ConpherenceTimeUtil::getCalendarWidgetTimestamps(
$data = CalendarTimeUtil::getCalendarWidgetTimestamps(
$u,
$day);
@ -17,14 +17,15 @@ final class ConpherenceTimeUtilTestCase extends PhabricatorTestCase {
}
}
public function testWidgetTimestampsStartDay() {
public function testTimestampsStartDay() {
$u = new PhabricatorUser();
$u->setTimezoneIdentifier('America/Los_Angeles');
$days = $this->getAllDays();
foreach ($days as $day) {
$data = ConpherenceTimeUtil::getCalendarWidgetTimestamps(
$data = CalendarTimeUtil::getTimestamps(
$u,
$day);
$day,
1);
$this->assertEqual(
$day,
@ -34,9 +35,10 @@ final class ConpherenceTimeUtilTestCase extends PhabricatorTestCase {
$t = 1370202281; // 2013-06-02 12:44:41 -0700 -- a Sunday
$time = PhabricatorTime::pushTime($t, 'America/Los_Angeles');
foreach ($days as $day) {
$data = ConpherenceTimeUtil::getCalendarWidgetTimestamps(
$data = CalendarTimeUtil::getTimestamps(
$u,
$day);
$day,
1);
$this->assertEqual(
$day,

View file

@ -1,37 +1,62 @@
<?php
final class ConpherenceTimeUtil {
/**
* This class is useful for generating various time objects, relative to the
* user and their timezone.
*
* For now, the class exposes two sets of static methods for the two main
* calendar views - one for the conpherence calendar widget and one for the
* user profile calendar view. These have slight differences such as
* conpherence showing both a three day "today 'til 2 days from now" *and*
* a Sunday -> Saturday list, whilest the profile view shows a more simple
* seven day rolling list of events.
*/
final class CalendarTimeUtil {
public static function getCalendarEventEpochs(
PhabricatorUser $user,
$start_day_str = 'Sunday') {
$start_day_str = 'Sunday',
$days = 9) {
$objects = self::getStartDateTimeObjects($user, $start_day_str);
$start_day = $objects['start_day'];
$end_day = clone $start_day;
$end_day->modify('+9 days');
$end_day->modify('+'.$days.' days');
return array(
'start_epoch' => $start_day->format('U'),
'end_epoch' => $end_day->format('U'));
}
public static function getCalendarWeekTimestamps(
PhabricatorUser $user) {
return self::getTimestamps($user, 'Today', 7);
}
public static function getCalendarWidgetTimestamps(
PhabricatorUser $user) {
return self::getTimestamps($user, 'Sunday', 9);
}
/**
* Public for testing purposes only. You should probably use one of the
* functions above.
*/
public static function getTimestamps(
PhabricatorUser $user,
$start_day_str = 'Sunday') {
$start_day_str,
$days) {
$objects = self::getStartDateTimeObjects($user, $start_day_str);
$start_day = $objects['start_day'];
$timestamps = array();
for ($day = 0; $day < 9; $day++) {
for ($day = 0; $day < $days; $day++) {
$timestamp = clone $start_day;
$timestamp->modify(sprintf('+%d days', $day));
$timestamps[] = $timestamp;
}
return array(
'today' => $objects['today'],
'epoch_stamps' => $timestamps
);
'epoch_stamps' => $timestamps);
}
private static function getStartDateTimeObjects(
@ -43,7 +68,8 @@ final class ConpherenceTimeUtil {
$today = new DateTime('@'.$today_epoch);
$today->setTimeZone($timezone);
if ($today->format('l') == $start_day_str) {
if (strtolower($start_day_str) == 'today' ||
$today->format('l') == $start_day_str) {
$start_day = clone $today;
} else {
$start_epoch = PhabricatorTime::parseLocalTime(

View file

@ -200,7 +200,7 @@ final class ConpherenceWidgetController extends
$content = array();
$layout = id(new AphrontMultiColumnView())
->setFluidLayout(true);
$timestamps = ConpherenceTimeUtil::getCalendarWidgetTimestamps($user);
$timestamps = CalendarTimeUtil::getCalendarWidgetTimestamps($user);
$today = $timestamps['today'];
$epoch_stamps = $timestamps['epoch_stamps'];
$one_day = 24 * 60 * 60;

View file

@ -217,7 +217,7 @@ final class ConpherenceThreadQuery
$participant_phids = array_mergev($participant_phids);
$file_phids = array_mergev($file_phids);
$epochs = ConpherenceTimeUtil::getCalendarEventEpochs(
$epochs = CalendarTimeUtil::getCalendarEventEpochs(
$this->getViewer());
$start_epoch = $epochs['start_epoch'];
$end_epoch = $epochs['end_epoch'];

View file

@ -141,51 +141,71 @@ final class PhabricatorPeopleProfileController
}
private function renderUserCalendar(PhabricatorUser $user) {
$now = time();
$year = phabricator_format_local_time($now, $user, 'Y');
$month = phabricator_format_local_time($now, $user, 'm');
$day = phabricator_format_local_time($now, $user, 'j');
$viewer = $this->getRequest()->getUser();
$epochs = CalendarTimeUtil::getCalendarEventEpochs(
$viewer,
'today',
7);
$start_epoch = $epochs['start_epoch'];
$end_epoch = $epochs['end_epoch'];
$statuses = id(new PhabricatorCalendarEventQuery())
->setViewer($user)
->setViewer($viewer)
->withInvitedPHIDs(array($user->getPHID()))
->withDateRange(
strtotime("{$year}-{$month}-{$day}"),
strtotime("{$year}-{$month}-{$day} +7 days"))
->withDateRange($start_epoch, $end_epoch)
->execute();
$timestamps = CalendarTimeUtil::getCalendarWeekTimestamps(
$viewer);
$today = $timestamps['today'];
$epoch_stamps = $timestamps['epoch_stamps'];
$events = array();
foreach ($statuses as $status) {
$event = new AphrontCalendarEventView();
$event->setEpochRange($status->getDateFrom(), $status->getDateTo());
$status_text = $status->getHumanStatus();
$event->setUserPHID($status->getUserPHID());
$event->setName($status_text);
$event->setDescription($status->getDescription());
$event->setEventID($status->getID());
$key = date('Y-m-d', $event->getEpochStart());
$events[$key][] = $event;
// Populate multiday events
// Better means?
$next_day = strtotime("{$key} +1 day");
if ($event->getEpochEnd() >= $next_day) {
$nextkey = date('Y-m-d', $next_day);
$events[$nextkey][] = $event;
foreach ($epoch_stamps as $day) {
$epoch_start = $day->format('U');
$next_day = clone $day;
$next_day->modify('+1 day');
$epoch_end = $next_day->format('U');
foreach ($statuses as $status) {
if ($status->getDateFrom() >= $epoch_end) {
// This list is sorted, so we can stop looking.
break;
}
$event = new AphrontCalendarEventView();
$event->setEpochRange($status->getDateFrom(), $status->getDateTo());
$status_text = $status->getHumanStatus();
$event->setUserPHID($status->getUserPHID());
$event->setName($status_text);
$event->setDescription($status->getDescription());
$event->setEventID($status->getID());
$key = date('Y-m-d', $event->getEpochStart());
$events[$epoch_start][] = $event;
// check if this is a multi day event...!
$day_iterator = clone $day;
while (true) {
$day_iterator->modify('+ 1 day');
$day_iterator_end = $day_iterator->format('U');
if ($event->getEpochEnd() > $day_iterator_end) {
$events[$day_iterator_end][] = $event;
} else {
break;
}
}
}
}
$i = 0;
$week = array();
for ($i = 0;$i <= 6;$i++) {
$datetime = strtotime("{$year}-{$month}-{$day} +{$i} days");
$headertext = phabricator_format_local_time($datetime, $user, 'l, M d');
$this_day = date('Y-m-d', $datetime);
foreach ($epoch_stamps as $day) {
$epoch = $day->format('U');
$headertext = phabricator_format_local_time($epoch, $user, 'l, M d');
$list = new PHUICalendarListView();
$list->setUser($user);
$list->setUser($viewer);
$list->showBlankState(true);
if (isset($events[$this_day])) {
foreach ($events[$this_day] as $event) {
if (isset($events[$epoch])) {
foreach ($events[$epoch] as $event) {
$list->addEvent($event);
}
}