[ Index ]

PHP Cross Reference of Phabricator

title

Body

[close]

/src/view/phui/calendar/ -> PHUICalendarMonthView.php (source)

   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")); // &nbsp;
  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  }


Generated: Sun Nov 30 09:20:46 2014 Cross-referenced by PHPXref 0.7.1