Files
thetempusproject/app/plugins/calendar/controllers/calendar.php
2024-08-04 21:15:59 -04:00

594 lines
26 KiB
PHP

<?php
/**
* app/plugins/calendar/controllers/calendar.php
*
* This is the calendar controller.
*
* @package TP Calendar
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Controllers;
use TheTempusProject\Bedrock\Functions\Check;
use TheTempusProject\Bedrock\Functions\Input;
use TheTempusProject\Bedrock\Functions\Session;
use TheTempusProject\Bedrock\Functions\Date;
use TheTempusProject\Classes\Controller;
use TheTempusProject\Houdini\Classes\Forms as HoudiniForms;
use TheTempusProject\Classes\Forms;
use TheTempusProject\Houdini\Classes\Issues;
use TheTempusProject\Houdini\Classes\Views;
use TheTempusProject\Houdini\Classes\Template;
use TheTempusProject\Houdini\Classes\Components;
use TheTempusProject\Hermes\Functions\Redirect;
use TheTempusProject\TheTempusProject as App;
use TheTempusProject\Models\Events;
use TheTempusProject\Models\Calendars;
use TheTempusProject\Houdini\Classes\Navigation;
class Calendar extends Controller {
protected static $events;
protected static $calendars;
protected static $defaultView;
protected static $defaultCalendar;
protected static $selectedDate;
public function __construct() {
if ( !App::$isLoggedIn ) {
Session::flash( 'notice', 'You must be logged in to create or manage calendars.' );
return Redirect::home();
}
parent::__construct();
self::$title = 'Calendar - {SITENAME}';
self::$pageDescription = 'The {SITENAME} calendar is where you can find various features for creating and managing events and schedules.';
self::$events = new Events;
self::$calendars = new Calendars;
$prefs = App::$activePrefs;
if ( ! empty( $prefs['calendarPreference'] ) ) {
$view = $prefs['calendarPreference'];
} else {
Session::flash( 'info', 'You can select a default view for this page in your user settings in the top right.' );
$view = 'byMonth';
}
self::$defaultView = $view;
self::$selectedDate = intval( strtotime( Date::determineDateInput() ) );
Template::setTemplate( 'calendar' );
// Date Dropdown
$dateDropdownView = Views::simpleView('calendar.nav.dateDropdown', Date::getDateBreakdown( self::$selectedDate ) );
Components::set( 'dateDropdown', $dateDropdownView );
// Calendar Top Tabs
$calendarTabs = Views::simpleView('calendar.nav.topTabs');
$tabsView = Navigation::activePageSelect( $calendarTabs, Input::get( 'url' ), false, true );
// must be done after top-nav gets selected
$calendarDropdown = Views::simpleView('calendar.nav.calendarDropdown', self::$calendars->simpleObjectByUser() );
$calendarDropdownView = Navigation::activePageSelect( $calendarDropdown, Input::get( 'url' ), false, true ); // add notebookID as second param
Components::set( 'calendarDropdown', $calendarDropdownView);
// must be done after dropdown gets added
Components::set( 'CalendarNav', Template::parse( $calendarTabs ) );
}
public function index() {
if ( method_exists( $this, self::$defaultView ) ) {
Redirect::to( 'calendar/'.self::$defaultView.'/' );
} else {
Redirect::to( 'calendar/byMonth/' );
}
}
/**
* Events
*/
public function event( $id = null ) {
$event = $this->findEventOrFail( $id );
Views::view( 'calendar.events.view', $event );
}
public function createEvent() {
// get the url calendar input
$newCalendar = Input::get('calendar_id') ? Input::get('calendar_id') : '';// for loading the form
$calendarSelect = HoudiniForms::getFormFieldHtml( 'calendar_id', 'Calendar', 'select', $newCalendar, self::$calendars->simpleByUser() );
Components::set( 'calendarSelect', $calendarSelect );
$repeatSelect = HoudiniForms::getFormFieldHtml( 'repeats', 'Frequency', 'select', 'none', self::$events->repeatOptions );
Components::set( 'repeatSelect', $repeatSelect );
$dateSelect = Views::simpleView( 'calendar.dateSelect', $this->getEventBreakdown( self::$selectedDate ) );
Components::set( 'dateSelect', $dateSelect );
if ( ! Input::exists() ) {
return Views::view( 'calendar.events.create' );
}
/** Attempt to save the form data somewhat */
// get the form calendar input
$calendarID = Input::post('calendar_id') ? Input::post('calendar_id') : ''; // for submitting the form
$calendarSelect = HoudiniForms::getFormFieldHtml( 'calendar_id', 'Calendar', 'select', $calendarID, self::$calendars->simpleByUser() );
Components::set( 'calendarSelect', $calendarSelect );
$repeatSelect = HoudiniForms::getFormFieldHtml( 'repeats', 'Frequency', 'select', Input::post('repeats'), self::$events->repeatOptions );
Components::set( 'repeatSelect', $repeatSelect );
if ( ! Forms::check( 'createEvent' ) ) {
Issues::add( 'error', [ 'There was an error with your form.' => Check::userErrors() ] );
return Views::view( 'calendar.events.create' );
}
$event_id = self::$events->create(
$calendarID,
Input::post('title'),
Date::applyUtcToDate( Date::determineDateInput() ),
Input::post('description'),
Input::post('location'),
Input::post('repeats'),
Input::post('color'),
0,
);
if ( ! $event_id ) {
Issues::add( 'error', [ 'There was an error creating your event.' => Check::userErrors() ] );
return Views::view( 'calendar.events.create' );
}
if ( Input::post('repeats') != 'none' ) {
$childrens = self::$events->generateChildEvents( $event_id, true, true );
}
Session::flash( 'success', 'Your Event has been created.' );
Redirect::to( 'calendar/'.self::$defaultView.'/'. $calendarID );
}
public function editEvent( $id = null ) {
$calendar = Input::exists('calendar_id') ? Input::post('calendar_id') : '';
$event = self::$events->findById( $id );
$readableDate = date('Y-m-d H:i:s', $event->event_time);
if ( $event == false ) {
Session::flash( 'error', 'Event not found.' );
return Redirect::to( 'calendar/'.self::$defaultView.'/' );
}
if ( $event->createdBy != App::$activeUser->ID ) {
Session::flash( 'error', 'You do not have permission to modify this event.' );
return Redirect::to( 'calendar/'.self::$defaultView.'/' );
}
$repeatSelect = HoudiniForms::getFormFieldHtml( 'repeats', 'Frequency', 'select', $event->repeats, self::$events->repeatOptions );
Components::set( 'repeatSelect', $repeatSelect );
// there should be a way to do this natively
$event_at = Date::getDateBreakdown( $event->event_time, true );
// $readableDate = date('Y-m-d H:i:s', $readableDate);
$dateSelect = Views::simpleView( 'calendar.dateSelect', $event_at );
Components::set( 'dateSelect', $dateSelect );
Components::set( 'color', $event->color );
if ( ! Input::exists( 'submit' ) ) {
return Views::view( 'calendar.events.edit', $event );
}
if ( ! Forms::check( 'editEvent' ) ) {
Issues::add( 'error', [ 'There was an error updating your event.' => Check::userErrors() ] );
return Views::view( 'calendar.events.edit', $event );
}
$result = self::$events->update(
$id,
Input::post('title'),
Date::applyUtcToDate( Date::determineDateInput() ),
Input::post('description'),
Input::post('location'),
Input::post('repeats'),
Input::post('color'),
);
if ( Input::post('repeats') != 'none' && $event->parent_id == 0 ) {
$childrens = self::$events->generateChildEvents( $event->ID, true, true );
}
if ( ! $result ) {
Issues::add( 'error', [ 'There was an error updating your event.' => Check::userErrors() ] );
return Views::view( 'calendar.events.edit', $event->ID );
}
Session::flash( 'success', 'Your Event has been updated.' );
Redirect::to( 'calendar/'.self::$defaultView.'/'. $event->calendar_id );
}
public function deleteEvent( $id = null ) {
$event = self::$events->findById( $id );
if ( $event == false ) {
Issues::add( 'error', 'Event not found.' );
return $this->index();
}
if ( $event->createdBy != App::$activeUser->ID ) {
Issues::add( 'error', 'You do not have permission to modify this event.' );
return $this->index();
}
$result = self::$events->delete( $id );
if ( !$result ) {
Session::flash( 'error', 'There was an error deleting the event(s)' );
} else {
Session::flash( 'success', 'Event deleted' );
}
return $this->index();
}
/**
* Calendars
*/
public function calendar( $id = null ) {
$calendar = $this->findCalendarOrFail( $id );
Views::view( 'calendar.calendar.view', $calendar );
}
public function createCalendar() {
$timezoneSelect = HoudiniForms::getTimezoneHtml( Date::getTimezone() );
Components::set( 'timezoneSelect', $timezoneSelect );
if ( ! Input::exists() ) {
return Views::view( 'calendar.calendar.create' );
}
if ( ! Forms::check( 'createCalendar' ) ) {
Issues::add( 'error', [ 'There was an error creating your calendar111.' => Check::userErrors() ] );
return Views::view( 'calendar.calendar.create' );
}
$calendar = self::$calendars->create( Input::post('title'), Input::post('description'), Input::post('timezone'), Input::post('color') );
if ( ! $calendar ) {
return Views::view( 'calendar.calendar.create' );
}
Session::flash( 'success', 'Your Calendar has been created.' );
Redirect::to( 'calendar/'.self::$defaultView.'/');
}
public function editCalendar( $id = null ) {
$calendar = $this->findCalendarOrFail( $id );
$timezoneSelect = HoudiniForms::getTimezoneHtml( Date::getTimezone() );
Components::set( 'timezoneSelect', $timezoneSelect );
Components::set( 'color', $calendar->color );
if ( ! Input::exists( 'submit' ) ) {
return Views::view( 'calendar.calendar.edit', $calendar );
}
if ( !Forms::check( 'editCalendar' ) ) {
Issues::add( 'error', [ 'There was an error editing your calendar.' => Check::userErrors() ] );
return Views::view( 'calendar.calendar.edit', $calendar );
}
$result = self::$calendars->update( $id, Input::post('title'), Input::post('description'), Input::post('timezone'), Input::post('color') );
if ( !$result ) {
Issues::add( 'error', [ 'There was an error updating your calendar.' => Check::userErrors() ] );
return Views::view( 'calendar.calendar.edit', $calendar );
}
Session::flash( 'success', 'Your Calendar has been updated.' );
Redirect::to( 'calendar/'.self::$defaultView.'/'. $calendar->ID );
}
public function deleteCalendar( $id = null ) {
$calendar = self::$calendars->findById( $id );
if ( $calendar == false ) {
Issues::add( 'error', 'Calendar not found.' );
return $this->index();
}
if ( $calendar->createdBy != App::$activeUser->ID ) {
Issues::add( 'error', 'You do not have permission to modify this calendar.' );
return $this->index();
}
$results = self::$events->deleteByCalendar( $id );
$result = self::$calendars->delete( $id );
if ( !$result ) {
Session::flash( 'error', 'There was an error deleting the calendar(s)' );
} else {
Session::flash( 'success', 'Calendar deleted' );
}
Redirect::to( 'calendar/'.self::$defaultView.'/' );
}
/**
* Views
*/
public function byDay( $id = 0 ) {
// Set base components
Components::set( 'currentView', __FUNCTION__ );
Components::set( 'calendarID', $id );
// Set components for next / back arrows
$nextDayMonth = date( 'M', strtotime( 'tomorrow', self::$selectedDate ) );
$nextDay = date( 'd', strtotime( 'tomorrow', self::$selectedDate ) );
$lastDayMonth = date( 'M', strtotime( 'yesterday', self::$selectedDate ) );
$lastDay = date( 'd', strtotime( 'yesterday', self::$selectedDate ) );
Components::set( 'nextDayMonth', $nextDayMonth );
Components::set( 'nextDay', $nextDay );
Components::set( 'lastDayMonth', $lastDayMonth );
Components::set( 'lastDay', $lastDay );
// Get the data
$dayArray = self::$events->dayArray( $id, self::$selectedDate );
// build the results
$selectedHour = Date::getCurrentHour();
$day = date( 'd', self::$selectedDate );
$month = date( 'M', self::$selectedDate );
$year = date( 'Y', self::$selectedDate );
$fullDay = [];
foreach ( $dayArray as $hour => $events ) {
Components::set( 'hour', $hour );
$hourCell = new \stdClass();
$hourCell->hour = $hour;
if ( $hour == $selectedHour ) {
$hourCell->hourSelected = ' hour-active';
} else {
$hourCell->hourSelected = '';
}
$hourCell->day = $day;
$hourCell->month = $month;
$hourCell->year = $year;
$hourCell->EventCells = Views::simpleView( 'calendar.nav.row', $events );
$fullDay[] = $hourCell;
}
// Calendar Top Tabs
Components::unset( 'calendarDropdown');
$calendarTabs = Views::simpleView('calendar.nav.topTabs');
$tabsView = Navigation::activePageSelect( $calendarTabs, '/calendar/byDay/', false, true );
// must be done after top-nav gets selected
$calendarDropdown = Views::simpleView('calendar.nav.calendarDropdown', self::$calendars->simpleObjectByUser() );
$calendarDropdownView = Navigation::activePageSelect( $calendarDropdown, Input::get( 'url' ), false, true ); // add notebookID as second param
Components::set( 'calendarDropdown', $calendarDropdownView);
Components::set( 'CalendarNav', Template::parse( $tabsView ) );
Components::set( 'activeDate', date( 'F d, Y', self::$selectedDate ) );
Views::view( 'calendar.byDay', $fullDay );
}
public function byWeek( $id = 0 ) {
// Set base components
Components::set( 'currentView', __FUNCTION__ );
Components::set( 'calendarID', $id );
// Set components for next / back arrows
$lastWeekMonth = date( 'M', strtotime( '-7 days', self::$selectedDate) );
$lastWeekDay = date( 'd', strtotime( '-7 days', self::$selectedDate) );
$lastWeekYear = date( 'Y', strtotime( '-7 days', self::$selectedDate) );
$nextWeekMonth = date( 'M', strtotime( '+7 days', self::$selectedDate) );
$nextWeekDay = date( 'd', strtotime( '+7 days', self::$selectedDate) );
$nextWeekYear = date( 'Y', strtotime( '+7 days', self::$selectedDate) );
Components::set( 'lastWeekMonth', $lastWeekMonth );
Components::set( 'lastWeek', $lastWeekDay );
Components::set( 'lastYear', $lastWeekYear );
Components::set( 'nextWeekMonth', $nextWeekMonth );
Components::set( 'nextWeek', $nextWeekDay );
Components::set( 'nextYear', $nextWeekYear );
// Get the data
$weekArray = self::$events->weekArray( $id, self::$selectedDate );
// build the results
$presentMonth = date( 'F', self::$selectedDate );
$presentDay = date( 'd', self::$selectedDate );
foreach ( $weekArray as $week => $days ) {
$weekFormat = [];
foreach ( $days as $day => $events ) {
if ( empty( $first ) ) {
$first = true;
if ( intval( $presentDay ) >= $day ) {
$month = date( 'F', self::$selectedDate );
} else {
$month = date( 'F', strtotime( '-7 days', self::$selectedDate ) );
}
}
if ( $day == '01' ) {
$month = date( 'F', strtotime( '+7 days', self::$selectedDate ) );
}
Components::set( 'currentMonth', $month );
Components::set( 'currentDay', $day );
$dayCell = new \stdClass();
if ( $presentDay == $day && $presentMonth == $month ) {
$dayCell->highlightedDate = ' today';
} else {
$dayCell->highlightedDate = '';
}
$dayCell->day = $day;
$dayCell->dayEventList = Views::simpleView( 'calendar.nav.cell', $events );
$weekFormat[] = $dayCell;
}
$weekView = Views::simpleView( 'calendar.nav.week', $weekFormat );
Components::set( $week . 'Element', $weekView );
}
// Calendar Top Tabs
Components::unset( 'calendarDropdown');
$calendarTabs = Views::simpleView('calendar.nav.topTabs');
$tabsView = Navigation::activePageSelect( $calendarTabs, '/calendar/byWeek/', false, true );
// must be done after top-nav gets selected
$calendarDropdown = Views::simpleView('calendar.nav.calendarDropdown', self::$calendars->simpleObjectByUser() );
$calendarDropdownView = Navigation::activePageSelect( $calendarDropdown, Input::get( 'url' ), false, true ); // add notebookID as second param
Components::set( 'calendarDropdown', $calendarDropdownView);
Components::set( 'CalendarNav', Template::parse( $tabsView ) );
Components::set( 'dateWeek', 'Week of ' . date( 'F d, Y', self::$selectedDate ) );
Views::view( 'calendar.byWeek' );
}
public function byMonth( $id = 0 ) {
// Set base components
Components::set( 'currentView', __FUNCTION__ );
Components::set( 'calendarID', $id );
// Set components for next / back arrows
$month = date( 'F', strtotime( 'first day of last month', self::$selectedDate ) );
$lastMonthYear = date( 'Y', strtotime( 'first day of last month', self::$selectedDate ) );
$nextMonth = date( 'F', strtotime( 'first day of next month', self::$selectedDate ) );
$nextMonthYear = date( 'Y', strtotime( 'first day of next month', self::$selectedDate ) );
Components::set( 'lastMonth', $month );
Components::set( 'lastMonthYear', $lastMonthYear );
Components::set( 'nextMonth', $nextMonth );
Components::set( 'nextMonthYear', $nextMonthYear );
// Get the data
$monthArray = self::$events->monthArray( $id, self::$selectedDate );
// build the results
$lastMonth = strtotime( 'last month', self::$selectedDate );
$presentMonth = date( 'F', self::$selectedDate );
$presentDay = date( 'd', self::$selectedDate );
foreach ( $monthArray as $week => $days ) {
$weekFormat = [];
foreach ( $days as $day => $events ) {
if ( $day == '01' ) {
$month = date( 'F', strtotime( '+1 month', $lastMonth ) );
$lastMonth = strtotime( '+1 month', $lastMonth) ;
}
Components::set( 'currentMonth', $month );
Components::set( 'currentDay', $day );
$dayCell = new \stdClass();
if ( $presentDay == $day && $presentMonth == $month ) {
$dayCell->highlightedDate = ' today';
} else {
$dayCell->highlightedDate = '';
}
$dayCell->day = $day;
// prevent duplicated entries for previous/next month
if ( $lastMonth < strtotime( 'this month',self::$selectedDate ) || $lastMonth == strtotime( 'next month',self::$selectedDate )) {
$events = [];
}
$dayCell->dayEventList = Views::simpleView( 'calendar.nav.cell', $events );
$weekFormat[] = $dayCell;
}
$weekView = Views::simpleView( 'calendar.nav.week', $weekFormat );
Components::set( $week . 'Element', $weekView );
}
// Calendar Top Tabs
Components::unset( 'calendarDropdown');
$calendarTabs = Views::simpleView('calendar.nav.topTabs');
$tabsView = Navigation::activePageSelect( $calendarTabs, '/calendar/byMonth/', false, true );
// must be done after top-nav gets selected
$calendarDropdown = Views::simpleView('calendar.nav.calendarDropdown', self::$calendars->simpleObjectByUser() );
$calendarDropdownView = Navigation::activePageSelect( $calendarDropdown, Input::get( 'url' ), false, true ); // add notebookID as second param
Components::set( 'calendarDropdown', $calendarDropdownView);
Components::set( 'CalendarNav', Template::parse( $tabsView ) );
Components::set( 'dateMonth', date( 'F Y', self::$selectedDate ) );
Views::view( 'calendar.byMonth' );
}
public function byYear( $id = 0 ) {
// Set base components
Components::set( 'calendarID', $id );
Components::set( 'currentView', __FUNCTION__ );
// Set components for next / back arrows
$nextYear = date( 'Y', strtotime( 'next year', self::$selectedDate ) );
$lastYear = date( 'Y', strtotime( 'last year', self::$selectedDate ) );
Components::set( 'lastYear', $lastYear );
Components::set( 'nextYear', $nextYear );
// Get the data
$eventList = self::$events->yearArray( $id, self::$selectedDate );
// Calendar Top Tabs
Components::unset( 'calendarDropdown');
$calendarTabs = Views::simpleView('calendar.nav.topTabs');
$tabsView = Navigation::activePageSelect( $calendarTabs, '/calendar/byYear/', false, true );
// must be done after top-nav gets selected
$calendarDropdown = Views::simpleView('calendar.nav.calendarDropdown', self::$calendars->simpleObjectByUser() );
$calendarDropdownView = Navigation::activePageSelect( $calendarDropdown, Input::get( 'url' ), false, true ); // add notebookID as second param
Components::set( 'calendarDropdown', $calendarDropdownView);
Components::set( 'CalendarNav', Template::parse( $tabsView ) );
Components::set( 'dateYear', date( 'Y', self::$selectedDate ) );
Views::view( 'calendar.byYear', $eventList );
}
public function events( $id = 0 ) {
Components::set( 'currentView', __FUNCTION__ );
Components::set( 'calendarID', $id );
if ( ! empty( $id ) ) {
$calendar = self::$calendars->findById( $id );
if ( $calendar == false ) {
Issues::add( 'error', 'Calendar not found.' );
return $this->index();
}
if ( $calendar->createdBy != App::$activeUser->ID ) {
Issues::add( 'error', 'You do not have permission to view this calendar.' );
return $this->index();
}
Components::set( 'calendarName', $calendar->title );
$eventList = self::$events->findByCalendar( $id );
} else {
$eventList = self::$events->userEvents( 5 );
}
// Calendar Top Tabs
Components::unset( 'calendarDropdown');
$calendarTabs = Views::simpleView('calendar.nav.topTabs');
$tabsView = Navigation::activePageSelect( $calendarTabs, '/calendar/events/', false, true );
// must be done after top-nav gets selected
$calendarDropdown = Views::simpleView('calendar.nav.calendarDropdown', self::$calendars->simpleObjectByUser() );
$calendarDropdownView = Navigation::activePageSelect( $calendarDropdown, Input::get( 'url' ), false, true ); // add notebookID as second param
Components::set( 'calendarDropdown', $calendarDropdownView);
Components::set( 'CalendarNav', Template::parse( $tabsView ) );
Views::view( 'calendar.events.list', $eventList );
}
/**
* Support Functions
*/
private function findCalendarOrFail( $id = null ) {
$calendar = self::$calendars->findById( $id );
if ( $calendar == false ) {
Session::flash( 'error', 'Calendar not found.' );
Redirect::to( 'calendar/'.self::$defaultView.'/' );
}
if ( $calendar->createdBy != App::$activeUser->ID ) {
Session::flash( 'error', 'Permissions Error.' );
Redirect::to( 'calendar/'.self::$defaultView.'/' );
}
return $calendar;
}
private function findEventOrFail( $id = null ) {
$event = self::$events->findById( $id );
if ( $event == false ) {
Session::flash( 'error', 'Event not found.' );
Redirect::to( 'calendar/'.self::$defaultView.'/' );
}
if ( $event->createdBy != App::$activeUser->ID ) {
Session::flash( 'error', 'Permissions Error.' );
Redirect::to( 'calendar/'.self::$defaultView.'/' );
}
return $event;
}
private function getEventBreakdown( $start_timestamp = 0, $end_timestamp = 0, $with_timezone = false ) {
$out = new \stdClass();
if ( empty( $end_timestamp ) ) {
$out->allDay = 'true';
// $out->date = ;
// $out->time = ;
$out->endDate = $out->date;
$out->endTime = $out->time;
} else {
$out->allDay = 'false';
// $out->date = ;
// $out->time = ;
$out->endDate = $out->date;
$out->endTime = $out->time;
}
$timestamp = intval( $timestamp );
$init = date('Y-m-d H:i:s', $timestamp);
if ( true === $with_timezone ) {
$readableDate = self::applyTimezoneToTimestamp( $timestamp );
} else {
$readableDate = date('Y-m-d H:i:s', $timestamp);
}
$date = date( 'Y-m-d', strtotime( $readableDate ) );
$time = date( 'H:i', strtotime( $readableDate ) );
return [
'time' => $time,
'date' => $date,
];
}
}