Page MenuHomestyx hydra

No OneTemporary

diff --git a/src/applications/people/controller/PhabricatorPeopleProfileViewController.php b/src/applications/people/controller/PhabricatorPeopleProfileViewController.php
index 170eabcad0..323d5f66af 100644
--- a/src/applications/people/controller/PhabricatorPeopleProfileViewController.php
+++ b/src/applications/people/controller/PhabricatorPeopleProfileViewController.php
@@ -1,366 +1,367 @@
<?php
final class PhabricatorPeopleProfileViewController
extends PhabricatorPeopleProfileController {
public function shouldAllowPublic() {
return true;
}
public function handleRequest(AphrontRequest $request) {
$viewer = $this->getViewer();
$username = $request->getURIData('username');
$user = id(new PhabricatorPeopleQuery())
->setViewer($viewer)
->withUsernames(array($username))
->needBadges(true)
->needProfileImage(true)
->needAvailability(true)
->executeOne();
if (!$user) {
return new Aphront404Response();
}
$this->setUser($user);
$profile = $user->loadUserProfile();
$picture = $user->getProfileImageURI();
$profile_icon = PhabricatorPeopleIconSet::getIconIcon($profile->getIcon());
$profile_icon = id(new PHUIIconView())
->setIcon($profile_icon);
$profile_title = $profile->getDisplayTitle();
$header = id(new PHUIHeaderView())
->setHeader($user->getFullName())
->setSubheader(array($profile_icon, $profile_title))
->setImage($picture)
->setProfileHeader(true);
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$user,
PhabricatorPolicyCapability::CAN_EDIT);
if ($can_edit) {
$id = $user->getID();
$header->setImageEditURL($this->getApplicationURI("picture/{$id}/"));
}
$properties = $this->buildPropertyView($user);
$name = $user->getUsername();
$feed = $this->buildPeopleFeed($user, $viewer);
$feed = id(new PHUIObjectBoxView())
->setHeaderText(pht('Recent Activity'))
->addClass('project-view-feed')
->appendChild($feed);
$projects = $this->buildProjectsView($user);
$badges = $this->buildBadgesView($user);
$calendar = $this->buildCalendarDayView($user);
require_celerity_resource('project-view-css');
$home = id(new PHUITwoColumnView())
->setHeader($header)
->addClass('project-view-home')
->setMainColumn(
array(
$properties,
$feed,
))
->setSideColumn(
array(
$projects,
$badges,
$calendar,
));
$nav = $this->getProfileMenu();
$nav->selectFilter(PhabricatorPeopleProfilePanelEngine::PANEL_PROFILE);
$crumbs = $this->buildApplicationCrumbs();
$crumbs->setBorder(true);
return $this->newPage()
->setTitle($user->getUsername())
->setNavigation($nav)
->setCrumbs($crumbs)
->appendChild(
array(
$home,
));
}
private function buildPropertyView(
PhabricatorUser $user) {
$viewer = $this->getRequest()->getUser();
$view = id(new PHUIPropertyListView())
->setUser($viewer)
->setObject($user);
$field_list = PhabricatorCustomField::getObjectFields(
$user,
PhabricatorCustomField::ROLE_VIEW);
$field_list->appendFieldsToPropertyList($user, $viewer, $view);
if (!$view->hasAnyProperties()) {
return null;
}
$view = id(new PHUIObjectBoxView())
->appendChild($view)
->addClass('project-view-properties');
return $view;
}
private function buildProjectsView(
PhabricatorUser $user) {
$viewer = $this->getViewer();
$projects = id(new PhabricatorProjectQuery())
->setViewer($viewer)
->withMemberPHIDs(array($user->getPHID()))
->needImages(true)
->withStatuses(
array(
PhabricatorProjectStatus::STATUS_ACTIVE,
))
->execute();
$header = id(new PHUIHeaderView())
->setHeader(pht('Projects'));
if (!empty($projects)) {
$limit = 5;
$render_phids = array_slice($projects, 0, $limit);
$list = id(new PhabricatorProjectListView())
->setUser($viewer)
->setProjects($render_phids);
if (count($projects) > $limit) {
$header_text = pht(
'Projects (%s)',
phutil_count($projects));
$header = id(new PHUIHeaderView())
->setHeader($header_text)
->addActionLink(
id(new PHUIButtonView())
->setTag('a')
->setIcon('fa-list-ul')
->setText(pht('View All'))
->setHref('/project/?member='.$user->getPHID()));
}
} else {
$error = id(new PHUIBoxView())
->addClass('mlb')
->appendChild(pht('User does not belong to any projects.'));
$list = id(new PHUIInfoView())
->setSeverity(PHUIInfoView::SEVERITY_NODATA)
->appendChild($error);
}
$box = id(new PHUIObjectBoxView())
->setHeader($header)
->appendChild($list)
->setBackground(PHUIObjectBoxView::GREY);
return $box;
}
private function buildCalendarDayView(PhabricatorUser $user) {
$viewer = $this->getViewer();
$class = 'PhabricatorCalendarApplication';
if (!PhabricatorApplication::isClassInstalledForViewer($class, $viewer)) {
return null;
}
$midnight = PhabricatorTime::getTodayMidnightDateTime($viewer);
$week_end = clone $midnight;
$week_end = $week_end->modify('+3 days');
$range_start = $midnight->format('U');
$range_end = $week_end->format('U');
$query = id(new PhabricatorCalendarEventQuery())
->setViewer($viewer)
->withDateRange($range_start, $range_end)
->withInvitedPHIDs(array($viewer->getPHID()))
->withIsCancelled(false);
$statuses = $query->execute();
$phids = mpull($statuses, 'getUserPHID');
$events = array();
foreach ($statuses as $status) {
$viewer_is_invited = $status->getIsUserInvited($viewer->getPHID());
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$status,
PhabricatorPolicyCapability::CAN_EDIT);
$event = new AphrontCalendarEventView();
$event->setCanEdit($can_edit);
$event->setEventID($status->getID());
$event->setEpochRange($status->getDateFrom(), $status->getDateTo());
$event->setIsAllDay($status->getIsAllDay());
$event->setIcon($status->getIcon());
$event->setViewerIsInvited($viewer_is_invited);
$event->setName($status->getName());
$event->setURI($status->getURI());
$events[] = $event;
}
$events = msort($events, 'getEpochStart');
$day_view = id(new PHUICalendarWeekView())
->setViewer($viewer)
+ ->setView('week')
->setEvents($events)
->setWeekLength(3)
->render();
$header = id(new PHUIHeaderView())
->setHeader(pht('Calendar'));
$box = id(new PHUIObjectBoxView())
->setHeader($header)
->appendChild($day_view)
->setBackground(PHUIObjectBoxView::GREY);
return $box;
}
private function buildBadgesView(PhabricatorUser $user) {
$viewer = $this->getViewer();
$class = 'PhabricatorBadgesApplication';
if (!PhabricatorApplication::isClassInstalledForViewer($class, $viewer)) {
return null;
}
$awards = array();
$badges = array();
if ($user->getBadgePHIDs()) {
$awards = id(new PhabricatorBadgesAwardQuery())
->setViewer($viewer)
->withRecipientPHIDs(array($user->getPHID()))
->execute();
$awards = mpull($awards, null, 'getBadgePHID');
$badges = array();
foreach ($awards as $award) {
$badge = $award->getBadge();
if ($badge->getStatus() == PhabricatorBadgesBadge::STATUS_ACTIVE) {
$badges[$award->getBadgePHID()] = $badge;
}
}
}
if (count($badges)) {
$flex = new PHUIBadgeBoxView();
foreach ($badges as $badge) {
if ($badge) {
$awarder_info = array();
$award = idx($awards, $badge->getPHID(), null);
$awarder_phid = $award->getAwarderPHID();
$awarder_handle = $viewer->renderHandle($awarder_phid);
$awarder_info = pht(
'Awarded by %s',
$awarder_handle->render());
$item = id(new PHUIBadgeView())
->setIcon($badge->getIcon())
->setHeader($badge->getName())
->setSubhead($badge->getFlavor())
->setQuality($badge->getQuality())
->addByLine($awarder_info);
$flex->addItem($item);
}
}
} else {
$error = id(new PHUIBoxView())
->addClass('mlb')
->appendChild(pht('User does not have any badges.'));
$flex = id(new PHUIInfoView())
->setSeverity(PHUIInfoView::SEVERITY_NODATA)
->appendChild($error);
}
// Best option?
$badges = id(new PhabricatorBadgesQuery())
->setViewer($viewer)
->withStatuses(array(
PhabricatorBadgesBadge::STATUS_ACTIVE,
))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->execute();
$button = id(new PHUIButtonView())
->setTag('a')
->setIcon('fa-plus')
->setText(pht('Award'))
->setWorkflow(true)
->setHref('/badges/award/'.$user->getID().'/');
$can_award = false;
if (count($badges)) {
$can_award = true;
}
$header = id(new PHUIHeaderView())
->setHeader(pht('Badges'));
if (count($badges)) {
$header->addActionLink($button);
}
$box = id(new PHUIObjectBoxView())
->setHeader($header)
->addClass('project-view-badges')
->appendChild($flex)
->setBackground(PHUIObjectBoxView::GREY);
return $box;
}
private function buildPeopleFeed(
PhabricatorUser $user,
$viewer) {
$query = new PhabricatorFeedQuery();
$query->setFilterPHIDs(
array(
$user->getPHID(),
));
$query->setLimit(100);
$query->setViewer($viewer);
$stories = $query->execute();
$builder = new PhabricatorFeedBuilder($stories);
$builder->setUser($viewer);
$builder->setShowHovercards(true);
$builder->setNoDataString(pht('To begin on such a grand journey, '.
'requires but just a single step.'));
$view = $builder->buildView();
return $view->render();
}
}
diff --git a/src/view/phui/calendar/PHUICalendarListView.php b/src/view/phui/calendar/PHUICalendarListView.php
index 9f9bc86a80..fc2929adae 100644
--- a/src/view/phui/calendar/PHUICalendarListView.php
+++ b/src/view/phui/calendar/PHUICalendarListView.php
@@ -1,192 +1,198 @@
<?php
final class PHUICalendarListView extends AphrontTagView {
private $events = array();
private $blankState;
private $view;
private function getView() {
return $this->view;
}
public function setView($view) {
$this->view = $view;
return $this;
}
public function addEvent(AphrontCalendarEventView $event) {
$this->events[] = $event;
return $this;
}
public function showBlankState($state) {
$this->blankState = $state;
return $this;
}
protected function getTagName() {
return 'div';
}
protected function getTagAttributes() {
require_celerity_resource('phui-calendar-css');
require_celerity_resource('phui-calendar-list-css');
return array('class' => 'phui-calendar-event-list');
}
protected function getTagContent() {
if (!$this->blankState && empty($this->events)) {
return '';
}
$singletons = array();
$allday = false;
foreach ($this->events as $event) {
$start_epoch = $event->getEpochStart();
if ($event->getIsAllDay()) {
$timelabel = pht('All Day');
} else {
$timelabel = phabricator_time(
$event->getEpochStart(),
$this->getUser());
}
if ($event->getViewerIsInvited()) {
$icon_color = 'green';
} else {
$icon_color = null;
}
$dot = id(new PHUIIconView())
->setIcon($event->getIcon(), $icon_color)
->addClass('phui-calendar-list-item-icon');
$title = phutil_tag(
'span',
array(
'class' => 'phui-calendar-list-title',
),
$this->getEventTitle($event, $allday));
$time = phutil_tag(
'span',
array(
'class' => 'phui-calendar-list-time',
),
$timelabel);
$class = 'phui-calendar-list-item';
if ($event->getViewerIsInvited()) {
$class = $class.' phui-calendar-viewer-invited';
}
if ($event->getIsAllDay()) {
$class = $class.' all-day';
}
$tip = $this->getEventTooltip($event);
- $tip_align = ($this->getView() == 'day') ? 'E' : 'N';
+ if ($this->getView() == 'day') {
+ $tip_align = 'E';
+ } else if ($this->getView() == 'month') {
+ $tip_align = 'N';
+ } else {
+ $tip_align = 'W';
+ }
$content = javelin_tag(
'a',
array(
'href' => $event->getURI(),
'sigil' => 'has-tooltip',
'meta' => array(
'tip' => $tip,
'size' => 200,
'align' => $tip_align,
),
),
array(
$dot,
$time,
$title,
));
$singletons[] = phutil_tag(
'li',
array(
'class' => $class,
),
$content);
}
if (empty($singletons)) {
$singletons[] = phutil_tag(
'li',
array(
'class' => 'phui-calendar-list-item-empty',
),
pht('Clear sailing ahead.'));
}
$list = phutil_tag(
'ul',
array(
'class' => 'phui-calendar-list',
),
$singletons);
return $list;
}
private function getEventTitle($event) {
$class = 'phui-calendar-item';
return phutil_tag(
'span',
array(
'class' => $class,
),
$event->getName());
}
private function getEventTooltip(AphrontCalendarEventView $event) {
$time_pref = $this->getUser()
->getPreference(PhabricatorUserPreferences::PREFERENCE_TIME_FORMAT);
Javelin::initBehavior('phabricator-tooltips');
$start = id(AphrontFormDateControlValue::newFromEpoch(
$this->getUser(),
$event->getEpochStart()));
$end = id(AphrontFormDateControlValue::newFromEpoch(
$this->getUser(),
$event->getEpochEnd()));
$start_date = $start->getDateTime()->format('m d Y');
$end_date = $end->getDateTime()->format('m d Y');
if ($event->getIsAllDay()) {
if ($start_date == $end_date) {
$tip = pht('All day');
} else {
$tip = pht(
'All day, %s - %s',
$start->getValueAsFormat('M j, Y'),
$end->getValueAsFormat('M j, Y'));
}
} else {
if ($start->getValueDate() == $end->getValueDate()) {
$tip = pht(
'%s - %s',
$start->getValueAsFormat($time_pref),
$end->getValueAsFormat($time_pref));
} else {
$tip = pht(
'%s - %s',
$start->getValueAsFormat('M j, Y, '.$time_pref),
$end->getValueAsFormat('M j, Y, '.$time_pref));
}
}
return $tip;
}
public function getIsViewerInvitedOnList() {
foreach ($this->events as $event) {
if ($event->getViewerIsInvited()) {
return true;
}
}
return false;
}
}
diff --git a/src/view/phui/calendar/PHUICalendarMonthView.php b/src/view/phui/calendar/PHUICalendarMonthView.php
index d40736494e..396947cdbe 100644
--- a/src/view/phui/calendar/PHUICalendarMonthView.php
+++ b/src/view/phui/calendar/PHUICalendarMonthView.php
@@ -1,596 +1,597 @@
<?php
final class PHUICalendarMonthView extends AphrontView {
private $rangeStart;
private $rangeEnd;
private $day;
private $month;
private $year;
private $events = array();
private $browseURI;
private $image;
private $error;
public function setBrowseURI($browse_uri) {
$this->browseURI = $browse_uri;
return $this;
}
private function getBrowseURI() {
return $this->browseURI;
}
public function addEvent(AphrontCalendarEventView $event) {
$this->events[] = $event;
return $this;
}
public function setImage($uri) {
$this->image = $uri;
return $this;
}
public function setInfoView(PHUIInfoView $error) {
$this->error = $error;
return $this;
}
public function __construct(
$range_start,
$range_end,
$month,
$year,
$day = null) {
$this->rangeStart = $range_start;
$this->rangeEnd = $range_end;
$this->day = $day;
$this->month = $month;
$this->year = $year;
}
public function render() {
$viewer = $this->getViewer();
$events = msort($this->events, 'getEpochStart');
$days = $this->getDatesInMonth();
$cell_lists = array();
require_celerity_resource('phui-calendar-month-css');
foreach ($days as $day) {
$day_number = $day->format('j');
$class = 'phui-calendar-month-day';
$weekday = $day->format('w');
$day->setTime(0, 0, 0);
$day_start_epoch = $day->format('U');
$day_end_epoch = id(clone $day)->modify('+1 day')->format('U');
$list_events = array();
$all_day_events = array();
foreach ($events as $event) {
if ($event->getEpochStart() >= $day_end_epoch) {
break;
}
if ($event->getEpochStart() < $day_end_epoch &&
$event->getEpochEnd() > $day_start_epoch) {
if ($event->getIsAllDay()) {
$all_day_events[] = $event;
} else {
$list_events[] = $event;
}
}
}
$max_daily = 15;
$counter = 0;
- $list = new PHUICalendarListView();
- $list->setViewer($viewer);
+ $list = id(new PHUICalendarListView())
+ ->setViewer($viewer)
+ ->setView('month');
foreach ($all_day_events as $item) {
if ($counter <= $max_daily) {
$list->addEvent($item);
}
$counter++;
}
foreach ($list_events as $item) {
if ($counter <= $max_daily) {
$list->addEvent($item);
}
$counter++;
}
$uri = $this->getBrowseURI();
$uri = $uri.$day->format('Y').'/'.
$day->format('m').'/'.
$day->format('d').'/';
$cell_lists[] = array(
'list' => $list,
'date' => $day,
'uri' => $uri,
'count' => count($all_day_events) + count($list_events),
'class' => $class,
);
}
$rows = array();
$cell_lists_by_week = array_chunk($cell_lists, 7);
foreach ($cell_lists_by_week as $week_of_cell_lists) {
$cells = array();
$max_count = $this->getMaxDailyEventsForWeek($week_of_cell_lists);
foreach ($week_of_cell_lists as $cell_list) {
$cells[] = $this->getEventListCell($cell_list, $max_count);
}
$rows[] = phutil_tag('tr', array(), $cells);
$cells = array();
foreach ($week_of_cell_lists as $cell_list) {
$cells[] = $this->getDayNumberCell($cell_list);
}
$rows[] = phutil_tag('tr', array(), $cells);
}
$header = $this->getDayNamesHeader();
$table = phutil_tag(
'table',
array('class' => 'phui-calendar-view'),
array(
$header,
$rows,
));
$warnings = $this->getQueryRangeWarning();
$box = id(new PHUIObjectBoxView())
->setHeader($this->renderCalendarHeader($this->getDateTime()))
->appendChild($table)
->setFormErrors($warnings);
if ($this->error) {
$box->setInfoView($this->error);
}
return $box;
}
private function getMaxDailyEventsForWeek($week_of_cell_lists) {
$max_count = 0;
foreach ($week_of_cell_lists as $cell_list) {
if ($cell_list['count'] > $max_count) {
$max_count = $cell_list['count'];
}
}
return $max_count;
}
private function getEventListCell($event_list, $max_count = 0) {
$list = $event_list['list'];
$class = $event_list['class'];
$uri = $event_list['uri'];
$count = $event_list['count'];
$viewer_is_invited = $list->getIsViewerInvitedOnList();
$event_count_badge = $this->getEventCountBadge($count, $viewer_is_invited);
$cell_day_secret_link = $this->getHiddenDayLink($uri, $max_count, 125);
$cell_data_div = phutil_tag(
'div',
array(
'class' => 'phui-calendar-month-cell-div',
),
array(
$cell_day_secret_link,
$event_count_badge,
$list,
));
return phutil_tag(
'td',
array(
'class' => 'phui-calendar-month-event-list '.$class,
),
$cell_data_div);
}
private function getDayNumberCell($event_list) {
$class = $event_list['class'];
$date = $event_list['date'];
$cell_day_secret_link = null;
$week_number = null;
if ($date) {
$uri = $event_list['uri'];
$cell_day_secret_link = $this->getHiddenDayLink($uri, 0, 25);
$cell_day = phutil_tag(
'a',
array(
'class' => 'phui-calendar-date-number',
'href' => $uri,
),
$date->format('j'));
if ($date->format('w') == 1) {
$week_number = phutil_tag(
'a',
array(
'class' => 'phui-calendar-week-number',
'href' => $uri,
),
$date->format('W'));
}
} else {
$cell_day = null;
}
if ($date && $date->format('j') == $this->day &&
$date->format('m') == $this->month) {
$today_class = 'phui-calendar-today-slot phui-calendar-today';
} else {
$today_class = 'phui-calendar-today-slot';
}
if ($this->isDateInCurrentWeek($date)) {
$today_class .= ' phui-calendar-this-week';
}
$last_week_day = 6;
if ($date->format('w') == $last_week_day) {
$today_class .= ' last-weekday';
}
$today_slot = phutil_tag(
'div',
array(
'class' => $today_class,
),
null);
$cell_div = phutil_tag(
'div',
array(
'class' => 'phui-calendar-month-cell-div',
),
array(
$cell_day_secret_link,
$week_number,
$cell_day,
$today_slot,
));
return phutil_tag(
'td',
array(
'class' => 'phui-calendar-date-number-container '.$class,
),
$cell_div);
}
private function isDateInCurrentWeek($date) {
list($week_start_date, $week_end_date) = $this->getThisWeekRange();
if ($date->format('U') < $week_end_date->format('U') &&
$date->format('U') >= $week_start_date->format('U')) {
return true;
}
return false;
}
private function getEventCountBadge($count, $viewer_is_invited) {
$class = 'phui-calendar-month-count-badge';
if ($viewer_is_invited) {
$class = $class.' viewer-invited-day-badge';
}
$event_count = null;
if ($count > 0) {
$event_count = phutil_tag(
'div',
array(
'class' => $class,
),
$count);
}
return phutil_tag(
'div',
array(
'class' => 'phui-calendar-month-event-count',
),
$event_count);
}
private function getHiddenDayLink($uri, $count, $max_height) {
// approximately the height of the tallest cell
$height = 18 * $count + 5;
$height = ($height > $max_height) ? $height : $max_height;
$height_style = 'height: '.$height.'px';
return phutil_tag(
'a',
array(
'class' => 'phui-calendar-month-secret-link',
'style' => $height_style,
'href' => $uri,
),
null);
}
private function getDayNamesHeader() {
list($week_start, $week_end) = $this->getWeekStartAndEnd();
$weekday_names = array(
$this->getDayHeader(pht('Sun'), pht('Sunday'), true),
$this->getDayHeader(pht('Mon'), pht('Monday')),
$this->getDayHeader(pht('Tue'), pht('Tuesday')),
$this->getDayHeader(pht('Wed'), pht('Wednesday')),
$this->getDayHeader(pht('Thu'), pht('Thursday')),
$this->getDayHeader(pht('Fri'), pht('Friday')),
$this->getDayHeader(pht('Sat'), pht('Saturday'), true),
);
$sorted_weekday_names = array();
for ($i = $week_start; $i < ($week_start + 7); $i++) {
$sorted_weekday_names[] = $weekday_names[$i % 7];
}
return phutil_tag(
'tr',
array('class' => 'phui-calendar-day-of-week-header'),
$sorted_weekday_names);
}
private function getDayHeader($short, $long, $is_weekend = false) {
$class = null;
if ($is_weekend) {
$class = 'weekend-day-header';
}
$day = array();
$day[] = phutil_tag(
'span',
array(
'class' => 'long-weekday-name',
),
$long);
$day[] = phutil_tag(
'span',
array(
'class' => 'short-weekday-name',
),
$short);
return phutil_tag(
'th',
array(
'class' => $class,
),
$day);
}
private function renderCalendarHeader(DateTime $date) {
$button_bar = null;
// check for a browseURI, which means we need "fancy" prev / next UI
$uri = $this->getBrowseURI();
if ($uri) {
list($prev_year, $prev_month) = $this->getPrevYearAndMonth();
$prev_uri = $uri.$prev_year.'/'.$prev_month.'/';
list($next_year, $next_month) = $this->getNextYearAndMonth();
$next_uri = $uri.$next_year.'/'.$next_month.'/';
$button_bar = new PHUIButtonBarView();
$left_icon = id(new PHUIIconView())
->setIcon('fa-chevron-left bluegrey');
$left = id(new PHUIButtonView())
->setTag('a')
->setColor(PHUIButtonView::GREY)
->setHref($prev_uri)
->setTitle(pht('Previous Month'))
->setIcon($left_icon);
$right_icon = id(new PHUIIconView())
->setIcon('fa-chevron-right bluegrey');
$right = id(new PHUIButtonView())
->setTag('a')
->setColor(PHUIButtonView::GREY)
->setHref($next_uri)
->setTitle(pht('Next Month'))
->setIcon($right_icon);
$button_bar->addButton($left);
$button_bar->addButton($right);
}
$header = id(new PHUIHeaderView())
->setHeader($date->format('F Y'));
if ($button_bar) {
$header->setButtonBar($button_bar);
}
if ($this->image) {
$header->setImage($this->image);
}
return $header;
}
private function getQueryRangeWarning() {
$errors = array();
$range_start_epoch = null;
$range_end_epoch = null;
if ($this->rangeStart) {
$range_start_epoch = $this->rangeStart->getEpoch();
}
if ($this->rangeEnd) {
$range_end_epoch = $this->rangeEnd->getEpoch();
}
$month_start = $this->getDateTime();
$month_end = id(clone $month_start)->modify('+1 month');
$month_start = $month_start->format('U');
$month_end = $month_end->format('U') - 1;
if (($range_start_epoch != null &&
$range_start_epoch < $month_end &&
$range_start_epoch > $month_start) ||
($range_end_epoch != null &&
$range_end_epoch < $month_end &&
$range_end_epoch > $month_start)) {
$errors[] = pht('Part of the month is out of range');
}
if (($range_end_epoch != null &&
$range_end_epoch < $month_start) ||
($range_start_epoch != null &&
$range_start_epoch > $month_end)) {
$errors[] = pht('Month is out of query range');
}
return $errors;
}
private function getNextYearAndMonth() {
$next = $this->getDateTime();
$next->modify('+1 month');
return array(
$next->format('Y'),
$next->format('m'),
);
}
private function getPrevYearAndMonth() {
$prev = $this->getDateTime();
$prev->modify('-1 month');
return array(
$prev->format('Y'),
$prev->format('m'),
);
}
/**
* Return a DateTime object representing the first moment in each day in the
* month, according to the user's locale.
*
* @return list List of DateTimes, one for each day.
*/
private function getDatesInMonth() {
$viewer = $this->getViewer();
$timezone = new DateTimeZone($viewer->getTimezoneIdentifier());
$month = $this->month;
$year = $this->year;
list($next_year, $next_month) = $this->getNextYearAndMonth();
$end_date = new DateTime("{$next_year}-{$next_month}-01", $timezone);
list($start_of_week, $end_of_week) = $this->getWeekStartAndEnd();
$days_in_month = id(clone $end_date)->modify('-1 day')->format('d');
$first_month_day_date = new DateTime("{$year}-{$month}-01", $timezone);
$last_month_day_date = id(clone $end_date)->modify('-1 day');
$first_weekday_of_month = $first_month_day_date->format('w');
$last_weekday_of_month = $last_month_day_date->format('w');
$day_date = id(clone $first_month_day_date);
$num_days_display = $days_in_month;
if ($start_of_week !== $first_weekday_of_month) {
$interim_start_num = ($first_weekday_of_month + 7 - $start_of_week) % 7;
$num_days_display += $interim_start_num;
$day_date->modify('-'.$interim_start_num.' days');
}
if ($end_of_week !== $last_weekday_of_month) {
$interim_end_day_num = ($end_of_week - $last_weekday_of_month + 7) % 7;
$num_days_display += $interim_end_day_num;
$end_date->modify('+'.$interim_end_day_num.' days');
}
$days = array();
for ($day = 1; $day <= $num_days_display; $day++) {
$day_epoch = $day_date->format('U');
$end_epoch = $end_date->format('U');
if ($day_epoch >= $end_epoch) {
break;
} else {
$days[] = clone $day_date;
}
$day_date->modify('+1 day');
}
return $days;
}
private function getTodayMidnight() {
$viewer = $this->getUser();
$today = new DateTime('@'.time());
$today->setTimeZone($viewer->getTimeZone());
$today->setTime(0, 0, 0);
return $today;
}
private function getThisWeekRange() {
list($week_start, $week_end) = $this->getWeekStartAndEnd();
$today = $this->getTodayMidnight();
$date_weekday = $today->format('w');
$days_from_week_start = ($date_weekday + 7 - $week_start) % 7;
$days_to_week_end = 7 - $days_from_week_start;
$modify = '-'.$days_from_week_start.' days';
$week_start_date = id(clone $today)->modify($modify);
$modify = '+'.$days_to_week_end.' days';
$week_end_date = id(clone $today)->modify($modify);
return array($week_start_date, $week_end_date);
}
private function getWeekStartAndEnd() {
$preferences = $this->getViewer()->loadPreferences();
$pref_week_start = PhabricatorUserPreferences::PREFERENCE_WEEK_START_DAY;
$week_start = $preferences->getPreference($pref_week_start, 0);
$week_end = ($week_start + 6) % 7;
return array($week_start, $week_end);
}
private function getDateTime() {
$user = $this->getViewer();
$timezone = new DateTimeZone($user->getTimezoneIdentifier());
$month = $this->month;
$year = $this->year;
$date = new DateTime("{$year}-{$month}-01 ", $timezone);
return $date;
}
}
diff --git a/src/view/phui/calendar/PHUICalendarWeekView.php b/src/view/phui/calendar/PHUICalendarWeekView.php
index bcfc3666c1..6237e5b569 100644
--- a/src/view/phui/calendar/PHUICalendarWeekView.php
+++ b/src/view/phui/calendar/PHUICalendarWeekView.php
@@ -1,121 +1,131 @@
<?php
final class PHUICalendarWeekView extends AphrontView {
private $events;
private $dateTime;
private $weekLength = 7;
+ private $view = 'day';
public function setEvents($events) {
$this->events = $events;
return $this;
}
public function setDateTime($date_time) {
$this->dateTime = $date_time;
return $this;
}
private function getDateTime() {
if ($this->dateTime) {
return $this->dateTime;
}
return $this->getDefaultDateTime();
}
public function setWeekLength($week_length) {
$this->weekLength = $week_length;
return $this;
}
+ public function setView($view) {
+ $this->view = $view;
+ return $this;
+ }
+
+ private function getView() {
+ return $this->view;
+ }
+
public function render() {
$this->events = msort($this->events, 'getEpochStart');
$week_of_boxes = $this->getWeekOfBoxes();
$filled_boxes = array();
foreach ($week_of_boxes as $day_box) {
$box_start = $day_box['start'];
$box_end = id(clone $box_start)->modify('+1 day');
$box_start = $box_start->format('U');
$box_end = $box_end->format('U');
$box_events = array();
foreach ($this->events as $event) {
$event_start = $event->getEpochStart();
$event_end = $event->getEpochEnd();
if ($event_start < $box_end && $event_end > $box_start) {
$box_events[] = $event;
}
}
$filled_boxes[] = $this->renderSidebarBox(
$box_events,
$day_box['title']);
}
return $filled_boxes;
}
private function renderSidebarBox($events, $title) {
$widget = id(new PHUICalendarWidgetView())
->addClass('calendar-day-view-sidebar');
$list = id(new PHUICalendarListView())
->setUser($this->getViewer())
- ->setView('day');
+ ->setView($this->getView());
if (count($events) == 0) {
$list->showBlankState(true);
} else {
$sorted_events = msort($events, 'getEpochStart');
foreach ($sorted_events as $event) {
$list->addEvent($event);
}
}
$widget
->setCalendarList($list)
->setHeader($title);
return $widget;
}
private function getWeekOfBoxes() {
$day_boxes = array();
$week_length = $this->weekLength - 1;
$display_start_day = $this->getDateTime();
$display_end_day = id(clone $display_start_day)
->modify('+'.$week_length.' day');
$box_start_time = clone $display_start_day;
$today_time = PhabricatorTime::getTodayMidnightDateTime($this->getViewer());
$tomorrow_time = clone $today_time;
$tomorrow_time->modify('+1 day');
while ($box_start_time <= $display_end_day) {
if ($box_start_time == $today_time) {
$title = pht('Today');
} else if ($box_start_time == $tomorrow_time) {
$title = pht('Tomorrow');
} else {
$title = $box_start_time->format('l');
}
$day_boxes[] = array(
'title' => $title,
'start' => clone $box_start_time,
);
$box_start_time->modify('+1 day');
}
return $day_boxes;
}
private function getDefaultDateTime() {
return PhabricatorTime::getTodayMidnightDateTime($this->getViewer());
}
}

File Metadata

Mime Type
text/x-diff
Expires
Sun, Jul 27, 2:58 PM (1 w, 10 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
185948
Default Alt Text
(35 KB)

Event Timeline