diff --git a/README.md b/README.md index efb8f21..02bf716 100755 --- a/README.md +++ b/README.md @@ -23,25 +23,39 @@ Please make sure you have added the required classes. You can apply styles in one of three ways: 1) Using $calendar->stylesheet() after you have initialised a calendar; + ```php - $calendar = new Calendar(); + + $calendar = new Calendar; $calendar->stylesheet(); + ``` 2) Using the calendar.css (or calendar.min.css) from the css directory; + ```html + + ``` 3) Create your own stylesheet and add it to the head of your HTML document. -#### Draw a calendar +#### Draw a 'Month View' calendar -In its simplest form, use the following to create a calendar +In its simplest form, use the following to create a calendar for current month. This will use all defaults (English, Week starting on Sunday, including stylesheet, printing to the page). + +```php + + (new Calendar)->display(); + +``` + +Or, you can break it down with full customisability: ```php # create the calendar object - $calendar = new Calendar(); + $calendar = new Calendar; # change the weekly start date to "Monday" $calendar->useMondayStartingDate(); @@ -54,6 +68,11 @@ In its simplest form, use the following to create a calendar # to revert to initials, use: $calendar->useInitialDayNames(); + + # add your own table class(es) + $calendar->addTableClasses('class-1 class-2 class-3'); + # or using an array of classes. + $calendar->addTableClasses(['class-1', 'class-2', 'class-3']); # (optional) - if you want to hide certain weekdays from the calendar, for example a calendar without weekends, you can use the following methods: $calendar->hideSaturdays() # This will hide Saturdays @@ -69,8 +88,8 @@ In its simplest form, use the following to create a calendar # if needed, add event $calendar->addEvent( - '2017-01-14', # start date in Y-m-d format - '2017-01-14', # end date in Y-m-d format + '2022-01-14', # start date in either Y-m-d or Y-m-d H:i if you want to add a time. + '2022-01-14', # end date in either Y-m-d or Y-m-d H:i if you want to add a time. 'My Birthday', # event name text true, # should the date be masked - boolean default true ['myclass', 'abc'] # (optional) additional classes in either string or array format to be included on the event days @@ -81,16 +100,16 @@ In its simplest form, use the following to create a calendar $events = array(); $events[] = array( - 'start' => '2017-01-14', - 'end' => '2017-01-14', + 'start' => '2022-01-14', + 'end' => '2022-01-14', 'summary' => 'My Birthday', 'mask' => true, 'classes' => ['myclass', 'abc'] ); $events[] = array( - 'start' => '2017-12-25', - 'end' => '2017-12-25', + 'start' => '2022-12-25', + 'end' => '2022-12-25', 'summary' => 'Christmas', 'mask' => true ); @@ -116,17 +135,66 @@ In its simplest form, use the following to create a calendar echo $calendar->draw(date('Y-m-d'), 'yellow'); # print a yellow calendar echo $calendar->draw(date('Y-m-d'), 'green'); # print a green calendar echo $calendar->draw(date('Y-m-d'), 'grey'); # print a grey calendar - echo $calendar->draw(date('Y-m-d'), 'blue'); # print a blue calendar + echo $calendar->draw(date('Y-m-d'), 'blue'); # print a blue calendar + + # you can also call ->display(), which handles the echo'ing and adding the stylesheet. + echo $calendar->display(date('Y-m-d')); # draw this months calendar + +``` +#### Draw a 'Week View' calendar + +Instead of a 'month view' calendar, you can now render as a 'week view'. To do this, simply use ->useWeekView(). Remember, when adding events to a week-view calendar, you need to include the time too (see events above). + +```php + + $events = array(); + + $events[] = array( + 'start' => '2022-01-14 14:40', + 'end' => '2022-01-14 15:10', + 'summary' => 'My Birthday', + 'mask' => true, + 'classes' => ['myclass', 'abc'] + ); + + $events[] = array( + 'start' => '2022-11-04 14:00', + 'end' => '2022-11-04 18:30', + 'summary' => 'Event 1', + 'mask' => true + ); + $events[] = array( + 'start' => '2022-11-04 14:00', + 'end' => '2022-11-04 18:30', + 'summary' => 'Event 2', + 'mask' => true + ); + + $calendar = new Calendar; + + $calendar->addEvents($events)->setTimeFormat('00:00', '00:00', 10)->useWeekView()->display(date('Y-m-d'), 'green'); + +``` + +You can change the start/end times of the day, along with the time interval by using the ->setTimeFormat method: + +```php + + $calendar->setTimeFormat('00:00', '00:00', 10)->useWeekView()->display(date('Y-m-d'), 'green'); + # This will print a week view calendar with 10 minute slots from midnight to midnight - ie. 00:00, 00:10, 00:20 and so on. + ``` #### Monday Start Date You can now change the weekly start date from a **Sunday** to a **Monday**. To activate this, simple use the **useMondayStartingDate()** method before you 'draw'. + ```php - $calendar = new Calendar(); + $calendar = new Calendar; $calendar->useMondayStartingDate(); - $calendar->draw(date('Y-m-d'), 'green'); + $calendar->display(date('Y-m-d'), 'green'); + ``` #### Translated Calendars @@ -182,6 +250,7 @@ We now ship with both **English** and **Spanish** translations, with more coming 'november' => 'Noviembre', 'december' => 'Diciembre' ]); + ```` If you want to help with translations, use the code in the **useSpanish()** method as a guide, and open a pull-request. diff --git a/html/css/calendar.css b/html/css/calendar.css index c50fe89..0cb1636 100755 --- a/html/css/calendar.css +++ b/html/css/calendar.css @@ -82,4 +82,35 @@ .calendar tbody tr td.mask, .calendar tbody tr td.mask-end { background: #C23B22; +} + +.calendar .cal-weekview-time { + border: rgba(0,0,0.25); +} + +.calendar .cal-weekview-time { + padding: 4px 2px 2px 4px; +} + +.calendar .cal-weekview-time>div { + background: rgba(0, 0, 0, 0.03); + padding: 10px; + min-height: 50px; +} + +.calendar .cal-weekview-event.mask-start, +.calendar .cal-weekview-event.mask, +.calendar .cal-weekview-event.mask-end { + background: #C23B22; + margin-bottom: 3px; + padding: 5px; +} + +.calendar .cal-weekview-time-th { + background: rgba(0, 0, 0, .1); +} + +.calendar .cal-weekview-time-th>div { + padding: 10px; + min-height: 50px; } \ No newline at end of file diff --git a/html/css/calendar.min.css b/html/css/calendar.min.css index aa4b5d0..c69a26d 100644 --- a/html/css/calendar.min.css +++ b/html/css/calendar.min.css @@ -1 +1 @@ -.calendar{background:#2ca8c2;color:#fff;width:100%;font-family:Oxygen;table-layout:fixed}.calendar.purple{background:#913ccd}.calendar.pink{background:#f15f74}.calendar.orange{background:#f76d3c}.calendar.yellow{background:#f7d842}.calendar.green{background:#98cb4a}.calendar.grey{background:#839098}.calendar.blue{background:#5481e6}.calendar-title th{font-size:22px;font-weight:700;padding:20px;text-align:center;text-transform:uppercase;background:rgba(0,0,0,.05)}.calendar-header th{padding:10px;text-align:center;background:rgba(0,0,0,.1)}.calendar tbody tr td{text-align:center;vertical-align:top;width:14.28%}.calendar tbody tr td.pad{background:rgba(255,255,255,.1)}.calendar tbody tr td.day div:first-child{padding:4px;line-height:17px;height:25px}.calendar tbody tr td.day div:last-child{font-size:10px;padding:4px;min-height:25px}.calendar tbody tr td.today{background:rgba(0,0,0,.25)}.calendar tbody tr td.mask,.calendar tbody tr td.mask-end,.calendar tbody tr td.mask-start{background:#c23b22} \ No newline at end of file +.calendar{background:#2ca8c2;color:#fff;width:100%;font-family:Oxygen;table-layout:fixed}.calendar.purple{background:#913ccd}.calendar.pink{background:#f15f74}.calendar.orange{background:#f76d3c}.calendar.yellow{background:#f7d842}.calendar.green{background:#98cb4a}.calendar.grey{background:#839098}.calendar.blue{background:#5481e6}.calendar-title th{font-size:22px;font-weight:700;padding:20px;text-align:center;text-transform:uppercase;background:rgba(0,0,0,.05)}.calendar-header th{padding:10px;text-align:center;background:rgba(0,0,0,.1)}.calendar tbody tr td{text-align:center;vertical-align:top;width:14.28%}.calendar tbody tr td.pad{background:rgba(255,255,255,.1)}.calendar tbody tr td.day div:first-child{padding:4px;line-height:17px;height:25px}.calendar tbody tr td.day div:last-child{font-size:10px;padding:4px;min-height:25px}.calendar tbody tr td.today{background:rgba(0,0,0,.25)}.calendar tbody tr td.mask,.calendar tbody tr td.mask-end,.calendar tbody tr td.mask-start{background:#c23b22}.calendar .cal-weekview-time{border:rgba(0,0,.25)}.calendar .cal-weekview-time{padding:4px 2px 2px 4px}.calendar .cal-weekview-time>div{background:rgba(0,0,0,.03);padding:10px;min-height:50px}.calendar .cal-weekview-event.mask,.calendar .cal-weekview-event.mask-end,.calendar .cal-weekview-event.mask-start{background:#c23b22;margin-bottom:3px;padding:5px}.calendar .cal-weekview-time-th{background:rgba(0,0,0,.1)}.calendar .cal-weekview-time-th>div{padding:10px;min-height:50px} \ No newline at end of file diff --git a/src/phpCalendar/Calendar.php b/src/phpCalendar/Calendar.php index 3c47de2..19c6541 100755 --- a/src/phpCalendar/Calendar.php +++ b/src/phpCalendar/Calendar.php @@ -16,6 +16,37 @@ */ class Calendar { + /** + * Calendar Type + * + * @var string + */ + private $type = 'month'; + + /** + * Time Interval used in the week view. + * Default is set to 30 minutes. + * + * @var integer + */ + private $time_interval = 30; + + /** + * The Week View Starting Time. + * Leave at 00:00 for a full 24-hour calendar. + * + * @var string + */ + private $start_time = '00:00'; + + /** + * The Week View end time. + * Leave at 00:00 for a full 24-hour calendar. + * + * @var string + */ + private $end_time = '00:00'; + /** * The Day Format. * @@ -93,6 +124,13 @@ class Calendar 'december' => 'December' ]; + /** + * Table classes that should be injected into the table header. + * + * @var array + */ + private $table_classes = []; + /** * Hide all 'sundays' from the calendar view. * @@ -163,6 +201,11 @@ public function setDays($days) return $this; } + /** + * Toggles the calendar locale to Spanish. + * + * @return Calendar + */ public function useSpanish() { $this->setDays([ @@ -210,6 +253,8 @@ public function useSpanish() 'november' => 'Noviembre', 'december' => 'Diciembre' ]); + + return $this; } /** @@ -228,6 +273,11 @@ public function setMonths($months) return $this; } + /** + * Hide Sundays + * + * @return Calendar + */ public function hideSundays() { $this->hide_sundays = true; @@ -235,6 +285,11 @@ public function hideSundays() return $this; } + /** + * Hide Mondays + * + * @return Calendar + */ public function hideMondays() { $this->hide_mondays = true; @@ -242,6 +297,11 @@ public function hideMondays() return $this; } + /** + * Hide Tuesdays + * + * @return Calendar + */ public function hideTuesdays() { $this->hide_tuesdays = true; @@ -249,6 +309,11 @@ public function hideTuesdays() return $this; } + /** + * Hide Wednesdays + * + * @return Calendar + */ public function hideWednesdays() { $this->hide_wednesdays = true; @@ -256,6 +321,11 @@ public function hideWednesdays() return $this; } + /** + * Hide Thursdays + * + * @return Calendar + */ public function hideThursdays() { $this->hide_thursdays = true; @@ -263,6 +333,11 @@ public function hideThursdays() return $this; } + /** + * Hide Fridays + * + * @return Calendar + */ public function hideFridays() { $this->hide_fridays = true; @@ -270,6 +345,11 @@ public function hideFridays() return $this; } + /** + * Hide Saturdays + * + * @return Calendar + */ public function hideSaturdays() { $this->hide_saturdays = true; @@ -334,7 +414,7 @@ public function useMondayStartingDate() */ public function stylesheet($print = true) { - $styles = ''; + $styles = ''; if ($print) { echo $styles; @@ -364,9 +444,17 @@ public function addEvent($start, $end, $summary = false, $mask = false, $classes { $event = new stdClass(); - $event->start = DateTime::createFromFormat('Y-m-d', $start); - - $event->end = DateTime::createFromFormat('Y-m-d', $end); + if (strpos($start, ' ') !== false) { + $event->start = DateTime::createFromFormat('Y-m-d H:i', $start); + } else { + $event->start = DateTime::createFromFormat('Y-m-d', $start); + } + + if (strpos($end, ' ') !== false) { + $event->end = DateTime::createFromFormat('Y-m-d H:i', $end); + } else { + $event->end = DateTime::createFromFormat('Y-m-d', $end); + } $event->mask = $mask ? true : false; @@ -426,6 +514,52 @@ public function clearEvents() return $this; } + /** + * Use Month View. + * + * @return Calendar + */ + public function useMonthView() + { + $this->type = 'month'; + + return $this; + } + + /** + * Use Week View. + * + * @return Calendar + */ + public function useWeekView() + { + $this->type = 'week'; + + return $this; + } + + /** + * Add any custom table classes that should be injected into the calender table header. + * + * This can be a space separated list, or an array of classes. + * + * @param mixed $classes + * + * @return Calendar + */ + public function addTableClasses($classes) + { + if (!is_array($classes)) { + $classes = explode(' ', $classes); + } + + foreach ($classes as $class) { + $this->table_classes[] = $class; + } + + return $this; + } + /** * Returns an array of days to loop over. * @@ -465,13 +599,14 @@ private function findEvents(DateTime $date) } /** - * Draw the calendar and echo out. - * @param string $date The date of this calendar. - * @param string $format The format of the preceding date. - * - * @return string The calendar + * Returns the calendar as a month view. + * + * @param boolean $date + * @param boolean $color + * + * @return string */ - public function draw($date = false, $color = false) + public function asMonthView($date = false, $color = false) { $calendar = ''; @@ -498,16 +633,16 @@ public function draw($date = false, $color = false) $total_days_in_month = (int) $date->format('t'); - $color = $color ? : ''; - - $calendar .= ''; - + $color = $color ?: ''; + + $calendar .= '
'; + $calendar .= ''; $calendar .= ''; - + $calendar .= ''; @@ -517,18 +652,18 @@ public function draw($date = false, $color = false) $calendar .= ''; foreach ($this->getDays() as $index => $day) { - - $calendar .= ''; + $calendar .= ''; } $calendar .= ''; - + $calendar .= ''; $calendar .= ''; - $calendar .= ''; + $week = 1; + $calendar .= ''; // account for a monday start, if set. $weekday = !$this->starting_day ? (($date->format('w') == 0) ? 6 : $date->format('w') - 1) : $date->format('w'); @@ -556,11 +691,13 @@ public function draw($date = false, $color = false) if ($event->start->format('Y-m-d') == $running_day->format('Y-m-d')) { $class .= $event->mask ? ' mask-start' : ''; $class .= ($event->classes) ? ' ' . $event->classes : ''; - $event_summary .= ($event->summary) ? : ''; + $event_summary .= ($event->summary) ?: ''; # is the current day in between the start and end of the event - } elseif ($running_day->getTimestamp() > $event->start->getTimestamp() - && $running_day->getTimestamp() < $event->end->getTimestamp()) { + } elseif ( + $running_day->getTimestamp() > $event->start->getTimestamp() + && $running_day->getTimestamp() < $event->end->getTimestamp() + ) { $class .= $event->mask ? ' mask' : ''; # is the current day the start of the event @@ -572,18 +709,18 @@ public function draw($date = false, $color = false) $today_class = ($running_day->format('Y-m-d') == $today->format('Y-m-d')) ? ' today' : ''; - $calendar .= ''; @@ -594,7 +731,8 @@ public function draw($date = false, $color = false) # start a new calendar row if there are still days left in the month if (($running_day_count + 1) <= $total_days_in_month) { - $calendar .= ''; + $week++; + $calendar .= ''; } # reset padding because its a new calendar row @@ -609,7 +747,7 @@ public function draw($date = false, $color = false) if ($this->starting_day == 6) { $padding_at_end_of_month = 7 - $running_day->format('w'); } else { - $padding_at_end_of_month = ($running_day->format('w') == 0) ? 1 : 7 - ($running_day->format('w')-1); + $padding_at_end_of_month = ($running_day->format('w') == 0) ? 1 : 7 - ($running_day->format('w') - 1); } # padding at the end of the month @@ -619,7 +757,7 @@ public function draw($date = false, $color = false) if ($offset == 7) { $offset = 0; } - + $calendar .= ''; } } @@ -632,4 +770,207 @@ public function draw($date = false, $color = false) return $calendar; } + + /** + * Sets the time formats when overriding the default week view calendar start/end time and intervals. + * + * @param string $start_time + * @param string $end_time + * @param integer $minutes + * + * @return void + */ + public function setTimeFormat($start_time = '00:00', $end_time = '00:00', $minutes = 30) + { + $this->start_time = $start_time; + $this->end_time = $end_time; + $this->time_interval = $minutes; + + return $this; + } + + /** + * Get an array of time slots. + * + * @return array + */ + public function getTimes() + { + $start_time = DateTime::createFromFormat('H:i', $this->start_time); + $end_time = DateTime::createFromFormat('H:i', $this->end_time); + if ($start_time == $end_time) { + $end_time->modify('+1 day'); + } + + $times = []; + while ($start_time->format('Ymd H:i') <= $end_time->format('Ymd H:i')) { + if (!in_array($start_time->format('H:i'), $times)) { + $times[] = $start_time->format('H:i'); + } + $start_time->modify('+' . $this->time_interval . ' minutes'); + } + + return $times; + } + + /** + * Returns the calendar output as a week view. + * + * @param boolean $date + * @param boolean $color + * + * @return string + */ + public function asWeekView($date = false, $color = false) + { + $calendar = ''; + + $colspan = 7; + + $days = array_keys($this->days); + + foreach ($days as $day) { + if ($this->{'hide_' . $day . 's'}) { + $colspan--; + $calendar .= ''; + } + } + + if ($date) { + $date = DateTime::createFromFormat('Y-m-d', $date); + } else { + $date = new DateTime(); + } + + if ($this->starting_day == 6) { + $date->modify('last sunday'); + } elseif ($this->starting_day == 0) { + $date->modify('last monday'); + } + + $dates = []; + + do { + $dates[] = clone $date; + $date->modify('+1 Day'); + } while (count($dates) < 7); + + $today = new DateTime(); + + $color = $color ?: ''; + + $calendar .= '
'; - + $calendar .= $this->months[strtolower($date->format('F'))] . ' ' . $date->format('Y'); $calendar .= '
' . ($this->day_format == 'full' ? $day['full'] : $day['initials']) . '' . ($this->day_format == 'full' ? $day['full'] : $day['initials']) . '
'; + $calendar .= ''; + + $calendar .= '
'; - $calendar .= '
'; - $calendar .= $running_day->format('j'); - + $calendar .= '
'; - $calendar .= '
'; - + $calendar .= '
'; + $calendar .= $event_summary; - + $calendar .= '
'; $calendar .= '
'; + + $calendar .= ''; + + $calendar .= ''; + + $calendar .= ''; + + $days = $this->getDays(); + foreach ($dates as $date) { + $calendar .= ''; + } + + $calendar .= ''; + + $calendar .= ''; + + $calendar .= ''; + + foreach ($this->getTimes() as $time) { + $calendar .= ''; + + $calendar .= ''; + + foreach ($dates as $date ){ + + $datetime = $date->setTime(substr($time, 0, 2), substr($time, 3, 2)); + + $events = $this->findEvents($datetime); + + $class = ''; + + $event_summary = ''; + + $today_class = ($date->format('Y-m-d H') == $today->format('Y-m-d H')) ? ' today' : ''; + + $calendar .= ''; + } + echo ''; + } + + $calendar .= ''; + + $calendar .= '
'; + $calendar .= '
' . $days[strtolower($date->format('l'))]['full'] . '
'; + $calendar .= '
' . $date->format('j') . '
'; + $calendar .= '
' . $this->months[strtolower($date->format('F'))] . '
'; + $calendar .= '
' . $time . '
'; + + $calendar .= '
'; + + if ($events) { + foreach ($events as $index => $event) { + # is the current day the start of the event + if ($event->start->format('Y-m-d') == $date->format('Y-m-d')) { + $class .= $event->mask ? ' mask-start' : ''; + $class .= ($event->classes) ? ' ' . $event->classes : ''; + $event_summary = ($event->summary) ?: ''; + + # is the current day in between the start and end of the event + } elseif ( + $date->getTimestamp() > $event->start->getTimestamp() + && $date->getTimestamp() < $event->end->getTimestamp() + ) { + $class .= $event->mask ? ' mask' : ''; + + # is the current day the start of the event + } elseif ($date->format('Y-m-d') == $event->end->format('Y-m-d')) { + $class .= $event->mask ? ' mask-end' : ''; + } + + $calendar .= '
'; + $calendar .= $event_summary; + $calendar .= '
'; + + } + } + + $calendar .= '
'; + + $calendar .= '
'; + + return $calendar; + } + + /** + * Draw the calendar and return HTML output. + * @param string $date The date of this calendar. + * @param string $format The format of the preceding date. + * + * @return string The calendar + */ + public function draw($date = false, $color = false) + { + if ($this->type == 'week') { + return $this->asWeekView($date, $color); + } else{ + return $this->asMonthView($date, $color); + } + } + + /** + * Shortcut helper to print the calendar output. + * + * @param boolean $date + * @param boolean $color + * + * @return void + */ + public function display($date = false, $color = false) + { + echo $this->stylesheet(); + echo $this->draw($date, $color); + } }