diff --git a/src/__celerity_resource_map__.php b/src/__celerity_resource_map__.php index a35cb52434..2f6d320118 100644 --- a/src/__celerity_resource_map__.php +++ b/src/__celerity_resource_map__.php @@ -16,6 +16,15 @@ celerity_register_resource_map(array( ), 'disk' => '/rsrc/css/aphront/attached-file-view.css', ), + 'aphront-calendar-view-css' => + array( + 'uri' => '/res/7036c676/rsrc/css/aphront/calendar-view.css', + 'type' => 'css', + 'requires' => + array( + ), + 'disk' => '/rsrc/css/aphront/calendar-view.css', + ), 'aphront-contextbar-view-css' => array( 'uri' => '/res/3e2f3045/rsrc/css/aphront/context-bar.css', diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index bcf0fd1c2b..ea4a2a5e7b 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -15,6 +15,7 @@ phutil_register_library_map(array( 'AphrontApplicationConfiguration' => 'aphront/applicationconfiguration', 'AphrontAttachedFileView' => 'view/control/attachedfile', 'AphrontCSRFException' => 'aphront/exception/csrf', + 'AphrontCalendarMonthView' => 'applications/calendar/view/month', 'AphrontContextBarView' => 'view/layout/contextbar', 'AphrontController' => 'aphront/controller', 'AphrontCrumbsView' => 'view/layout/crumbs', @@ -301,6 +302,8 @@ phutil_register_library_map(array( 'ManiphestView' => 'applications/maniphest/view/base', 'Phabricator404Controller' => 'applications/base/controller/404', 'PhabricatorAuthController' => 'applications/auth/controller/base', + 'PhabricatorCalendarBrowseController' => 'applications/calendar/controller/browse', + 'PhabricatorCalendarController' => 'applications/calendar/controller/base', 'PhabricatorConduitAPIController' => 'applications/conduit/controller/api', 'PhabricatorConduitCertificateToken' => 'applications/conduit/storage/token', 'PhabricatorConduitConnectionLog' => 'applications/conduit/storage/connectionlog', @@ -664,6 +667,7 @@ phutil_register_library_map(array( 'AphrontAjaxResponse' => 'AphrontResponse', 'AphrontAttachedFileView' => 'AphrontView', 'AphrontCSRFException' => 'AphrontException', + 'AphrontCalendarMonthView' => 'AphrontView', 'AphrontContextBarView' => 'AphrontView', 'AphrontCrumbsView' => 'AphrontView', 'AphrontDefaultApplicationConfiguration' => 'AphrontApplicationConfiguration', @@ -873,6 +877,8 @@ phutil_register_library_map(array( 'ManiphestView' => 'AphrontView', 'Phabricator404Controller' => 'PhabricatorController', 'PhabricatorAuthController' => 'PhabricatorController', + 'PhabricatorCalendarBrowseController' => 'PhabricatorCalendarController', + 'PhabricatorCalendarController' => 'PhabricatorController', 'PhabricatorConduitAPIController' => 'PhabricatorConduitController', 'PhabricatorConduitCertificateToken' => 'PhabricatorConduitDAO', 'PhabricatorConduitConnectionLog' => 'PhabricatorConduitDAO', diff --git a/src/aphront/default/configuration/AphrontDefaultApplicationConfiguration.php b/src/aphront/default/configuration/AphrontDefaultApplicationConfiguration.php index 47c91ccd86..2209350a02 100644 --- a/src/aphront/default/configuration/AphrontDefaultApplicationConfiguration.php +++ b/src/aphront/default/configuration/AphrontDefaultApplicationConfiguration.php @@ -356,6 +356,10 @@ class AphrontDefaultApplicationConfiguration 'preview/$' => 'PhrictionDocumentPreviewController', 'diff/(?P\d+)/$' => 'PhrictionDiffController', ), + + '/calendar/' => array( + '$' => 'PhabricatorCalendarBrowseController', + ), ); } diff --git a/src/applications/calendar/controller/base/PhabricatorCalendarController.php b/src/applications/calendar/controller/base/PhabricatorCalendarController.php new file mode 100644 index 0000000000..9688769cb7 --- /dev/null +++ b/src/applications/calendar/controller/base/PhabricatorCalendarController.php @@ -0,0 +1,43 @@ +buildStandardPageView(); + + $page->setApplicationName('Calendar'); + $page->setBaseURI('/calendar/'); + $page->setTitle(idx($data, 'title')); + + // Unicode has a calendar character but it's in some distant code plane, + // use "keyboard" since it looks vaguely similar. + $page->setGlyph("\xE2\x8C\xA8"); + + $page->appendChild($view); + $page->setTabs( + array( + ), + idx($data, 'tab')); + + $response = new AphrontWebpageResponse(); + return $response->setContent($page->render()); + } + +} diff --git a/src/applications/calendar/controller/base/__init__.php b/src/applications/calendar/controller/base/__init__.php new file mode 100644 index 0000000000..9afe359857 --- /dev/null +++ b/src/applications/calendar/controller/base/__init__.php @@ -0,0 +1,15 @@ +getRequest(); + $user = $request->getUser(); + + $months = array(); + for ($ii = 1; $ii <= 12; $ii++) { + $month_view = new AphrontCalendarMonthView($ii, 2011); + $month_view->setUser($user); + $months[] = '
'; + $months[] = $month_view; + $months[] = '
'; + } + + return $this->buildStandardPageResponse( + $months, + array( + 'title' => 'Calendar', + )); + } +} diff --git a/src/applications/calendar/controller/browse/__init__.php b/src/applications/calendar/controller/browse/__init__.php new file mode 100644 index 0000000000..f6ed2aa4fa --- /dev/null +++ b/src/applications/calendar/controller/browse/__init__.php @@ -0,0 +1,13 @@ +user = $user; + return $this; + } + + public function __construct($month, $year) { + $this->month = $month; + $this->year = $year; + } + + public function render() { + if (empty($this->user)) { + throw new Exception("Call setUser() before render()!"); + } + + $days = $this->getDatesInMonth(); + + require_celerity_resource('aphront-calendar-view-css'); + + $first = reset($days); + $empty = $first->format('w'); + + $markup = array(); + + for ($ii = 0; $ii < $empty; $ii++) { + $markup[] = null; + } + + foreach ($days as $day) { + $markup[] = + '
'. + $day->format('j'). + '
'; + } + + $table = array(); + $rows = array_chunk($markup, 7); + foreach ($rows as $row) { + $table[] = ''; + while (count($row) < 7) { + $row[] = null; + } + foreach ($row as $cell) { + $table[] = ''.$cell.''; + } + $table[] = ''; + } + $table = + ''. + ''. + ''. + ''. + ''. + ''. + ''. + ''. + ''. + ''. + ''. + ''. + ''. + implode("\n", $table). + '
'.$first->format('F Y').'
SunMonTueWedThuFriSat
'; + + return $table; + } + + /** + * 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; + + // Find the year and month numbers of the following month, so we can + // determine when this month ends. + $next_year = $year; + $next_month = $month + 1; + if ($next_month == 13) { + $next_year = $year + 1; + $next_month = 1; + } + + $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; + } +} diff --git a/src/applications/calendar/view/month/__init__.php b/src/applications/calendar/view/month/__init__.php new file mode 100644 index 0000000000..9cc72509a9 --- /dev/null +++ b/src/applications/calendar/view/month/__init__.php @@ -0,0 +1,13 @@ +