Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F2889406
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Advanced/Developer...
View Handle
View Hovercard
Size
27 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/src/applications/calendar/application/PhabricatorCalendarApplication.php b/src/applications/calendar/application/PhabricatorCalendarApplication.php
index b9c17e6a43..7a1ca000e5 100644
--- a/src/applications/calendar/application/PhabricatorCalendarApplication.php
+++ b/src/applications/calendar/application/PhabricatorCalendarApplication.php
@@ -1,89 +1,89 @@
<?php
final class PhabricatorCalendarApplication extends PhabricatorApplication {
public function getName() {
return pht('Calendar');
}
public function getShortDescription() {
return pht('Upcoming Events');
}
public function getFlavorText() {
return pht('Never miss an episode ever again.');
}
public function getBaseURI() {
return '/calendar/';
}
public function getFontIcon() {
return 'fa-calendar';
}
public function getTitleGlyph() {
// Unicode has a calendar character but it's in some distant code plane,
// use "keyboard" since it looks vaguely similar.
return "\xE2\x8C\xA8";
}
public function isPrototype() {
return true;
}
public function getRemarkupRules() {
return array(
new PhabricatorCalendarRemarkupRule(),
);
}
public function getRoutes() {
return array(
'/E(?P<id>[1-9]\d*)' => 'PhabricatorCalendarEventViewController',
'/calendar/' => array(
- '(?:query/(?P<queryKey>[^/]+)/)?'
+ '(?:query/(?P<queryKey>[^/]+)/(?:(?P<year>\d+)/(?P<month>\d+)/)?)?'
=> 'PhabricatorCalendarEventListController',
'event/' => array(
'create/'
=> 'PhabricatorCalendarEventEditController',
'edit/(?P<id>[1-9]\d*)/'
=> 'PhabricatorCalendarEventEditController',
'cancel/(?P<id>[1-9]\d*)/'
=> 'PhabricatorCalendarEventCancelController',
'(?P<action>join|decline|accept)/(?P<id>[1-9]\d*)/'
=> 'PhabricatorCalendarEventJoinController',
'comment/(?P<id>[1-9]\d*)/'
=> 'PhabricatorCalendarEventCommentController',
),
),
);
}
public function getQuickCreateItems(PhabricatorUser $viewer) {
$items = array();
$item = id(new PHUIListItemView())
->setName(pht('Calendar Event'))
->setIcon('fa-calendar')
->setHref($this->getBaseURI().'event/create/');
$items[] = $item;
return $items;
}
public function getMailCommandObjects() {
return array(
'event' => array(
'name' => pht('Email Commands: Events'),
'header' => pht('Interacting with Calendar Events'),
'object' => new PhabricatorCalendarEvent(),
'summary' => pht(
'This page documents the commands you can use to interact with '.
'events in Calendar. These commands work when creating new tasks '.
'via email and when replying to existing tasks.'),
),
);
}
}
diff --git a/src/applications/calendar/controller/PhabricatorCalendarEventListController.php b/src/applications/calendar/controller/PhabricatorCalendarEventListController.php
index 1d82160a59..30a908fb8e 100644
--- a/src/applications/calendar/controller/PhabricatorCalendarEventListController.php
+++ b/src/applications/calendar/controller/PhabricatorCalendarEventListController.php
@@ -1,39 +1,41 @@
<?php
final class PhabricatorCalendarEventListController
extends PhabricatorCalendarController {
- private $queryKey;
-
public function shouldAllowPublic() {
return true;
}
- public function willProcessRequest(array $data) {
- $this->queryKey = idx($data, 'queryKey');
- }
+ public function handleRequest(AphrontRequest $request) {
+ $year = $request->getURIData('year');
+ $month = $request->getURIData('month');
+ $engine = new PhabricatorCalendarEventSearchEngine();
+
+ if ($month && $year) {
+ $engine->setCalendarYearAndMonth($year, $month);
+ }
- public function processRequest() {
$controller = id(new PhabricatorApplicationSearchController())
- ->setQueryKey($this->queryKey)
- ->setSearchEngine(new PhabricatorCalendarEventSearchEngine())
+ ->setQueryKey($request->getURIData('queryKey'))
+ ->setSearchEngine($engine)
->setNavigation($this->buildSideNav());
return $this->delegateToController($controller);
}
public function buildSideNav() {
$user = $this->getRequest()->getUser();
$nav = new AphrontSideNavFilterView();
$nav->setBaseURI(new PhutilURI($this->getApplicationURI()));
id(new PhabricatorCalendarEventSearchEngine())
->setViewer($user)
->addNavigationItems($nav->getMenu());
$nav->selectFilter(null);
return $nav;
}
}
diff --git a/src/applications/calendar/query/PhabricatorCalendarEventSearchEngine.php b/src/applications/calendar/query/PhabricatorCalendarEventSearchEngine.php
index 9ad462577d..b65180ce66 100644
--- a/src/applications/calendar/query/PhabricatorCalendarEventSearchEngine.php
+++ b/src/applications/calendar/query/PhabricatorCalendarEventSearchEngine.php
@@ -1,317 +1,379 @@
<?php
final class PhabricatorCalendarEventSearchEngine
extends PhabricatorApplicationSearchEngine {
+ private $calendarYear;
+ private $calendarMonth;
+
public function getResultTypeDescription() {
return pht('Calendar Events');
}
public function getApplicationClassName() {
return 'PhabricatorCalendarApplication';
}
public function buildSavedQueryFromRequest(AphrontRequest $request) {
$saved = new PhabricatorSavedQuery();
$saved->setParameter(
'rangeStart',
$this->readDateFromRequest($request, 'rangeStart'));
$saved->setParameter(
'rangeEnd',
$this->readDateFromRequest($request, 'rangeEnd'));
$saved->setParameter(
'upcoming',
$this->readBoolFromRequest($request, 'upcoming'));
$saved->setParameter(
'invitedPHIDs',
$this->readUsersFromRequest($request, 'invited'));
$saved->setParameter(
'creatorPHIDs',
$this->readUsersFromRequest($request, 'creators'));
$saved->setParameter(
'isCancelled',
$request->getStr('isCancelled'));
$saved->setParameter(
'display',
$request->getStr('display'));
return $saved;
}
public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) {
$query = id(new PhabricatorCalendarEventQuery());
+ $viewer = $this->requireViewer();
$min_range = null;
$max_range = null;
if ($saved->getParameter('rangeStart')) {
$min_range = $saved->getParameter('rangeStart');
}
if ($saved->getParameter('rangeEnd')) {
$max_range = $saved->getParameter('rangeEnd');
}
+ if ($saved->getParameter('display') == 'month') {
+ list($start_month, $start_year) = $this->getDisplayMonthAndYear($saved);
+ $start_day = 1;
+
+ $end_year = ($start_month == 12) ? $start_year + 1 : $start_year;
+ $end_month = ($start_month == 12) ? 1 : $start_month + 1;
+ $end_day = 1;
+
+ $calendar_start = AphrontFormDateControlValue::newFromParts(
+ $viewer,
+ $start_year,
+ $start_month,
+ $start_day)->getEpoch();
+ $calendar_end = AphrontFormDateControlValue::newFromParts(
+ $viewer,
+ $end_year,
+ $end_month,
+ $end_day)->getEpoch();
+
+ if (!$min_range || ($min_range < $calendar_start)) {
+ $min_range = $calendar_start;
+ }
+ if (!$max_range || ($max_range > $calendar_end)) {
+ $max_range = $calendar_end;
+ }
+ }
+
if ($saved->getParameter('upcoming')) {
if ($min_range) {
$min_range = max(time(), $min_range);
} else {
$min_range = time();
}
}
if ($min_range || $max_range) {
$query->withDateRange($min_range, $max_range);
}
$invited_phids = $saved->getParameter('invitedPHIDs');
if ($invited_phids) {
$query->withInvitedPHIDs($invited_phids);
}
$creator_phids = $saved->getParameter('creatorPHIDs');
if ($creator_phids) {
$query->withCreatorPHIDs($creator_phids);
}
$is_cancelled = $saved->getParameter('isCancelled');
switch ($is_cancelled) {
case 'active':
$query->withIsCancelled(false);
break;
case 'cancelled':
$query->withIsCancelled(true);
break;
}
return $query;
}
public function buildSearchForm(
AphrontFormView $form,
PhabricatorSavedQuery $saved) {
$range_start = $saved->getParameter('rangeStart');
$range_end = $saved->getParameter('rangeEnd');
$upcoming = $saved->getParameter('upcoming');
$is_cancelled = $saved->getParameter('isCancelled', 'active');
$display = $saved->getParameter('display', 'month');
$invited_phids = $saved->getParameter('invitedPHIDs', array());
$creator_phids = $saved->getParameter('creatorPHIDs', array());
$resolution_types = array(
'active' => pht('Active Events Only'),
'cancelled' => pht('Cancelled Events Only'),
'both' => pht('Both Cancelled and Active Events'),
);
$display_options = array(
'month' => pht('Month View'),
'list' => pht('List View'),
);
$form
->appendControl(
id(new AphrontFormTokenizerControl())
->setDatasource(new PhabricatorPeopleDatasource())
->setName('creators')
->setLabel(pht('Created By'))
->setValue($creator_phids))
->appendControl(
id(new AphrontFormTokenizerControl())
->setDatasource(new PhabricatorPeopleDatasource())
->setName('invited')
->setLabel(pht('Invited'))
->setValue($invited_phids))
->appendChild(
id(new AphrontFormDateControl())
->setLabel(pht('Occurs After'))
->setUser($this->requireViewer())
->setName('rangeStart')
->setAllowNull(true)
->setValue($range_start))
->appendChild(
id(new AphrontFormDateControl())
->setLabel(pht('Occurs Before'))
->setUser($this->requireViewer())
->setName('rangeEnd')
->setAllowNull(true)
->setValue($range_end))
->appendChild(
id(new AphrontFormCheckboxControl())
->addCheckbox(
'upcoming',
1,
pht('Show only upcoming events.'),
$upcoming))
->appendChild(
id(new AphrontFormSelectControl())
->setLabel(pht('Cancelled Events'))
->setName('isCancelled')
->setValue($is_cancelled)
->setOptions($resolution_types))
->appendChild(
id(new AphrontFormSelectControl())
->setLabel(pht('Display Options'))
->setName('display')
->setValue($display)
->setOptions($display_options));
}
protected function getURI($path) {
return '/calendar/'.$path;
}
protected function getBuiltinQueryNames() {
$names = array(
'month' => pht('Month View'),
'upcoming' => pht('Upcoming Events'),
'all' => pht('All Events'),
);
return $names;
}
+ public function setCalendarYearAndMonth($year, $month) {
+ $this->calendarYear = $year;
+ $this->calendarMonth = $month;
+
+ return $this;
+ }
+
public function buildSavedQueryFromBuiltin($query_key) {
$query = $this->newSavedQuery();
$query->setQueryKey($query_key);
switch ($query_key) {
case 'month':
return $query->setParameter('display', 'month');
case 'upcoming':
return $query->setParameter('upcoming', true);
case 'all':
return $query;
}
return parent::buildSavedQueryFromBuiltin($query_key);
}
protected function getRequiredHandlePHIDsForResultList(
array $objects,
PhabricatorSavedQuery $query) {
$phids = array();
foreach ($objects as $event) {
$phids[$event->getUserPHID()] = 1;
}
return array_keys($phids);
}
protected function renderResultList(
array $events,
PhabricatorSavedQuery $query,
array $handles) {
if ($query->getParameter('display') == 'month') {
return $this->buildCalendarView($events, $query, $handles);
}
assert_instances_of($events, 'PhabricatorCalendarEvent');
$viewer = $this->requireViewer();
$list = new PHUIObjectItemListView();
foreach ($events as $event) {
$href = '/E'.$event->getID();
$from = phabricator_datetime($event->getDateFrom(), $viewer);
$to = phabricator_datetime($event->getDateTo(), $viewer);
$creator_handle = $handles[$event->getUserPHID()];
$name = (strlen($event->getName())) ?
$event->getName() : $event->getTerseSummary($viewer);
$color = ($event->getStatus() == PhabricatorCalendarEvent::STATUS_AWAY)
? 'red'
: 'yellow';
$item = id(new PHUIObjectItemView())
->setHeader($name)
->setHref($href)
->setBarColor($color)
->addByline(pht('Creator: %s', $creator_handle->renderLink()))
->addAttribute(pht('From %s to %s', $from, $to))
->addAttribute(id(new PhutilUTF8StringTruncator())
->setMaximumGlyphs(64)
->truncateString($event->getDescription()));
$list->addItem($item);
}
return $list;
}
private function buildCalendarView(
array $statuses,
PhabricatorSavedQuery $query,
array $handles) {
$viewer = $this->requireViewer();
$now = time();
- $epoch = $query->getParameter('rangeStart');
- if (!$epoch) {
- $epoch = $query->getParameter('rangeEnd');
- if (!$epoch) {
- $epoch = time();
- }
- }
-
- $year = phabricator_format_local_time($epoch, $viewer, 'Y');
- $month = phabricator_format_local_time($epoch, $viewer, 'm');
+ list($start_month, $start_year) = $this->getDisplayMonthAndYear($query);
$now_year = phabricator_format_local_time($now, $viewer, 'Y');
$now_month = phabricator_format_local_time($now, $viewer, 'm');
$now_day = phabricator_format_local_time($now, $viewer, 'j');
- if ($month == $now_month && $year == $now_year) {
- $month_view = new PHUICalendarMonthView($month, $year, $now_day);
+ if ($start_month == $now_month && $start_year == $now_year) {
+ $month_view = new PHUICalendarMonthView(
+ $start_month,
+ $start_year,
+ $now_day);
} else {
- $month_view = new PHUICalendarMonthView($month, $year);
+ $month_view = new PHUICalendarMonthView(
+ $start_month,
+ $start_year);
}
$month_view->setUser($viewer);
$phids = mpull($statuses, 'getUserPHID');
/* Assign Colors */
$unique = array_unique($phids);
$allblue = false;
$calcolors = CalendarColors::getColors();
if (count($unique) > count($calcolors)) {
$allblue = true;
}
$i = 0;
$eventcolor = array();
foreach ($unique as $phid) {
if ($allblue) {
$eventcolor[$phid] = CalendarColors::COLOR_SKY;
} else {
$eventcolor[$phid] = $calcolors[$i];
}
$i++;
}
foreach ($statuses as $status) {
$event = new AphrontCalendarEventView();
$event->setEpochRange($status->getDateFrom(), $status->getDateTo());
$name_text = $handles[$status->getUserPHID()]->getName();
$status_text = $status->getHumanStatus();
$event->setUserPHID($status->getUserPHID());
$event->setDescription(pht('%s (%s)', $name_text, $status_text));
$event->setName($status_text);
$event->setEventID($status->getID());
$event->setColor($eventcolor[$status->getUserPHID()]);
$month_view->addEvent($event);
}
+ $month_view->setBrowseURI(
+ $this->getURI('query/'.$query->getQueryKey().'/'));
+
return $month_view;
+ }
+
+ private function getDisplayMonthAndYear(
+ PhabricatorSavedQuery $query) {
+ $viewer = $this->requireViewer();
+ // get month/year from url
+ if ($this->calendarYear && $this->calendarMonth) {
+ $start_year = $this->calendarYear;
+ $start_month = $this->calendarMonth;
+ } else {
+ $epoch = $query->getParameter('rangeStart');
+ if (!$epoch) {
+ $epoch = $query->getParameter('rangeEnd');
+ if (!$epoch) {
+ $epoch = time();
+ }
+ }
+ $start_year = phabricator_format_local_time($epoch, $viewer, 'Y');
+ $start_month = phabricator_format_local_time($epoch, $viewer, 'm');
+ }
+
+ return array($start_month, $start_year);
+ }
+ public function getPageSize(PhabricatorSavedQuery $saved) {
+ return $saved->getParameter('limit', 1000);
}
}
diff --git a/src/view/form/control/AphrontFormDateControlValue.php b/src/view/form/control/AphrontFormDateControlValue.php
index 5462e40a18..0874475884 100644
--- a/src/view/form/control/AphrontFormDateControlValue.php
+++ b/src/view/form/control/AphrontFormDateControlValue.php
@@ -1,97 +1,114 @@
<?php
final class AphrontFormDateControlValue extends Phobject {
private $valueDay;
private $valueMonth;
private $valueYear;
private $valueTime;
private $viewer;
private $zone;
public function getValueDay() {
return $this->valueDay;
}
public function getValueMonth() {
return $this->valueMonth;
}
public function getValueYear() {
return $this->valueYear;
}
public function getValueTime() {
return $this->valueTime;
}
public function isValid() {
return ($this->getEpoch() !== null);
}
+ public static function newFromParts(
+ PhabricatorUser $viewer,
+ $year,
+ $month,
+ $day,
+ $time = '12:00 AM') {
+
+ $value = new AphrontFormDateControlValue();
+ $value->viewer = $viewer;
+ $value->valueYear = $year;
+ $value->valueMonth = $month;
+ $value->valueDay = $day;
+ $value->valueTime = $time;
+
+ return $value;
+ }
+
public static function newFromRequest($request, $key) {
$value = new AphrontFormDateControlValue();
$value->viewer = $request->getViewer();
$value->valueDay = $request->getInt($key.'_d');
$value->valueMonth = $request->getInt($key.'_m');
$value->valueYear = $request->getInt($key.'_y');
$value->valueTime = $request->getStr($key.'_t');
return $value;
}
public static function newFromEpoch(PhabricatorUser $viewer, $epoch) {
$value = new AphrontFormDateControlValue();
$value->viewer = $viewer;
$readable = $value->formatTime($epoch, 'Y!m!d!g:i A');
$readable = explode('!', $readable, 4);
$value->valueYear = $readable[0];
$value->valueMonth = $readable[1];
$value->valueDay = $readable[2];
$value->valueTime = $readable[3];
return $value;
}
private function formatTime($epoch, $format) {
return phabricator_format_local_time(
$epoch,
$this->viewer,
$format);
}
public function getEpoch() {
$year = $this->valueYear;
$month = $this->valueMonth;
$day = $this->valueDay;
$time = $this->valueTime;
$zone = $this->getTimezone();
if (!strlen($time)) {
return null;
}
try {
$date = new DateTime("{$year}-{$month}-{$day} {$time}", $zone);
$value = $date->format('U');
} catch (Exception $ex) {
$value = null;
}
return $value;
}
private function getTimezone() {
if ($this->zone) {
return $this->zone;
}
$viewer_zone = $this->viewer->getTimezoneIdentifier();
$this->zone = new DateTimeZone($viewer_zone);
return $this->zone;
}
}
diff --git a/src/view/phui/calendar/PHUICalendarMonthView.php b/src/view/phui/calendar/PHUICalendarMonthView.php
index b69128e5e8..c4a7624a3d 100644
--- a/src/view/phui/calendar/PHUICalendarMonthView.php
+++ b/src/view/phui/calendar/PHUICalendarMonthView.php
@@ -1,319 +1,316 @@
<?php
final class PHUICalendarMonthView extends AphrontView {
private $day;
private $month;
private $year;
private $holidays = array();
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 setHolidays(array $holidays) {
assert_instances_of($holidays, 'PhabricatorCalendarHoliday');
$this->holidays = mpull($holidays, null, 'getDay');
return $this;
}
public function __construct($month, $year, $day = null) {
$this->day = $day;
$this->month = $month;
$this->year = $year;
}
public function render() {
if (empty($this->user)) {
throw new Exception('Call setUser() before render()!');
}
$events = msort($this->events, 'getEpochStart');
$days = $this->getDatesInMonth();
require_celerity_resource('phui-calendar-month-css');
$first = reset($days);
$empty = $first->format('w');
$markup = array();
$empty_box = phutil_tag(
'div',
array('class' => 'phui-calendar-day phui-calendar-empty'),
'');
for ($ii = 0; $ii < $empty; $ii++) {
$markup[] = $empty_box;
}
$show_events = array();
foreach ($days as $day) {
$day_number = $day->format('j');
$holiday = idx($this->holidays, $day->format('Y-m-d'));
$class = 'phui-calendar-day';
$weekday = $day->format('w');
if ($day_number == $this->day) {
$class .= ' phui-calendar-today';
}
if ($holiday || $weekday == 0 || $weekday == 6) {
$class .= ' phui-calendar-not-work-day';
}
$day->setTime(0, 0, 0);
$epoch_start = $day->format('U');
$day->modify('+1 day');
$epoch_end = $day->format('U');
if ($weekday == 0) {
$show_events = array();
} else {
$show_events = array_fill_keys(
array_keys($show_events),
phutil_tag_div(
'phui-calendar-event phui-calendar-event-empty',
"\xC2\xA0")); //
}
$list_events = array();
foreach ($events as $event) {
if ($event->getEpochStart() >= $epoch_end) {
// This list is sorted, so we can stop looking.
break;
}
if ($event->getEpochStart() < $epoch_end &&
$event->getEpochEnd() > $epoch_start) {
$list_events[] = $event;
}
}
$list = new PHUICalendarListView();
$list->setUser($this->user);
foreach ($list_events as $item) {
$list->addEvent($item);
}
$holiday_markup = null;
if ($holiday) {
$name = $holiday->getName();
$holiday_markup = phutil_tag(
'div',
array(
'class' => 'phui-calendar-holiday',
'title' => $name,
),
$name);
}
$markup[] = phutil_tag_div(
$class,
array(
phutil_tag_div('phui-calendar-date-number', $day_number),
$holiday_markup,
$list,
));
}
$table = array();
$rows = array_chunk($markup, 7);
foreach ($rows as $row) {
$cells = array();
while (count($row) < 7) {
$row[] = $empty_box;
}
$j = 0;
foreach ($row as $cell) {
if ($j == 0) {
$cells[] = phutil_tag(
'td',
array(
'class' => 'phui-calendar-month-weekstart',
),
$cell);
} else {
$cells[] = phutil_tag('td', array(), $cell);
}
$j++;
}
$table[] = phutil_tag('tr', array(), $cells);
}
$header = phutil_tag(
'tr',
array('class' => 'phui-calendar-day-of-week-header'),
array(
phutil_tag('th', array(), pht('Sun')),
phutil_tag('th', array(), pht('Mon')),
phutil_tag('th', array(), pht('Tue')),
phutil_tag('th', array(), pht('Wed')),
phutil_tag('th', array(), pht('Thu')),
phutil_tag('th', array(), pht('Fri')),
phutil_tag('th', array(), pht('Sat')),
));
$table = phutil_tag(
'table',
array('class' => 'phui-calendar-view'),
array(
$header,
phutil_implode_html("\n", $table),
));
$box = id(new PHUIObjectBoxView())
->setHeader($this->renderCalendarHeader($first))
->appendChild($table);
if ($this->error) {
$box->setInfoView($this->error);
}
return $box;
}
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) {
- $uri = new PhutilURI($uri);
list($prev_year, $prev_month) = $this->getPrevYearAndMonth();
- $query = array('year' => $prev_year, 'month' => $prev_month);
- $prev_uri = (string) $uri->setQueryParams($query);
+ $prev_uri = $uri.$prev_year.'/'.$prev_month.'/';
list($next_year, $next_month) = $this->getNextYearAndMonth();
- $query = array('year' => $next_year, 'month' => $next_month);
- $next_uri = (string) $uri->setQueryParams($query);
+ $next_uri = $uri.$next_year.'/'.$next_month.'/';
$button_bar = new PHUIButtonBarView();
$left_icon = id(new PHUIIconView())
->setIconFont('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())
->setIconFont('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 getNextYearAndMonth() {
$month = $this->month;
$year = $this->year;
$next_year = $year;
$next_month = $month + 1;
if ($next_month == 13) {
$next_year = $year + 1;
$next_month = 1;
}
return array($next_year, $next_month);
}
private function getPrevYearAndMonth() {
$month = $this->month;
$year = $this->year;
$prev_year = $year;
$prev_month = $month - 1;
if ($prev_month == 0) {
$prev_year = $year - 1;
$prev_month = 12;
}
return array($prev_year, $prev_month);
}
/**
* 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() {
$user = $this->user;
$timezone = new DateTimeZone($user->getTimezoneIdentifier());
$month = $this->month;
$year = $this->year;
// Get the year and month numbers of the following month, so we can
// determine when this month ends.
list($next_year, $next_month) = $this->getNextYearAndMonth();
$end_date = new DateTime("{$next_year}-{$next_month}-01", $timezone);
$end_epoch = $end_date->format('U');
$days = array();
for ($day = 1; $day <= 31; $day++) {
$day_date = new DateTime("{$year}-{$month}-{$day}", $timezone);
$day_epoch = $day_date->format('U');
if ($day_epoch >= $end_epoch) {
break;
} else {
$days[] = $day_date;
}
}
return $days;
}
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Jan 19 2025, 12:07 (4 w, 4 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1124393
Default Alt Text
(27 KB)
Attached To
Mode
rP Phorge
Attached
Detach File
Event Timeline
Log In to Comment