1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-24 06:20:56 +01: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', 'BuildStepImplementation' => 'applications/harbormaster/step/BuildStepImplementation.php',
'CalendarColors' => 'applications/calendar/constants/CalendarColors.php', 'CalendarColors' => 'applications/calendar/constants/CalendarColors.php',
'CalendarConstants' => 'applications/calendar/constants/CalendarConstants.php', 'CalendarConstants' => 'applications/calendar/constants/CalendarConstants.php',
'CalendarTimeUtil' => 'applications/calendar/util/CalendarTimeUtil.php',
'CalendarTimeUtilTestCase' => 'applications/calendar/__tests__/CalendarTimeUtilTestCase.php',
'CelerityAPI' => 'infrastructure/celerity/CelerityAPI.php', 'CelerityAPI' => 'infrastructure/celerity/CelerityAPI.php',
'CelerityManagementMapWorkflow' => 'infrastructure/celerity/management/CelerityManagementMapWorkflow.php', 'CelerityManagementMapWorkflow' => 'infrastructure/celerity/management/CelerityManagementMapWorkflow.php',
'CelerityManagementWorkflow' => 'infrastructure/celerity/management/CelerityManagementWorkflow.php', 'CelerityManagementWorkflow' => 'infrastructure/celerity/management/CelerityManagementWorkflow.php',
@ -291,8 +293,6 @@ phutil_register_library_map(array(
'ConpherenceThreadListView' => 'applications/conpherence/view/ConpherenceThreadListView.php', 'ConpherenceThreadListView' => 'applications/conpherence/view/ConpherenceThreadListView.php',
'ConpherenceThreadMailReceiver' => 'applications/conpherence/mail/ConpherenceThreadMailReceiver.php', 'ConpherenceThreadMailReceiver' => 'applications/conpherence/mail/ConpherenceThreadMailReceiver.php',
'ConpherenceThreadQuery' => 'applications/conpherence/query/ConpherenceThreadQuery.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', 'ConpherenceTransaction' => 'applications/conpherence/storage/ConpherenceTransaction.php',
'ConpherenceTransactionComment' => 'applications/conpherence/storage/ConpherenceTransactionComment.php', 'ConpherenceTransactionComment' => 'applications/conpherence/storage/ConpherenceTransactionComment.php',
'ConpherenceTransactionQuery' => 'applications/conpherence/query/ConpherenceTransactionQuery.php', 'ConpherenceTransactionQuery' => 'applications/conpherence/query/ConpherenceTransactionQuery.php',
@ -2658,6 +2658,7 @@ phutil_register_library_map(array(
'AphrontWebpageResponse' => 'AphrontHTMLResponse', 'AphrontWebpageResponse' => 'AphrontHTMLResponse',
'AuditActionMenuEventListener' => 'PhabricatorEventListener', 'AuditActionMenuEventListener' => 'PhabricatorEventListener',
'CalendarColors' => 'CalendarConstants', 'CalendarColors' => 'CalendarConstants',
'CalendarTimeUtilTestCase' => 'PhabricatorTestCase',
'CelerityManagementMapWorkflow' => 'CelerityManagementWorkflow', 'CelerityManagementMapWorkflow' => 'CelerityManagementWorkflow',
'CelerityManagementWorkflow' => 'PhabricatorManagementWorkflow', 'CelerityManagementWorkflow' => 'PhabricatorManagementWorkflow',
'CelerityPhabricatorResourceController' => 'CelerityResourceController', 'CelerityPhabricatorResourceController' => 'CelerityResourceController',
@ -2852,7 +2853,6 @@ phutil_register_library_map(array(
'ConpherenceThreadListView' => 'AphrontView', 'ConpherenceThreadListView' => 'AphrontView',
'ConpherenceThreadMailReceiver' => 'PhabricatorObjectMailReceiver', 'ConpherenceThreadMailReceiver' => 'PhabricatorObjectMailReceiver',
'ConpherenceThreadQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'ConpherenceThreadQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'ConpherenceTimeUtilTestCase' => 'PhabricatorTestCase',
'ConpherenceTransaction' => 'PhabricatorApplicationTransaction', 'ConpherenceTransaction' => 'PhabricatorApplicationTransaction',
'ConpherenceTransactionComment' => 'PhabricatorApplicationTransactionComment', 'ConpherenceTransactionComment' => 'PhabricatorApplicationTransactionComment',
'ConpherenceTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 'ConpherenceTransactionQuery' => 'PhabricatorApplicationTransactionQuery',

View file

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

View file

@ -1,37 +1,62 @@
<?php <?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( public static function getCalendarEventEpochs(
PhabricatorUser $user, PhabricatorUser $user,
$start_day_str = 'Sunday') { $start_day_str = 'Sunday',
$days = 9) {
$objects = self::getStartDateTimeObjects($user, $start_day_str); $objects = self::getStartDateTimeObjects($user, $start_day_str);
$start_day = $objects['start_day']; $start_day = $objects['start_day'];
$end_day = clone $start_day; $end_day = clone $start_day;
$end_day->modify('+9 days'); $end_day->modify('+'.$days.' days');
return array( return array(
'start_epoch' => $start_day->format('U'), 'start_epoch' => $start_day->format('U'),
'end_epoch' => $end_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( 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, PhabricatorUser $user,
$start_day_str = 'Sunday') { $start_day_str,
$days) {
$objects = self::getStartDateTimeObjects($user, $start_day_str); $objects = self::getStartDateTimeObjects($user, $start_day_str);
$start_day = $objects['start_day']; $start_day = $objects['start_day'];
$timestamps = array(); $timestamps = array();
for ($day = 0; $day < 9; $day++) { for ($day = 0; $day < $days; $day++) {
$timestamp = clone $start_day; $timestamp = clone $start_day;
$timestamp->modify(sprintf('+%d days', $day)); $timestamp->modify(sprintf('+%d days', $day));
$timestamps[] = $timestamp; $timestamps[] = $timestamp;
} }
return array( return array(
'today' => $objects['today'], 'today' => $objects['today'],
'epoch_stamps' => $timestamps 'epoch_stamps' => $timestamps);
);
} }
private static function getStartDateTimeObjects( private static function getStartDateTimeObjects(
@ -43,7 +68,8 @@ final class ConpherenceTimeUtil {
$today = new DateTime('@'.$today_epoch); $today = new DateTime('@'.$today_epoch);
$today->setTimeZone($timezone); $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; $start_day = clone $today;
} else { } else {
$start_epoch = PhabricatorTime::parseLocalTime( $start_epoch = PhabricatorTime::parseLocalTime(

View file

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

View file

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

View file

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