[ Index ] |
PHP Cross Reference of Phabricator |
[Summary view] [Print] [Text view]
1 <?php 2 3 final class PHUICalendarMonthView extends AphrontView { 4 5 private $day; 6 private $month; 7 private $year; 8 private $holidays = array(); 9 private $events = array(); 10 private $browseURI; 11 private $image; 12 13 public function setBrowseURI($browse_uri) { 14 $this->browseURI = $browse_uri; 15 return $this; 16 } 17 private function getBrowseURI() { 18 return $this->browseURI; 19 } 20 21 public function addEvent(AphrontCalendarEventView $event) { 22 $this->events[] = $event; 23 return $this; 24 } 25 26 public function setImage($uri) { 27 $this->image = $uri; 28 return $this; 29 } 30 31 public function setHolidays(array $holidays) { 32 assert_instances_of($holidays, 'PhabricatorCalendarHoliday'); 33 $this->holidays = mpull($holidays, null, 'getDay'); 34 return $this; 35 } 36 37 public function __construct($month, $year, $day = null) { 38 $this->day = $day; 39 $this->month = $month; 40 $this->year = $year; 41 } 42 43 public function render() { 44 if (empty($this->user)) { 45 throw new Exception('Call setUser() before render()!'); 46 } 47 48 $events = msort($this->events, 'getEpochStart'); 49 50 $days = $this->getDatesInMonth(); 51 52 require_celerity_resource('phui-calendar-month-css'); 53 54 $first = reset($days); 55 $empty = $first->format('w'); 56 57 $markup = array(); 58 59 $empty_box = phutil_tag( 60 'div', 61 array('class' => 'phui-calendar-day phui-calendar-empty'), 62 ''); 63 64 for ($ii = 0; $ii < $empty; $ii++) { 65 $markup[] = $empty_box; 66 } 67 68 $show_events = array(); 69 70 foreach ($days as $day) { 71 $day_number = $day->format('j'); 72 73 $holiday = idx($this->holidays, $day->format('Y-m-d')); 74 $class = 'phui-calendar-day'; 75 $weekday = $day->format('w'); 76 77 if ($day_number == $this->day) { 78 $class .= ' phui-calendar-today'; 79 } 80 81 if ($holiday || $weekday == 0 || $weekday == 6) { 82 $class .= ' phui-calendar-not-work-day'; 83 } 84 85 $day->setTime(0, 0, 0); 86 $epoch_start = $day->format('U'); 87 88 $day->modify('+1 day'); 89 $epoch_end = $day->format('U'); 90 91 if ($weekday == 0) { 92 $show_events = array(); 93 } else { 94 $show_events = array_fill_keys( 95 array_keys($show_events), 96 phutil_tag_div( 97 'phui-calendar-event phui-calendar-event-empty', 98 "\xC2\xA0")); // 99 } 100 101 $list_events = array(); 102 foreach ($events as $event) { 103 if ($event->getEpochStart() >= $epoch_end) { 104 // This list is sorted, so we can stop looking. 105 break; 106 } 107 if ($event->getEpochStart() < $epoch_end && 108 $event->getEpochEnd() > $epoch_start) { 109 $list_events[] = $event; 110 } 111 } 112 113 $list = new PHUICalendarListView(); 114 $list->setUser($this->user); 115 foreach ($list_events as $item) { 116 $list->addEvent($item); 117 } 118 119 $holiday_markup = null; 120 if ($holiday) { 121 $name = $holiday->getName(); 122 $holiday_markup = phutil_tag( 123 'div', 124 array( 125 'class' => 'phui-calendar-holiday', 126 'title' => $name, 127 ), 128 $name); 129 } 130 131 $markup[] = phutil_tag_div( 132 $class, 133 array( 134 phutil_tag_div('phui-calendar-date-number', $day_number), 135 $holiday_markup, 136 $list, 137 )); 138 } 139 140 $table = array(); 141 $rows = array_chunk($markup, 7); 142 foreach ($rows as $row) { 143 $cells = array(); 144 while (count($row) < 7) { 145 $row[] = $empty_box; 146 } 147 $j = 0; 148 foreach ($row as $cell) { 149 if ($j == 0) { 150 $cells[] = phutil_tag( 151 'td', 152 array( 153 'class' => 'phui-calendar-month-weekstart', 154 ), 155 $cell); 156 } else { 157 $cells[] = phutil_tag('td', array(), $cell); 158 } 159 $j++; 160 } 161 $table[] = phutil_tag('tr', array(), $cells); 162 } 163 164 $header = phutil_tag( 165 'tr', 166 array('class' => 'phui-calendar-day-of-week-header'), 167 array( 168 phutil_tag('th', array(), pht('Sun')), 169 phutil_tag('th', array(), pht('Mon')), 170 phutil_tag('th', array(), pht('Tue')), 171 phutil_tag('th', array(), pht('Wed')), 172 phutil_tag('th', array(), pht('Thu')), 173 phutil_tag('th', array(), pht('Fri')), 174 phutil_tag('th', array(), pht('Sat')), 175 )); 176 177 $table = phutil_tag( 178 'table', 179 array('class' => 'phui-calendar-view'), 180 array( 181 $header, 182 phutil_implode_html("\n", $table), 183 )); 184 185 $box = id(new PHUIObjectBoxView()) 186 ->setHeader($this->renderCalendarHeader($first)) 187 ->appendChild($table); 188 189 return $box; 190 } 191 192 private function renderCalendarHeader(DateTime $date) { 193 $button_bar = null; 194 195 // check for a browseURI, which means we need "fancy" prev / next UI 196 $uri = $this->getBrowseURI(); 197 if ($uri) { 198 $uri = new PhutilURI($uri); 199 list($prev_year, $prev_month) = $this->getPrevYearAndMonth(); 200 $query = array('year' => $prev_year, 'month' => $prev_month); 201 $prev_uri = (string) $uri->setQueryParams($query); 202 203 list($next_year, $next_month) = $this->getNextYearAndMonth(); 204 $query = array('year' => $next_year, 'month' => $next_month); 205 $next_uri = (string) $uri->setQueryParams($query); 206 207 $button_bar = new PHUIButtonBarView(); 208 209 $left_icon = id(new PHUIIconView()) 210 ->setIconFont('fa-chevron-left bluegrey'); 211 $left = id(new PHUIButtonView()) 212 ->setTag('a') 213 ->setColor(PHUIButtonView::GREY) 214 ->setHref($prev_uri) 215 ->setTitle(pht('Previous Month')) 216 ->setIcon($left_icon); 217 218 $right_icon = id(new PHUIIconView()) 219 ->setIconFont('fa-chevron-right bluegrey'); 220 $right = id(new PHUIButtonView()) 221 ->setTag('a') 222 ->setColor(PHUIButtonView::GREY) 223 ->setHref($next_uri) 224 ->setTitle(pht('Next Month')) 225 ->setIcon($right_icon); 226 227 $button_bar->addButton($left); 228 $button_bar->addButton($right); 229 230 } 231 232 $header = id(new PHUIHeaderView()) 233 ->setHeader($date->format('F Y')); 234 235 if ($button_bar) { 236 $header->setButtonBar($button_bar); 237 } 238 239 if ($this->image) { 240 $header->setImage($this->image); 241 } 242 243 return $header; 244 } 245 246 private function getNextYearAndMonth() { 247 $month = $this->month; 248 $year = $this->year; 249 250 $next_year = $year; 251 $next_month = $month + 1; 252 if ($next_month == 13) { 253 $next_year = $year + 1; 254 $next_month = 1; 255 } 256 257 return array($next_year, $next_month); 258 } 259 260 private function getPrevYearAndMonth() { 261 $month = $this->month; 262 $year = $this->year; 263 264 $prev_year = $year; 265 $prev_month = $month - 1; 266 if ($prev_month == 0) { 267 $prev_year = $year - 1; 268 $prev_month = 12; 269 } 270 271 return array($prev_year, $prev_month); 272 } 273 274 /** 275 * Return a DateTime object representing the first moment in each day in the 276 * month, according to the user's locale. 277 * 278 * @return list List of DateTimes, one for each day. 279 */ 280 private function getDatesInMonth() { 281 $user = $this->user; 282 283 $timezone = new DateTimeZone($user->getTimezoneIdentifier()); 284 285 $month = $this->month; 286 $year = $this->year; 287 288 // Get the year and month numbers of the following month, so we can 289 // determine when this month ends. 290 list($next_year, $next_month) = $this->getNextYearAndMonth(); 291 292 $end_date = new DateTime("{$next_year}-{$next_month}-01", $timezone); 293 $end_epoch = $end_date->format('U'); 294 295 $days = array(); 296 for ($day = 1; $day <= 31; $day++) { 297 $day_date = new DateTime("{$year}-{$month}-{$day}", $timezone); 298 $day_epoch = $day_date->format('U'); 299 if ($day_epoch >= $end_epoch) { 300 break; 301 } else { 302 $days[] = $day_date; 303 } 304 } 305 306 return $days; 307 } 308 309 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Sun Nov 30 09:20:46 2014 | Cross-referenced by PHPXref 0.7.1 |