public function testTimestampsStartDay() { $u = new PhabricatorUser(); $u->setTimezoneIdentifier('America/Los_Angeles'); $days = $this->getAllDays(); foreach ($days as $day) { $data = CalendarTimeUtil::getTimestamps($u, $day, 1); $this->assertEqual($day, $data['epoch_stamps'][0]->format('l')); } $t = 1370202281; // 2013-06-02 12:44:41 -0700 -- a Sunday $time = PhabricatorTime::pushTime($t, 'America/Los_Angeles'); foreach ($days as $day) { $data = CalendarTimeUtil::getTimestamps($u, $day, 1); $this->assertEqual($day, $data['epoch_stamps'][0]->format('l')); } unset($time); }
private function renderCalendarWidgetPaneContent() { $user = $this->getRequest()->getUser(); $conpherence = $this->getConpherence(); $participants = $conpherence->getParticipants(); $widget_data = $conpherence->getWidgetData(); // TODO: This panel is built around an outdated notion of events and isn't // invitee-aware. $statuses = $widget_data['events']; $handles = $conpherence->getHandles(); $content = array(); $layout = id(new AphrontMultiColumnView())->setFluidLayout(true); $timestamps = CalendarTimeUtil::getCalendarWidgetTimestamps($user); $today = $timestamps['today']; $epoch_stamps = $timestamps['epoch_stamps']; $one_day = 24 * 60 * 60; $is_today = false; $calendar_columns = 0; $list_days = 0; foreach ($epoch_stamps as $day) { // build a header for the new day if ($day->format('Ymd') == $today->format('Ymd')) { $active_class = 'today'; $is_today = true; } else { $active_class = ''; $is_today = false; } $should_draw_list = $list_days < 7; $list_days++; if ($should_draw_list) { $content[] = phutil_tag('div', array('class' => 'day-header ' . $active_class), array(phutil_tag('div', array('class' => 'day-name'), $day->format('l')), phutil_tag('div', array('class' => 'day-date'), $day->format('m/d/y')))); } $week_day_number = $day->format('w'); $epoch_start = $day->format('U'); $next_day = clone $day; $next_day->modify('+1 day'); $epoch_end = $next_day->format('U'); $first_status_of_the_day = true; $statuses_of_the_day = array(); // keep looking through statuses where we last left off foreach ($statuses as $status) { if ($status->getDateFrom() >= $epoch_end) { // This list is sorted, so we can stop looking. break; } if ($status->getDateFrom() < $epoch_end && $status->getDateTo() > $epoch_start) { $statuses_of_the_day[$status->getUserPHID()] = $status; if ($should_draw_list) { $top_border = ''; if (!$first_status_of_the_day) { $top_border = ' top-border'; } $timespan = $status->getDateTo() - $status->getDateFrom(); if ($timespan > $one_day) { $time_str = 'm/d'; } else { $time_str = 'h:i A'; } $epoch_range = phabricator_format_local_time($status->getDateFrom(), $user, $time_str) . ' - ' . phabricator_format_local_time($status->getDateTo(), $user, $time_str); if (isset($handles[$status->getUserPHID()])) { $secondary_info = pht('%s, %s', $handles[$status->getUserPHID()]->getName(), $epoch_range); } else { $secondary_info = $epoch_range; } $content[] = phutil_tag('div', array('class' => 'user-status ' . $top_border), array(phutil_tag('div', array('class' => 'icon'), ''), phutil_tag('div', array('class' => 'description'), array($status->getName(), phutil_tag('div', array('class' => 'participant'), $secondary_info))))); } $first_status_of_the_day = false; } } // we didn't get a status on this day so add a spacer if ($first_status_of_the_day && $should_draw_list) { $content[] = phutil_tag('div', array('class' => 'no-events pm'), pht('No Events Scheduled.')); } if ($is_today || $calendar_columns && $calendar_columns < 3) { $active_class = ''; if ($is_today) { $active_class = '-active'; } $inner_layout = array(); foreach ($participants as $phid => $participant) { $status = idx($statuses_of_the_day, $phid, false); if ($status) { $inner_layout[] = phutil_tag('div', array(), ''); } else { $inner_layout[] = phutil_tag('div', array('class' => 'present'), ''); } } $layout->addColumn(phutil_tag('div', array('class' => 'day-column' . $active_class), array(phutil_tag('div', array('class' => 'day-name'), $day->format('D')), phutil_tag('div', array('class' => 'day-number'), $day->format('j')), $inner_layout))); $calendar_columns++; } } return array($layout, $content); }
private function renderUserCalendar(PhabricatorUser $user) { $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($viewer)->withInvitedPHIDs(array($user->getPHID()))->withDateRange($start_epoch, $end_epoch)->execute(); $timestamps = CalendarTimeUtil::getCalendarWeekTimestamps($viewer); $today = $timestamps['today']; $epoch_stamps = $timestamps['epoch_stamps']; $events = array(); 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->getDateTo() < $epoch_start) { continue; } if ($status->getDateFrom() >= $epoch_end) { continue; } $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()); $events[$epoch_start][] = $event; } } $week = array(); foreach ($epoch_stamps as $day) { $epoch = $day->format('U'); $headertext = phabricator_format_local_time($epoch, $user, 'l, M d'); $list = new PHUICalendarListView(); $list->setUser($viewer); $list->showBlankState(true); if (isset($events[$epoch])) { foreach ($events[$epoch] as $event) { $list->addEvent($event); } } $header = phutil_tag('a', array('href' => $this->getRequest()->getRequestURI() . 'calendar/'), $headertext); $calendar = new PHUICalendarWidgetView(); $calendar->setHeader($header); $calendar->setCalendarList($list); $week[] = $calendar; } return phutil_tag_div('profile-calendar', $week); }
private function loadWidgetData(array $conpherences) { $participant_phids = array(); $file_phids = array(); foreach ($conpherences as $conpherence) { $participant_phids[] = array_keys($conpherence->getParticipants()); $file_phids[] = $conpherence->getFilePHIDs(); } $participant_phids = array_mergev($participant_phids); $file_phids = array_mergev($file_phids); $epochs = CalendarTimeUtil::getCalendarEventEpochs($this->getViewer()); $start_epoch = $epochs['start_epoch']; $end_epoch = $epochs['end_epoch']; $events = array(); if ($participant_phids) { $events = id(new PhabricatorCalendarEventQuery())->setViewer($this->getViewer())->withInvitedPHIDs($participant_phids)->withIsCancelled(false)->withDateRange($start_epoch, $end_epoch)->execute(); $events = mpull($events, null, 'getPHID'); } $invitees = array(); foreach ($events as $event_phid => $event) { foreach ($event->getInvitees() as $invitee) { $invitees[$invitee->getInviteePHID()][$event_phid] = true; } } // attached files $files = array(); $file_author_phids = array(); $authors = array(); if ($file_phids) { $files = id(new PhabricatorFileQuery())->setViewer($this->getViewer())->withPHIDs($file_phids)->execute(); $files = mpull($files, null, 'getPHID'); $file_author_phids = mpull($files, 'getAuthorPHID', 'getPHID'); $authors = id(new PhabricatorHandleQuery())->setViewer($this->getViewer())->withPHIDs($file_author_phids)->execute(); $authors = mpull($authors, null, 'getPHID'); } foreach ($conpherences as $phid => $conpherence) { $participant_phids = array_keys($conpherence->getParticipants()); $widget_data = array(); $event_phids = array(); $participant_invites = array_select_keys($invitees, $participant_phids); foreach ($participant_invites as $invite_set) { $event_phids += $invite_set; } $thread_events = array_select_keys($events, array_keys($event_phids)); $thread_events = msort($thread_events, 'getDateFrom'); $widget_data['events'] = $thread_events; $conpherence_files = array(); $files_authors = array(); foreach ($conpherence->getFilePHIDs() as $curr_phid) { $curr_file = idx($files, $curr_phid); if (!$curr_file) { // this file was deleted or user doesn't have permission to see it // this is generally weird continue; } $conpherence_files[$curr_phid] = $curr_file; // some files don't have authors so be careful $current_author = null; $current_author_phid = idx($file_author_phids, $curr_phid); if ($current_author_phid) { $current_author = $authors[$current_author_phid]; } $files_authors[$curr_phid] = $current_author; } $widget_data += array('files' => $conpherence_files, 'files_authors' => $files_authors); $conpherence->attachWidgetData($widget_data); } return $this; }