summaryrefslogtreecommitdiffstats
path: root/vendor/gipfl/calendar
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/gipfl/calendar')
-rw-r--r--vendor/gipfl/calendar/composer.json32
-rw-r--r--vendor/gipfl/calendar/src/Calendar.php246
-rw-r--r--vendor/gipfl/calendar/src/Widget/CalendarMonth.php177
-rw-r--r--vendor/gipfl/calendar/src/Widget/CalendarMonthSummary.php278
4 files changed, 733 insertions, 0 deletions
diff --git a/vendor/gipfl/calendar/composer.json b/vendor/gipfl/calendar/composer.json
new file mode 100644
index 0000000..5e84ef6
--- /dev/null
+++ b/vendor/gipfl/calendar/composer.json
@@ -0,0 +1,32 @@
+{
+ "name": "gipfl/calendar",
+ "type": "library",
+ "description": "Calendar Utils",
+ "keywords": ["calendar"],
+ "homepage": "https://github.com/gipfl/calendar",
+ "authors": [
+ {
+ "name": "Thomas Gelf",
+ "email": "thomas@gelf.net"
+ }
+ ],
+ "config": {
+ "sort-packages": true
+ },
+ "require": {
+ "php": ">=5.4.0",
+ "gipfl/format": ">=0.3",
+ "gipfl/icingaweb2": ">=0.4.0",
+ "gipfl/translation": ">=0.1.1"
+ },
+ "autoload": {
+ "psr-4": {
+ "gipfl\\Calendar\\": "src"
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "gipfl\\Tests\\Calendar\\": "tests"
+ }
+ }
+}
diff --git a/vendor/gipfl/calendar/src/Calendar.php b/vendor/gipfl/calendar/src/Calendar.php
new file mode 100644
index 0000000..e81227c
--- /dev/null
+++ b/vendor/gipfl/calendar/src/Calendar.php
@@ -0,0 +1,246 @@
+<?php
+
+namespace gipfl\Calendar;
+
+use gipfl\Format\LocalTimeFormat;
+use InvalidArgumentException;
+
+class Calendar
+{
+ const FIRST_IS_MONDAY = 1;
+ const FIRST_IS_SUNDAY = 0;
+
+ protected $firstOfWeek;
+
+ protected $weekDays = [];
+
+ protected $shortWeekDays = [];
+
+ protected $timeFormat;
+
+ public function __construct($firstOfWeek = self::FIRST_IS_MONDAY)
+ {
+ $this->timeFormat = new LocalTimeFormat();
+ $this->setFirstOfWeek($firstOfWeek);
+ }
+
+ public function firstOfWeekIsMonday()
+ {
+ return $this->firstOfWeek === self::FIRST_IS_MONDAY;
+ }
+
+ public function firstOfWeekIsSunday()
+ {
+ return $this->firstOfWeek === self::FIRST_IS_SUNDAY;
+ }
+
+ public function setFirstOfWeek($firstOfWeek)
+ {
+ if ($firstOfWeek === self::FIRST_IS_SUNDAY || $firstOfWeek === self::FIRST_IS_MONDAY) {
+ if ($firstOfWeek !== $this->firstOfWeek) {
+ $this->firstOfWeek = $firstOfWeek;
+ $this->prepareWeekDays();
+ }
+
+ return $this;
+ } else {
+ throw new InvalidArgumentException(
+ "First day of week has to be either 0 or 1, got '$firstOfWeek'"
+ );
+ }
+ }
+
+ protected function prepareWeekDays()
+ {
+ if ($this->firstOfWeekIsSunday()) {
+ $start = '2019-02-03';
+ } else {
+ $start = '2019-02-04';
+ }
+
+ for ($i = 0; $i < 7; $i++) {
+ $day = strtotime("$start +{$i}days");
+ $this->weekDays[] = $this->timeFormat->getWeekdayName($day);
+ $this->shortWeekDays[] = $this->timeFormat->getShortWeekdayName($day);
+ }
+ }
+
+ public function listWeekDayNames()
+ {
+ return $this->weekDays;
+ }
+
+ public function listShortWeekDayNames()
+ {
+ return $this->shortWeekDays;
+ }
+
+ /**
+ * Either 'N' or 'w', depending on the first day of week
+ *
+ * @return string
+ */
+ protected function getDowFormat()
+ {
+ if ($this->firstOfWeekIsMonday()) {
+ // N -> 1-7 (Mo-Su)
+ return 'N';
+ } else {
+ // w -> 0-6 (Su-Sa)
+ return 'w';
+ }
+ }
+
+ /**
+ * @param $time
+ * @return int
+ */
+ protected function getWeekDay($time)
+ {
+ return (int) date($this->getDowFormat(), $time);
+ }
+
+ /**
+ * @param int $now
+ * @return array
+ */
+ public function getDaysForWeek($now)
+ {
+ $formatDow = $this->getDowFormat();
+ $today = date('Y-m-d', $now);
+ $day = $this->getFirstDayOfWeek($today);
+ $weekday = (int) date($formatDow, strtotime($day));
+ $week = [$weekday => $day];
+ for ($i = 1; $i < 7; $i++) {
+ $day = date('Y-m-d', strtotime("$day +1day"));
+ $weekday = (int) date($formatDow, strtotime($day));
+ $week[$weekday] = $day;
+ }
+
+ return $week;
+ }
+
+ /**
+ * @param int $now
+ * @return array
+ */
+ public function getWorkingDaysForWeek($now)
+ {
+ $formatDow = $this->getDowFormat();
+ $today = date('Y-m-d', $now);
+ $day = $this->getFirstDayOfWeek($today, self::FIRST_IS_MONDAY);
+ $weekday = (int) date($formatDow, strtotime($day));
+ $week = [$weekday => $day];
+ for ($i = 1; $i < 5; $i++) {
+ $day = date('Y-m-d', strtotime("$day +1day"));
+ $weekday = (int) date($formatDow, strtotime($day));
+ $week[$weekday] = $day;
+ }
+
+ return $week;
+ }
+
+ /**
+ * @param string $day
+ * @param int $firstOfWeek
+ * @return string
+ */
+ public function getFirstDayOfWeek($day, $firstOfWeek = null)
+ {
+ if ($firstOfWeek === null) {
+ $firstOfWeek = $this->firstOfWeek;
+ }
+ $dow = $this->getWeekDay(strtotime($day));
+ if ($dow > $firstOfWeek) {
+ $sub = $dow - $firstOfWeek;
+ return date('Y-m-d', strtotime("$day -{$sub}day"));
+ } else {
+ return $day;
+ }
+ }
+
+ /**
+ * @param string $day
+ * @param int $firstOfWeek
+ * @return string
+ */
+ protected function getLastDayOfWeek($day, $firstOfWeek = null)
+ {
+ if ($firstOfWeek === null) {
+ $firstOfWeek = $this->firstOfWeek;
+ }
+ $dow = $this->getWeekDay(strtotime($day));
+ $lastOfWeek = $firstOfWeek + 6;
+ if ($dow < $lastOfWeek) {
+ $add = $lastOfWeek - $dow;
+ return static::expressionToDate(static::incDay($day, $add));
+ } else {
+ return $day;
+ }
+ }
+
+ public function getWeekOfTheYear($day)
+ {
+ $time = strtotime($day);
+ // 0 = Sunday
+ if ($this->firstOfWeekIsSunday() && $this->getWeekDay($time) === 0) {
+ if (substr($time, 4, 6) === '-12-31') {
+ return (int) date('W', strtotime(static::decDay($day)));
+ } else {
+ return (int) date('W', strtotime(static::incDay($day)));
+ }
+ } else {
+ return (int) date('W', $time);
+ }
+ }
+
+ /**
+ * @param int $now
+ * @return array
+ */
+ public function getWeeksForMonth($now)
+ {
+ $first = date('Y-m-01', $now);
+ $last = date('Y-m-d', strtotime("$first +1month -1day"));
+
+ $formatDow = $this->getDowFormat();
+ $end = $this->getLastDayOfWeek($last);
+ $day = $this->getFirstDayOfWeek($first);
+ $formerWeekOfTheYear = 0;
+ $weeks = [];
+ while ($day <= $end) {
+ $weekOfTheYear = $this->getWeekOfTheYear($day);
+ if ($weekOfTheYear !== $formerWeekOfTheYear) {
+ $weeks[$weekOfTheYear] = [];
+ $week = & $weeks[$weekOfTheYear];
+ }
+
+ $weekday = (int) date($formatDow, strtotime($day));
+ $week[$weekday] = $day;
+ $day = date('Y-m-d', strtotime("$day +1day"));
+ $formerWeekOfTheYear = $weekOfTheYear;
+ }
+
+ return $weeks;
+ }
+
+ protected static function expressionToDate($expression)
+ {
+ return date('Y-m-d', strtotime($expression));
+ }
+
+ /**
+ * @param string $day
+ * @param int $increment days to add
+ * @return string
+ */
+ protected static function incDay($day, $increment = 1)
+ {
+ return sprintf('%s +%dday', $day, $increment);
+ }
+
+ protected static function decDay($day, $decrement = 1)
+ {
+ return sprintf('%s -%dday', $day, $decrement);
+ }
+}
diff --git a/vendor/gipfl/calendar/src/Widget/CalendarMonth.php b/vendor/gipfl/calendar/src/Widget/CalendarMonth.php
new file mode 100644
index 0000000..2fe1c5b
--- /dev/null
+++ b/vendor/gipfl/calendar/src/Widget/CalendarMonth.php
@@ -0,0 +1,177 @@
+<?php
+
+namespace gipfl\Calendar\Widget;
+
+use gipfl\Calendar\Calendar;
+use gipfl\Format\LocalTimeFormat;
+use gipfl\IcingaWeb2\Link;
+use gipfl\IcingaWeb2\Url;
+use gipfl\Translation\TranslationHelper;
+use ipl\Html\BaseHtmlElement;
+use ipl\Html\Html;
+use ipl\Html\HtmlElement;
+
+/**
+ * WARNING: API will change
+ */
+class CalendarMonth extends BaseHtmlElement
+{
+ use TranslationHelper;
+
+ protected $tag = 'div';
+
+ protected $defaultAttributes = [
+ 'id' => 'calendar-wrap'
+ ];
+
+ /** @var Calendar */
+ protected $calendar;
+
+ /** @var int */
+ protected $now;
+
+ /** @var Url */
+ protected $url;
+
+ /** @var HtmlElement */
+ protected $days = [];
+
+ protected $timeFormatter;
+
+ public function __construct(Calendar $calendar, Url $url, $now)
+ {
+ $this->now = $now;
+ $this->url = $url;
+ $this->calendar = $calendar;
+ $this->timeFormatter = new LocalTimeFormat();
+ }
+
+ protected function dayRow()
+ {
+ return Html::tag('ul', ['class' => 'days']);
+ }
+
+ /**
+ * @param $day
+ * @return HtmlElement
+ */
+ protected function getDay($day)
+ {
+ $this->ensureAssembled();
+ return $this->days[$day];
+ }
+
+ protected function hasDay($day)
+ {
+ $this->ensureAssembled();
+
+ return isset($this->days[$day]);
+ }
+
+ protected function createDay($day)
+ {
+ $title = (int) substr($day, -2);
+
+ if ($title === 1) {
+ $title = sprintf(
+ '%d %s',
+ $title,
+ $this->timeFormatter->getShortMonthName(strtotime($day))
+ );
+ }
+ $li = Html::tag(
+ 'li',
+ ['class' => 'day'],
+ Html::tag('div', ['class' => 'date'], $title)
+ );
+
+ $this->days[$day] = $li;
+
+ return $li;
+ }
+
+ public function addEvent($time, $text)
+ {
+ $day = date('Y-m-d', $time);
+ if (! $this->hasDay($day)) {
+ return $this;
+ }
+ // $this->getDay($day)->add(Html::tag('div', ['class' => 'event'], [
+ $this->getDay($day)->add(Html::tag('a', ['class' => 'event', 'href' => '#'], [
+ Html::tag('div', [
+ 'class' => 'event-time',
+ 'title' => date('Y-m-d H:i:s')
+ ], date('H:i', $time)),
+ Html::tag('div', ['class' => 'event-desc'], $text)
+ ]));
+
+ return $this;
+ }
+
+ protected function getFormerMonth()
+ {
+ $first = date('Y-m-01', $this->now);
+
+ return date('Y-m-d', strtotime("$first -1month"));
+ }
+
+ protected function getNextMonth()
+ {
+ $first = date('Y-m-01', $this->now);
+
+ return date('Y-m-d', strtotime("$first +1month"));
+ }
+
+ protected function getNavigationLinks()
+ {
+ return Html::tag('div', ['class' => 'calendar-navigation'], [
+ Link::create('<', $this->url->with('day', $this->getFormerMonth())),
+ Link::create('>', $this->url->with('day', $this->getNextMonth())),
+ ]);
+ }
+
+ protected function assemble()
+ {
+ $now = $this->now;
+ $today = date('Y-m-d', $now);
+
+ $this->add(
+ Html::tag('header', [
+ $this->getNavigationLinks(),
+ Html::tag('h1', date('F Y', $now))
+ ])
+ );
+
+ $calendar = Html::tag('div', ['class' => 'calendar']);
+ $calendar->add($this->weekdaysHeader());
+ $thisMonth = substr($today, 0, 7);
+
+ foreach ($this->calendar->getWeeksForMonth($now) as $cw => $week) {
+ $weekRow = $this->dayRow();
+ $weekRow->add(
+ Html::tag('li', [
+ 'class' => 'weekName'
+ ], Html::tag('span', sprintf($this->translate('Week %s'), $cw)))
+ );
+ foreach ($week as $day) {
+ $weekRow->add($this->createDay($day));
+ if (substr($day, 0, 7) !== $thisMonth) {
+ $this->getDay($day)->addAttributes(['class' => 'other-month']);
+ }
+ }
+ $calendar->add($weekRow);
+ }
+
+ $this->add($calendar);
+ }
+
+ protected function weekdaysHeader()
+ {
+ $ul = Html::tag('ul', ['class' => 'weekdays']);
+ foreach ($this->calendar->listWeekDayNames() as $weekday) {
+ $ul->add(Html::tag('li', $this->translate($weekday)));
+ }
+
+ return $ul;
+ }
+}
diff --git a/vendor/gipfl/calendar/src/Widget/CalendarMonthSummary.php b/vendor/gipfl/calendar/src/Widget/CalendarMonthSummary.php
new file mode 100644
index 0000000..950530f
--- /dev/null
+++ b/vendor/gipfl/calendar/src/Widget/CalendarMonthSummary.php
@@ -0,0 +1,278 @@
+<?php
+
+namespace gipfl\Calendar\Widget;
+
+use gipfl\Calendar\Calendar;
+use gipfl\Format\LocalTimeFormat;
+use gipfl\IcingaWeb2\Link;
+use gipfl\IcingaWeb2\Url;
+use gipfl\Translation\TranslationHelper;
+use ipl\Html\HtmlElement;
+use ipl\Html\Table;
+
+class CalendarMonthSummary extends Table
+{
+ use TranslationHelper;
+
+ protected $defaultAttributes = [
+ 'data-base-target' => '_next',
+ 'class' => 'calendar',
+ ];
+
+ protected $today;
+
+ protected $year;
+
+ protected $month;
+
+ protected $strMonth;
+
+ protected $strToday;
+
+ protected $days = [];
+
+ /** @var Calendar|null */
+ protected $calendar;
+
+ protected $showWeekNumbers = true;
+
+ protected $showOtherMonth = false;
+
+ protected $showGrayFuture = true;
+
+ protected $title;
+
+ protected $color = '255, 128, 0';
+
+ protected $forcedMax;
+
+ protected $timeFormat;
+
+ public function __construct($year, $month)
+ {
+ $this->year = $year;
+ $this->month = $month;
+ $this->strMonth = sprintf('%d-%02d', $year, $month);
+ $this->strToday = date('Y-m-d');
+ $this->timeFormat = new LocalTimeFormat();
+ }
+
+ public function setBaseColorRgb($red, $green, $blue)
+ {
+ $this->color = sprintf('%d, %d, %d', $red, $green, $blue);
+
+ return $this;
+ }
+
+ public function setCalendar(Calendar $calendar)
+ {
+ $this->calendar = $calendar;
+
+ return $this;
+ }
+
+ public function getCalendar()
+ {
+ if ($this->calendar === null) {
+ $this->calendar = new Calendar();
+ }
+
+ return $this->calendar;
+ }
+
+ public function addEvents($events, Url $baseUrl)
+ {
+ if (empty($events)) {
+ return $this;
+ }
+
+ if ($this->forcedMax === null) {
+ $max = max($events);
+ } else {
+ $max = $this->forcedMax;
+ }
+
+ if ($max === 0 || $max === null) {
+ return $this;
+ }
+
+ foreach ($events as $day => $count) {
+ if (! $this->hasDay($day)) {
+ continue;
+ }
+
+ if (! $this->showOtherMonth && $this->dayIsInThisMonth($day)) {
+ continue;
+ }
+
+ $text = (int) substr($day, -2);
+
+ $link = Link::create($text, $baseUrl->with('day', $day));
+ $alpha = $count / $max;
+
+ if ($alpha > 0.4) {
+ $link->addAttributes(['style' => 'color: white;']);
+ }
+ $link->addAttributes([
+ 'title' => sprintf('%d events', $count),
+ 'style' => sprintf(
+ 'background-color: rgba(%s, %.2F);',
+ $this->color,
+ $alpha
+ )
+ ]);
+
+ $this->getDay($day)->setContent($link);
+ }
+
+ return $this;
+ }
+
+ public function markNow($now = null)
+ {
+ if ($now === null) {
+ $now = time();
+ }
+ $this->today = date('Y-m-d', $now);
+
+ return $this;
+ }
+
+ public function setTitle($title)
+ {
+ $this->title = $title;
+
+ return $this;
+ }
+
+ protected function getTitle()
+ {
+ if ($this->title === null) {
+ $this->title = $this->getMonthName() . ' ' . $this->year;
+ }
+
+ return $this->title;
+ }
+
+ public function forceMax($max)
+ {
+ $this->forcedMax = $max;
+
+ return $this;
+ }
+
+ protected function getMonthAsTimestamp()
+ {
+ return strtotime($this->strMonth . '-01');
+ }
+
+ protected function assemble()
+ {
+ $this->setCaption($this->getTitle());
+ $this->getHeader()->add($this->createWeekdayHeader());
+ $calendar = $this->getCalendar();
+ foreach ($calendar->getWeeksForMonth($this->getMonthAsTimestamp()) as $cw => $week) {
+ $weekRow = $this->weekRow($cw);
+ foreach ($week as $wDay => $day) {
+ $dayElement = $this->createDay($day);
+ $otherMonth = $this->dayIsInThisMonth($day);
+ if ($wDay < 1 || $wDay > 5) {
+ $dayElement->addAttributes(['class' => 'weekend']);
+ }
+ $weekRow->add($dayElement);
+ }
+ $this->add($weekRow);
+ }
+ }
+
+ /**
+ * @param $day
+ * @return HtmlElement
+ */
+ protected function getDay($day)
+ {
+ $this->ensureAssembled();
+
+ return $this->days[$day];
+ }
+
+ protected function hasDay($day)
+ {
+ $this->ensureAssembled();
+
+ return isset($this->days[$day]);
+ }
+
+ protected function dayIsInThisMonth($day)
+ {
+ return substr($day, 0, 7) !== $this->strMonth;
+ }
+
+ protected function createDay($day)
+ {
+ $otherMonth = $this->dayIsInThisMonth($day);
+ $title = (int) substr($day, -2);
+ if ($otherMonth && ! $this->showOtherMonth) {
+ $title = '';
+ }
+ $td = Table::td($title);
+ $this->days[$day] = $td;
+
+ if ($otherMonth) {
+ $td->addAttributes(['class' => 'other-month']);
+ } elseif ($this->showGrayFuture && $day > $this->strToday) {
+ $td->addAttributes(['class' => 'future-day']);
+ }
+
+ // TODO: today VS strToday?!
+ if ($day === $this->today) {
+ $td->addAttributes(['class' => 'today']);
+ }
+
+ return $td;
+ }
+
+ protected function weekRow($cw)
+ {
+ $row = Table::tr();
+
+ if ($this->showWeekNumbers) {
+ $row->add(Table::th(sprintf('%02d', $cw), [
+ 'title' => sprintf($this->translate('Calendar Week %d'), $cw)
+ ]));
+ }
+
+ return $row;
+ }
+
+ protected function getMonthName()
+ {
+ return $this->timeFormat->getMonthName($this->getMonthAsTimestamp());
+ }
+
+ protected function createWeekdayHeader()
+ {
+ $calendar = $this->getCalendar();
+ $cols = $calendar->listShortWeekDayNames();
+ $row = Table::tr();
+ if ($this->showWeekNumbers) {
+ $row->add(Table::th(''));
+ }
+ if ($calendar->firstOfWeekIsMonday()) {
+ $weekend = [6 => true, 7 => true];
+ } else {
+ $weekend = [1 => true, 7 => true];
+ }
+ $wDay = 0;
+ foreach ($cols as $day) {
+ $wDay++;
+ $col = Table::th($day);
+ if (isset($weekend[$wDay])) {
+ $col->addAttributes(['class' => 'weekend']);
+ }
+ $row->add($col);
+ }
+
+ return $row;
+ }
+}