Initial commit
This commit is contained in:
593
app/plugins/calendar/controllers/calendar.php
Normal file
593
app/plugins/calendar/controllers/calendar.php
Normal file
@ -0,0 +1,593 @@
|
||||
<?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,
|
||||
];
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
153
app/plugins/calendar/css/calendar.css
Normal file
153
app/plugins/calendar/css/calendar.css
Normal file
@ -0,0 +1,153 @@
|
||||
.calendar-container {
|
||||
margin-left: 20px;
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.calendar-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.calendar-cell {
|
||||
flex: 1;
|
||||
border: 1px solid #ddd;
|
||||
text-align: center;
|
||||
padding: 10px 0;
|
||||
margin: 0 5px;
|
||||
}
|
||||
|
||||
.calendar-cell h4 {
|
||||
margin: 0;
|
||||
padding: 5px;
|
||||
border-radius: 4px;
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
|
||||
.hour-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.hour-body {
|
||||
display: flex; /* Add this line to use flexbox */
|
||||
flex-direction: row; /* Ensure the direction is row */
|
||||
flex: 4;
|
||||
border: 1px solid #ddd;
|
||||
text-align: center;
|
||||
padding: 10px 0;
|
||||
margin-left: 5px;
|
||||
margin-right: 5px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.hour-cell {
|
||||
flex: 1;
|
||||
border: 1px solid #ddd;
|
||||
text-align: center;
|
||||
padding: 10px 0;
|
||||
margin-left: 5px;
|
||||
margin-right: 5px;
|
||||
align-items: center;
|
||||
max-width: 250px;
|
||||
}
|
||||
|
||||
.today {
|
||||
background-color: #5cb85c !important;
|
||||
}
|
||||
|
||||
.hour-header, .hour-footer {
|
||||
flex: 0 0 10%;
|
||||
background-color: #f8f8f8;
|
||||
text-align: center;
|
||||
padding: 10px 0;
|
||||
margin: 0 5px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* Adjusting the first and last cell margins to align with the container edges */
|
||||
.calendar-cell:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.calendar-cell:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.select-container {
|
||||
color: white;
|
||||
}
|
||||
.custom-select {
|
||||
/* color: red; */
|
||||
color: #000;
|
||||
}
|
||||
.custom-select .white {
|
||||
background-color: #ffffff;
|
||||
}
|
||||
.custom-select .primary {
|
||||
background-color: #337ab7;
|
||||
}
|
||||
.custom-select .success {
|
||||
background-color: #5cb85c;
|
||||
}
|
||||
.custom-select .info {
|
||||
background-color: #5bc0de;
|
||||
}
|
||||
.custom-select .warning {
|
||||
background-color: #f0ad4e;
|
||||
}
|
||||
.custom-select .danger {
|
||||
background-color: #d9534f;
|
||||
}
|
||||
.select-container .primary {
|
||||
background-color: #337ab7;
|
||||
}
|
||||
.select-container .white {
|
||||
background-color: #ffffff;
|
||||
}
|
||||
.select-container .success {
|
||||
background-color: #5cb85c;
|
||||
}
|
||||
.select-container .info {
|
||||
background-color: #5bc0de;
|
||||
}
|
||||
.select-container .warning {
|
||||
background-color: #f0ad4e;
|
||||
}
|
||||
.select-container .danger {
|
||||
background-color: #d9534f;
|
||||
}
|
||||
|
||||
.dateDayContainer {
|
||||
width: 250px;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.dateWeekContainer {
|
||||
width: 450px;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.dateMonthContainer {
|
||||
width: 250px;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.dateYearContainer {
|
||||
width: 150px;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.hour-active {
|
||||
background-color: #217025 !important;
|
||||
/* color: #00ff0d !important; */
|
||||
background-image:none;
|
||||
}
|
136
app/plugins/calendar/forms.php
Normal file
136
app/plugins/calendar/forms.php
Normal file
@ -0,0 +1,136 @@
|
||||
<?php
|
||||
/**
|
||||
* app/plugins/calendar/forms.php
|
||||
*
|
||||
* This houses all of the form checking functions for this plugin.
|
||||
*
|
||||
* @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\Plugins\Calendar;
|
||||
|
||||
use TheTempusProject\Bedrock\Functions\Input;
|
||||
use TheTempusProject\Bedrock\Functions\Check;
|
||||
use TheTempusProject\Classes\Forms;
|
||||
|
||||
class CalendarForms extends Forms {
|
||||
/**
|
||||
* Adds these functions to the form list.
|
||||
*/
|
||||
public function __construct() {
|
||||
self::addHandler( 'calendarSelect', __CLASS__, 'calendarSelect' );
|
||||
self::addHandler( 'createEvent', __CLASS__, 'createEvent' );
|
||||
self::addHandler( 'createCalendar', __CLASS__, 'createCalendar' );
|
||||
self::addHandler( 'editEvent', __CLASS__, 'editEvent' );
|
||||
self::addHandler( 'editCalendar', __CLASS__, 'editCalendar' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the password re-send form.
|
||||
*
|
||||
* @return {bool}
|
||||
*/
|
||||
public static function calendarSelect() {
|
||||
if ( ! Input::exists( 'calendar_id' ) ) {
|
||||
Check::addUserError( 'You must include a title.' );
|
||||
return false;
|
||||
}
|
||||
// if ( !self::token() ) {
|
||||
// Check::addUserError( 'token - comment out later.' );
|
||||
// return false;
|
||||
// }
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function createEvent() {
|
||||
if ( ! Input::exists( 'title' ) ) {
|
||||
Check::addUserError( 'You must include a title.' );
|
||||
return false;
|
||||
}
|
||||
if ( ! Input::exists( 'date' ) ) {
|
||||
Check::addUserError( 'You must include a date.' );
|
||||
return false;
|
||||
}
|
||||
if ( ! Input::exists( 'time' ) ) {
|
||||
Check::addUserError( 'You must include a time.' );
|
||||
return false;
|
||||
}
|
||||
if ( ! Input::exists( 'repeats' ) ) {
|
||||
Check::addUserError( 'You must include a frequency.' );
|
||||
return false;
|
||||
}
|
||||
if ( ! Input::exists( 'calendar_id' ) ) {
|
||||
Check::addUserError( 'You must select a calendar.' );
|
||||
return false;
|
||||
}
|
||||
// if ( !self::token() ) {
|
||||
// Check::addUserError( 'token - comment out later.' );
|
||||
// return false;
|
||||
// }
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function createCalendar() {
|
||||
if ( ! Input::exists( 'title' ) ) {
|
||||
Check::addUserError( 'You must include a title.' );
|
||||
return false;
|
||||
}
|
||||
if ( ! Input::exists( 'timezone' ) ) {
|
||||
Check::addUserError( 'You must include a timezone.' );
|
||||
return false;
|
||||
}
|
||||
// if ( ! self::token() ) {
|
||||
// Check::addUserError( 'token - comment out later.' );
|
||||
// return false;
|
||||
// }
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function editEvent() {
|
||||
if ( ! Input::exists( 'title' ) ) {
|
||||
Check::addUserError( 'You must include a title.' );
|
||||
return false;
|
||||
}
|
||||
if ( ! Input::exists( 'date' ) ) {
|
||||
Check::addUserError( 'You must include a date.' );
|
||||
return false;
|
||||
}
|
||||
if ( ! Input::exists( 'time' ) ) {
|
||||
Check::addUserError( 'You must include a time.' );
|
||||
return false;
|
||||
}
|
||||
if ( ! Input::exists( 'repeats' ) ) {
|
||||
Check::addUserError( 'You must include a frequency.' );
|
||||
return false;
|
||||
}
|
||||
// if ( !self::token() ) {
|
||||
// Check::addUserError( 'token - comment out later.' );
|
||||
// return false;
|
||||
// }
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function editCalendar() {
|
||||
if ( ! Input::exists( 'submit' ) ) {
|
||||
return false;
|
||||
}
|
||||
if ( ! Input::exists( 'title' ) ) {
|
||||
Check::addUserError( 'You must include a title.' );
|
||||
return false;
|
||||
}
|
||||
if ( ! Input::exists( 'timezone' ) ) {
|
||||
Check::addUserError( 'You must include a timezone.' );
|
||||
return false;
|
||||
}
|
||||
// if ( !self::token() ) {
|
||||
// Check::addUserError( 'token - comment out later.' );
|
||||
// return false;
|
||||
// }
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
new CalendarForms;
|
157
app/plugins/calendar/models/calendars.php
Normal file
157
app/plugins/calendar/models/calendars.php
Normal file
@ -0,0 +1,157 @@
|
||||
<?php
|
||||
/**
|
||||
* app/plugins/calendar/models/events.php
|
||||
*
|
||||
* This class is used for the manipulation of the calendars database table.
|
||||
*
|
||||
* @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\Models;
|
||||
|
||||
use TheTempusProject\Bedrock\Classes\Config;
|
||||
use TheTempusProject\Bedrock\Functions\Check;
|
||||
use TheTempusProject\Bedrock\Functions\Date;
|
||||
use TheTempusProject\Canary\Canary as Debug;
|
||||
use TheTempusProject\Classes\DatabaseModel;
|
||||
use TheTempusProject\TheTempusProject as App;
|
||||
use TheTempusProject\Houdini\Classes\Filters;
|
||||
use TheTempusProject\Bedrock\Classes\CustomException;
|
||||
|
||||
class Calendars extends DatabaseModel {
|
||||
public $tableName = 'calendars';
|
||||
public $databaseMatrix = [
|
||||
[ 'title', 'varchar', '256' ],
|
||||
[ 'color', 'varchar', '48' ],
|
||||
[ 'privacy', 'varchar', '48' ],
|
||||
[ 'description', 'text', '' ],
|
||||
[ 'createdBy', 'int', '11' ],
|
||||
[ 'createdAt', 'int', '11' ],
|
||||
[ 'timezone', 'varchar', '256' ],
|
||||
];
|
||||
|
||||
/**
|
||||
* The model constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function create( $title, $description = '', $timezone = '', $color = 'default' ) {
|
||||
if ( ! Check::dataTitle( $title ) ) {
|
||||
Debug::info( 'Calendars: illegal title.' );
|
||||
return false;
|
||||
}
|
||||
if ( empty( $timezone ) ) {
|
||||
$timezone = Date::getTimezone();
|
||||
}
|
||||
$fields = [
|
||||
'title' => $title,
|
||||
'description' => $description,
|
||||
'timezone' => $timezone,
|
||||
'color' => $color,
|
||||
'createdBy' => App::$activeUser->ID,
|
||||
'createdAt' => time(),
|
||||
];
|
||||
if ( ! self::$db->insert( $this->tableName, $fields ) ) {
|
||||
new CustomException( 'calendarCreate' );
|
||||
Debug::error( "Calendar: not created " . var_export($fields,true) );
|
||||
return false;
|
||||
}
|
||||
return self::$db->lastId();
|
||||
}
|
||||
|
||||
public function update( $id, $title, $description = '', $timezone = '', $color = 'default' ) {
|
||||
if ( empty( $timezone ) ) {
|
||||
$timezone = Date::getTimezone();
|
||||
}
|
||||
if ( !Check::id( $id ) ) {
|
||||
Debug::info( 'Calendars: illegal ID.' );
|
||||
return false;
|
||||
}
|
||||
if ( !Check::dataTitle( $title ) ) {
|
||||
Debug::info( 'Calendars: illegal title.' );
|
||||
return false;
|
||||
}
|
||||
$fields = [
|
||||
'title' => $title,
|
||||
'description' => $description,
|
||||
'timezone' => $timezone,
|
||||
'color' => $color,
|
||||
];
|
||||
if ( !self::$db->update( $this->tableName, $id, $fields ) ) {
|
||||
new CustomException( 'calendarUpdate' );
|
||||
Debug::error( "Calendar: $id not updated: $fields" );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function byUser( $limit = null ) {
|
||||
$whereClause = ['createdBy', '=', App::$activeUser->ID];
|
||||
if ( empty( $limit ) ) {
|
||||
$calendars = self::$db->get( $this->tableName, $whereClause );
|
||||
} else {
|
||||
$calendars = self::$db->get( $this->tableName, $whereClause, 'ID', 'DESC', [0, $limit] );
|
||||
}
|
||||
if ( !$calendars->count() ) {
|
||||
Debug::info( 'No Calendars found.' );
|
||||
return false;
|
||||
}
|
||||
return $this->filter( $calendars->results() );
|
||||
}
|
||||
|
||||
public function getName( $id ) {
|
||||
$calendar = self::findById( $id );
|
||||
if (false == $calendar) {
|
||||
return 'unknown';
|
||||
}
|
||||
return $calendar->title;
|
||||
}
|
||||
|
||||
public function getColor( $id ) {
|
||||
$calendar = self::findById( $id );
|
||||
if (false == $calendar) {
|
||||
return 'default';
|
||||
}
|
||||
return $calendar->color;
|
||||
}
|
||||
|
||||
public function simpleByUser() {
|
||||
$whereClause = ['createdBy', '=', App::$activeUser->ID];
|
||||
$calendars = self::$db->get( $this->tableName, $whereClause );
|
||||
if ( !$calendars->count() ) {
|
||||
Debug::warn( 'Could not find any calendars' );
|
||||
return false;
|
||||
}
|
||||
|
||||
$calendars = $calendars->results();
|
||||
$out = [];
|
||||
foreach ( $calendars as &$calendar ) {
|
||||
$out[ $calendar->title ] = $calendar->ID;
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
public function simpleObjectByUser() {
|
||||
$whereClause = ['createdBy', '=', App::$activeUser->ID];
|
||||
$calendars = self::$db->get( $this->tableName, $whereClause );
|
||||
if ( !$calendars->count() ) {
|
||||
Debug::warn( 'Could not find any calendars' );
|
||||
return false;
|
||||
}
|
||||
|
||||
$calendars = $calendars->results();
|
||||
$out = [];
|
||||
foreach ( $calendars as &$calendar ) {
|
||||
$obj = new \stdClass();
|
||||
$obj->title = $calendar->title;
|
||||
$obj->ID = $calendar->ID;
|
||||
$out[] = $obj;
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
}
|
509
app/plugins/calendar/models/events.php
Normal file
509
app/plugins/calendar/models/events.php
Normal file
@ -0,0 +1,509 @@
|
||||
<?php
|
||||
/**
|
||||
* app/plugins/calendar/models/events.php
|
||||
*
|
||||
* This class is used for the manipulation of the events database table.
|
||||
*
|
||||
* @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\Models;
|
||||
|
||||
use TheTempusProject\Bedrock\Classes\Config;
|
||||
use TheTempusProject\Bedrock\Functions\Check;
|
||||
use TheTempusProject\Canary\Canary as Debug;
|
||||
use TheTempusProject\Classes\DatabaseModel;
|
||||
use TheTempusProject\TheTempusProject as App;
|
||||
use TheTempusProject\Houdini\Classes\Filters;
|
||||
use TheTempusProject\Models\Calendars;
|
||||
use TheTempusProject\Bedrock\Classes\CustomException;
|
||||
use TheTempusProject\Bedrock\Functions\Date;
|
||||
use TheTempusProject\Houdini\Classes\Pagination;
|
||||
|
||||
class Events extends DatabaseModel {
|
||||
public $tableName = 'events';
|
||||
public $repeatOptions = [
|
||||
'Does Not Repeat' => 'none',
|
||||
'Every Day' => 'daily',
|
||||
'Every Week' => 'weekly',
|
||||
'Every Month' => 'monthly',
|
||||
'Every Year' => 'yearly',
|
||||
];
|
||||
public $databaseMatrix = [
|
||||
[ 'calendar_id', 'int', '11' ],
|
||||
[ 'title', 'varchar', '256' ],
|
||||
[ 'event_time', 'int', '11' ],
|
||||
[ 'event_ends', 'int', '11' ],
|
||||
[ 'description', 'text', '' ],
|
||||
[ 'location', 'varchar', '256' ],
|
||||
[ 'repeats', 'varchar', '48' ],
|
||||
[ 'color', 'varchar', '48' ],
|
||||
[ 'parent_id', 'int', '11' ],
|
||||
[ 'createdBy', 'int', '11' ],
|
||||
[ 'createdAt', 'int', '11' ],
|
||||
];
|
||||
protected static $calendars;
|
||||
|
||||
/**
|
||||
* The model constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
self::$calendars = new Calendars;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves a chat form to the db.
|
||||
*
|
||||
* @param string $message -contents of the chat form.
|
||||
* @return bool
|
||||
*/
|
||||
public function create( $calendar_id, $title, $event_time, $description = '', $location = '', $repeats = 'none', $color = 'default', $parent_id = 0 ) {
|
||||
if ( ! Check::id( $calendar_id ) ) {
|
||||
Debug::info( 'calendar event: illegal calendar ID.' );
|
||||
return false;
|
||||
}
|
||||
$fields = [
|
||||
'calendar_id' => $calendar_id,
|
||||
'title' => $title,
|
||||
'event_time' => $event_time,
|
||||
'description' => $description,
|
||||
'location' => $location,
|
||||
'repeats' => $repeats,
|
||||
'color' => $color,
|
||||
'parent_id' => $parent_id,
|
||||
'createdBy' => App::$activeUser->ID,
|
||||
'createdAt' => time(),
|
||||
];
|
||||
if ( !self::$db->insert( $this->tableName, $fields ) ) {
|
||||
Debug::info( 'Events::create - failed to insert to db' );
|
||||
return false;
|
||||
}
|
||||
return self::$db->lastId();
|
||||
}
|
||||
|
||||
public function update( $id, $title, $event_time, $description = '', $location ='', $repeats = 'none', $color = 'default', $parent_id = 0, $calendar_id = '' ) {
|
||||
if ( ! Check::id( $id ) ) {
|
||||
Debug::info( 'calendar event: illegal ID.' );
|
||||
return false;
|
||||
}
|
||||
$fields = [
|
||||
'title' => $title,
|
||||
'event_time' => $event_time,
|
||||
'description' => $description,
|
||||
'location' => $location,
|
||||
'repeats' => $repeats,
|
||||
'color' => $color,
|
||||
'parent_id' => $parent_id,
|
||||
];
|
||||
if ( ! self::$db->update( $this->tableName, $id, $fields ) ) {
|
||||
new CustomException( 'calendarEventUpdate' );
|
||||
Debug::error( "Event: $id not updated: $fields" );
|
||||
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function dayArray( $calendar_id = 0, $date = 0 ) {
|
||||
$whereClause = [ 'createdBy', '=', App::$activeUser->ID, 'AND' ];
|
||||
if ( ! empty( $calendar_id ) ) {
|
||||
$whereClause = array_merge( $whereClause, [ 'calendar_id', '=', $calendar_id, 'AND' ] );
|
||||
}
|
||||
|
||||
$whereClause = array_merge( $whereClause, [
|
||||
'event_time', '>=', Date::getDayStartTimestamp( $date, true ), 'AND',
|
||||
'event_time', '<=', Date::getDayEndTimestamp( $date, true ),
|
||||
] );
|
||||
|
||||
$events = self::$db->get( $this->tableName, $whereClause );
|
||||
if ( ! $events->count() ) {
|
||||
$results = [];
|
||||
} else {
|
||||
$results = $events->results();
|
||||
}
|
||||
$events = $this->sortByEventTimeHour(
|
||||
$this->filter(
|
||||
$results
|
||||
)
|
||||
);
|
||||
// Generate day array
|
||||
$currentDay = [];
|
||||
$currentHour = Date::getDayStartTimestamp( $date );
|
||||
$lastHour = Date::getDayEndTimestamp( $date );
|
||||
while ( $currentHour <= $lastHour ) {
|
||||
$hour = date( 'H', $currentHour );
|
||||
if ( ! empty( $events[ $hour ] ) ) {
|
||||
$dailyEvents = $events[ $hour ];
|
||||
} else {
|
||||
$dailyEvents = [];
|
||||
}
|
||||
$currentDay[ $hour ] = $dailyEvents;
|
||||
$currentHour = strtotime('+1 hour', $currentHour);
|
||||
}
|
||||
return $currentDay;
|
||||
}
|
||||
|
||||
public function weekArray( $calendar_id = 0, $date = null ) {
|
||||
$whereClause = [ 'createdBy', '=', App::$activeUser->ID, 'AND' ];
|
||||
if ( ! empty( $calendar_id ) ) {
|
||||
$whereClause = array_merge( $whereClause, [ 'calendar_id', '=', $calendar_id, 'AND' ] );
|
||||
}
|
||||
|
||||
$whereClause = array_merge( $whereClause, [
|
||||
'event_time', '>=', Date::getWeekStartTimestamp( $date, true ), 'AND',
|
||||
'event_time', '<=', Date::getWeekEndTimestamp( $date, true ),
|
||||
] );
|
||||
$events = self::$db->get( $this->tableName, $whereClause );
|
||||
if ( ! $events->count() ) {
|
||||
$results = [];
|
||||
} else {
|
||||
$results = $events->results();
|
||||
}
|
||||
$events = $this->sortByEventTime(
|
||||
$this->filter(
|
||||
$results
|
||||
),
|
||||
);
|
||||
|
||||
// Generate weeks array
|
||||
$output = [];
|
||||
$currentWeek = [];
|
||||
$currentDay = Date::getWeekStartTimestamp( $date );
|
||||
$weekCounter = 1;
|
||||
$dayCounter = 1;
|
||||
|
||||
// Re-index the array using the date derived from event_time as the key
|
||||
while ( $currentDay <= Date::getWeekEndTimestamp( $date ) ) {
|
||||
$month = date( 'F', $currentDay );
|
||||
$dayOfMonth = date( 'd', $currentDay );
|
||||
if ( ! empty( $events[ $month ][ $dayOfMonth ] ) ) {
|
||||
$dailyEvents = $events[ $month ][ $dayOfMonth ];
|
||||
} else {
|
||||
$dailyEvents = [];
|
||||
}
|
||||
$currentWeek[ $dayOfMonth ] = $dailyEvents;
|
||||
$currentDay = strtotime('+1 day', $currentDay);
|
||||
}
|
||||
|
||||
// Handle any remaining days in the last week
|
||||
if ( ! empty( $currentWeek ) ) {
|
||||
$output["week$weekCounter"] = $currentWeek;
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
public function monthArray( $calendar_id = 0, $date = null ) {
|
||||
$whereClause = [ 'createdBy', '=', App::$activeUser->ID, 'AND' ];
|
||||
if ( ! empty( $calendar_id ) ) {
|
||||
$whereClause = array_merge( $whereClause, [ 'calendar_id', '=', $calendar_id, 'AND' ] );
|
||||
}
|
||||
$whereClause = array_merge( $whereClause, [
|
||||
'event_time', '>=', Date::getMonthStartTimestamp( $date, true ), 'AND',
|
||||
'event_time', '<=', Date::getMonthEndTimestamp( $date, true ),
|
||||
] );
|
||||
|
||||
$events = self::$db->get( $this->tableName, $whereClause );
|
||||
if ( ! $events->count() ) {
|
||||
$results = [];
|
||||
} else {
|
||||
$results = $events->results();
|
||||
}
|
||||
$events = $this->sortByEventTime(
|
||||
$this->filter(
|
||||
$results
|
||||
),
|
||||
);
|
||||
|
||||
// Generate weeks array
|
||||
$output = [];
|
||||
$currentWeek = [];
|
||||
$currentDay = Date::getMonthStartTimestamp( $date );
|
||||
$weekCounter = 1;
|
||||
$dayCounter = 1;
|
||||
|
||||
// Re-index the array using the date derived from event_time as the key
|
||||
while ( $currentDay <= Date::getMonthEndTimestamp( $date ) ) {
|
||||
$month = date( 'F', $currentDay );
|
||||
$dayOfMonth = date( 'd', $currentDay );
|
||||
if ( ! empty( $events[ $month ][ $dayOfMonth ] ) ) {
|
||||
$dailyEvents = $events[ $month ][ $dayOfMonth ];
|
||||
} else {
|
||||
$dailyEvents = [];
|
||||
}
|
||||
$currentWeek[$dayOfMonth] = $dailyEvents;
|
||||
if (count($currentWeek) == 7) {
|
||||
$output["week$weekCounter"] = $currentWeek;
|
||||
$currentWeek = [];
|
||||
$weekCounter++;
|
||||
}
|
||||
$currentDay = strtotime('+1 day', $currentDay);
|
||||
}
|
||||
|
||||
// Handle any remaining days in the last week
|
||||
if ( ! empty( $currentWeek ) ) {
|
||||
$output["week$weekCounter"] = $currentWeek;
|
||||
}
|
||||
while ( $weekCounter < 7 ) {
|
||||
$output["week$weekCounter"] = [];
|
||||
$weekCounter++;
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
public function yearArray( $calendar_id = 0, $date = null ) {
|
||||
if ( empty( $date ) ) {
|
||||
$date = time();
|
||||
}
|
||||
$year = date( 'Y', $date );
|
||||
$firstDayUnix = date( 'U', strtotime( "Jan 1, $year" ) );
|
||||
$lastDayUnix = date( 'U', strtotime( "December 31, $year" ) );
|
||||
$whereClause = [ 'createdBy', '=', App::$activeUser->ID, 'AND' ];
|
||||
if ( ! empty( $calendar_id ) ) {
|
||||
$whereClause = array_merge( $whereClause, [ 'calendar_id', '=', $calendar_id, 'AND' ] );
|
||||
}
|
||||
$whereClause = array_merge( $whereClause, [
|
||||
'event_time', '<=', $lastDayUnix, 'AND',
|
||||
'event_time', '>=', $firstDayUnix,
|
||||
] );
|
||||
$events = self::$db->get( $this->tableName, $whereClause );
|
||||
if ( ! $events->count() ) {
|
||||
Debug::info( 'No ' . $this->tableName . ' data found.' );
|
||||
return [];
|
||||
}
|
||||
return $this->filter( $events->results() );
|
||||
}
|
||||
|
||||
public function compareEventTime($a, $b) {
|
||||
return $a->event_time - $b->event_time;
|
||||
}
|
||||
|
||||
public function sortByEventTimeHour( $results ) {
|
||||
usort( $results, [ $this,'compareEventTime' ] );
|
||||
|
||||
$sortedResults = array();
|
||||
foreach ( $results as $result ) {
|
||||
$date = new \DateTime();
|
||||
$date->setTimestamp( $result->event_time );
|
||||
$timezone = new \DateTimeZone( Date::getTimezone() );
|
||||
$date->setTimezone( $timezone );
|
||||
$dateKey = $date->format('H');
|
||||
$sortedResults[ $dateKey ][] = $result;
|
||||
}
|
||||
return $sortedResults;
|
||||
}
|
||||
|
||||
public function sortByEventTime( $results ) {
|
||||
usort( $results, [ $this,'compareEventTime' ] );
|
||||
|
||||
$sortedResults = array();
|
||||
foreach ( $results as $result ) {
|
||||
$date = new \DateTime();
|
||||
$date->setTimestamp( $result->event_time );
|
||||
$timezone = new \DateTimeZone( Date::getTimezone() );
|
||||
$date->setTimezone( $timezone );
|
||||
$month = $date->format('F');
|
||||
$dateKey = $date->format('d');
|
||||
if ( ! isset( $sortedResults[ $month ] ) ) {
|
||||
$sortedResults[ $month ] = [];
|
||||
}
|
||||
if ( ! isset( $sortedResults[ $month ][ $dateKey ] ) ) {
|
||||
$sortedResults[ $month ][ $dateKey ] = [];
|
||||
}
|
||||
$sortedResults[ $month ][ $dateKey ][] = $result;
|
||||
}
|
||||
return $sortedResults;
|
||||
}
|
||||
|
||||
public function findByCalendar( $id ) {
|
||||
$calendar = $this->verifyCalendar( $id );
|
||||
if ( empty( $calendar ) ) {
|
||||
return [];
|
||||
}
|
||||
$whereClause = [ 'createdBy', '=', App::$activeUser->ID, 'AND' ];
|
||||
$whereClause = array_merge( $whereClause, [ 'calendar_id', '=', $id ] );
|
||||
$events = self::$db->getPaginated( $this->tableName, $whereClause );
|
||||
if ( ! $events->count() ) {
|
||||
Debug::info( 'No ' . $this->tableName . ' data found.' );
|
||||
return [];
|
||||
}
|
||||
return $this->filter( $events->results() );
|
||||
}
|
||||
|
||||
public function userEvents( $limit = 0 ) {
|
||||
$whereClause = [ 'createdBy', '=', App::$activeUser->ID ];
|
||||
$events = self::$db->getPaginated( $this->tableName, $whereClause );
|
||||
if ( ! $events->count() ) {
|
||||
Debug::info( 'No ' . $this->tableName . ' data found.' );
|
||||
return [];
|
||||
}
|
||||
return $this->filter( $events->results() );
|
||||
}
|
||||
|
||||
public function filter( $data, $params = [] ) {
|
||||
$out = [];
|
||||
foreach ( $data as $instance ) {
|
||||
if ( !is_object( $instance ) ) {
|
||||
$instance = $data;
|
||||
$end = true;
|
||||
}
|
||||
$instance->repeatsText = array_search('none', $this->repeatOptions);
|
||||
$instance->calendarName = self::$calendars->getName( $instance->calendar_id );
|
||||
if ( empty( $instance->color ) || $instance->color == 'default' || $instance->color == 'none') {
|
||||
$instance->displayColor = self::$calendars->getColor( $instance->calendar_id );
|
||||
} else {
|
||||
$instance->displayColor = $instance->color;
|
||||
}
|
||||
$out[] = $instance;
|
||||
if ( !empty( $end ) ) {
|
||||
$out = $out[0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
public function today( $limit = 0 ) {
|
||||
$date = time();
|
||||
$day = date('d', $date);
|
||||
$month = date('M', $date);
|
||||
$year = date( 'Y', $date );
|
||||
$firstDayUnix = date( 'U', strtotime( "00:00:00 $day $month $year" ) );
|
||||
$lastDayUnix = date( 'U', strtotime( "23:59:59 $day $month $year" ) );
|
||||
$whereClause = [ 'createdBy', '=', App::$activeUser->ID, 'AND' ];
|
||||
$whereClause = array_merge( $whereClause, [
|
||||
'event_time', '<=', $lastDayUnix, 'AND',
|
||||
'event_time', '>=', $firstDayUnix,
|
||||
] );
|
||||
if ( empty( $limit ) ) {
|
||||
$events = self::$db->get( $this->tableName, $whereClause );
|
||||
} else {
|
||||
$events = self::$db->get( $this->tableName, $whereClause, 'ID', 'DESC', [0, $limit] );
|
||||
}
|
||||
if ( ! $events->count() ) {
|
||||
Debug::info( 'No ' . $this->tableName . ' data found.' );
|
||||
return [];
|
||||
}
|
||||
return $this->filter( $events->results() );
|
||||
}
|
||||
|
||||
private function verifyCalendar( $calendar_id ) {
|
||||
if ( ! Check::id( $calendar_id ) ) {
|
||||
Debug::info( 'Invalid Calendar ID' );
|
||||
return false;
|
||||
}
|
||||
$calendar = self::$calendars->findById( $calendar_id );
|
||||
if ( $calendar == false ) {
|
||||
Debug::info( 'Calendar not found' );
|
||||
return false;
|
||||
}
|
||||
if ( $calendar->createdBy != App::$activeUser->ID ) {
|
||||
Debug::info( 'You do not have permission to view this calendar' );
|
||||
return false;
|
||||
}
|
||||
return $calendar;
|
||||
}
|
||||
|
||||
public function deleteByCalendar( $calendar_id ) {
|
||||
$calendar = $this->verifyCalendar( $calendar_id );
|
||||
if ( empty( $calendar ) ) {
|
||||
return [];
|
||||
}
|
||||
$whereClause = [ 'createdBy', '=', App::$activeUser->ID, 'AND' ];
|
||||
$whereClause = array_merge( $whereClause, [ 'calendar_id', '=', $calendar_id ] );
|
||||
$events = self::$db->get( $this->tableName, $whereClause );
|
||||
if ( ! $events->count() ) {
|
||||
Debug::info( 'No ' . $this->tableName . ' data found.' );
|
||||
return [];
|
||||
}
|
||||
foreach( $events->results() as $event ) {
|
||||
$this->deleteByParent( $event->ID );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function deleteByParent( $event_id ) {
|
||||
$whereClause = [ 'createdBy', '=', App::$activeUser->ID, 'AND' ];
|
||||
$whereClause = array_merge( $whereClause, [ 'parent_id', '=', $event_id ] );
|
||||
$events = self::$db->get( $this->tableName, $whereClause );
|
||||
if ( ! $events->count() ) {
|
||||
Debug::info( 'No ' . $this->tableName . ' data found.' );
|
||||
return [];
|
||||
}
|
||||
foreach( $events->results() as $event ) {
|
||||
$this->delete( $event->ID );
|
||||
}
|
||||
// need to delete all child events accordingly
|
||||
return true;
|
||||
}
|
||||
|
||||
public function delete( $idArray ) {
|
||||
if ( !is_array( $idArray ) ) {
|
||||
$idArray = [ $idArray ];
|
||||
}
|
||||
return parent::delete( $idArray );
|
||||
}
|
||||
|
||||
public function generateChildEvents( $event_id, $remove_existing_children = true, $remove_history = false ) {
|
||||
$event = self::findById( $event_id );
|
||||
if (empty($event)) {
|
||||
return false;
|
||||
}
|
||||
if ($event->parent_id != 0) {
|
||||
return false;
|
||||
}
|
||||
if (!in_array($event->repeats, $this->repeatOptions)) {
|
||||
return false;
|
||||
}
|
||||
$startDate = time();
|
||||
$whereClause = [
|
||||
'parent_id', '=', $event_id,
|
||||
];
|
||||
if ( $remove_history && ! $remove_existing_children) {
|
||||
$whereClause = array_merge( $whereClause, [ 'AND', 'event_time', '<=', $startDate ] );
|
||||
} elseif ( $remove_existing_children && ! $remove_history ) {
|
||||
$whereClause = array_merge( $whereClause, [ 'AND', 'event_time', '>=', $startDate ] );
|
||||
} elseif ( !$remove_existing_children && !$remove_history ) {
|
||||
return false;
|
||||
}
|
||||
self::$db->delete($this->tableName, $whereClause);
|
||||
|
||||
switch ($event->repeats) {
|
||||
case 'daily':
|
||||
return $this->generateEvents( $event, 'P90D' );
|
||||
case 'weekly':
|
||||
return $this->generateEvents( $event, 'P1W' );
|
||||
case 'monthly':
|
||||
return $this->generateEvents( $event, 'P1M' );
|
||||
case 'yearly':
|
||||
return $this->generateEvents( $event, 'P1Y' );
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private function generateEvents( $event, $interval, $years = 2 ) {
|
||||
$endDate = strtotime('+'.$years.' years');
|
||||
$interval = new \DateInterval( $interval );
|
||||
$period = new \DatePeriod(new \DateTime('@' . $event->event_time), $interval, new \DateTime('@' . $endDate));
|
||||
foreach ($period as $date) {
|
||||
if ( $date->getTimestamp() <= time() ) {
|
||||
continue;
|
||||
}
|
||||
$result = $this->create(
|
||||
$event->calendar_id,
|
||||
$event->title,
|
||||
$date->getTimestamp(),
|
||||
$event->description,
|
||||
$event->location,
|
||||
$event->repeats,
|
||||
$event->color,
|
||||
$event->ID,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
84
app/plugins/calendar/plugin.php
Normal file
84
app/plugins/calendar/plugin.php
Normal file
@ -0,0 +1,84 @@
|
||||
<?php
|
||||
/**
|
||||
* app/plugins/calendar/plugin.php
|
||||
*
|
||||
* This houses all of the main plugin info and functionality.
|
||||
*
|
||||
* @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\Plugins;
|
||||
|
||||
use TheTempusProject\Classes\Plugin;
|
||||
use TheTempusProject\Models\Events;
|
||||
use TheTempusProject\Models\Calendars;
|
||||
use TheTempusProject\Houdini\Classes\Components;
|
||||
use TheTempusProject\Houdini\Classes\Template;
|
||||
|
||||
class Calendar extends Plugin {
|
||||
public $pluginName = 'TP Calendar';
|
||||
public $configName = 'calendar';
|
||||
public $pluginAuthor = 'JoeyK';
|
||||
public $pluginWebsite = 'https://TheTempusProject.com';
|
||||
public $modelVersion = '1.0';
|
||||
public $pluginVersion = '3.0';
|
||||
public $pluginDescription = 'A simple plugin which adds a site wide calendar system.';
|
||||
public $permissionMatrix = [
|
||||
'useCalendar' => [
|
||||
'pretty' => 'Can use the calendar feature',
|
||||
'default' => false,
|
||||
],
|
||||
'createEvents' => [
|
||||
'pretty' => 'Can add events to calendars',
|
||||
'default' => false,
|
||||
],
|
||||
];
|
||||
public $main_links = [
|
||||
[
|
||||
'text' => 'Calendar',
|
||||
'url' => '{ROOT_URL}calendar/index',
|
||||
'filter' => 'loggedin',
|
||||
],
|
||||
];
|
||||
public $configMatrix = [
|
||||
'enabled' => [
|
||||
'type' => 'radio',
|
||||
'pretty' => 'Enable Calendar.',
|
||||
'default' => true,
|
||||
],
|
||||
];
|
||||
public $preferenceMatrix = [
|
||||
'calendarPreference' => [
|
||||
'pretty' => 'Default Calendar View',
|
||||
'type' => 'select',
|
||||
'default' => 'byMonth',
|
||||
'options' => [
|
||||
'Daily' => 'byDay',
|
||||
'Weekly' => 'byWeek',
|
||||
'Monthly' => 'byMonth',
|
||||
'Yearly' => 'byYear',
|
||||
'All Events' => 'events',
|
||||
],
|
||||
],
|
||||
'weekStart' => [
|
||||
'pretty' => 'First day of the week for the Calendar',
|
||||
'type' => 'select',
|
||||
'default' => 'sunday',
|
||||
'options' => [
|
||||
'Sunday' => '6',
|
||||
'Monday' => '7',
|
||||
],
|
||||
],
|
||||
];
|
||||
public $events;
|
||||
public $calendars;
|
||||
|
||||
public function __construct( $load = false ) {
|
||||
$this->events = new Events;
|
||||
$this->calendars = new Calendars;
|
||||
parent::__construct( $load );
|
||||
}
|
||||
}
|
41
app/plugins/calendar/templates/calendar.inc.php
Normal file
41
app/plugins/calendar/templates/calendar.inc.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
/**
|
||||
* app/plugins/blog/templates/blog.inc.php
|
||||
*
|
||||
* This is the loader for the blog template.
|
||||
*
|
||||
* @package TP Blog
|
||||
* @version 3.0
|
||||
* @author Joey Kimsey <Joey@thetempusproject.com>
|
||||
* @link https://TheTempusProject.com
|
||||
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
|
||||
*/
|
||||
namespace TheTempusProject\Templates;
|
||||
|
||||
use TheTempusProject\Plugins\Calendar;
|
||||
|
||||
use TheTempusProject\Houdini\Classes\Components;
|
||||
use TheTempusProject\Houdini\Classes\Navigation;
|
||||
use TheTempusProject\Houdini\Classes\Views;
|
||||
use TheTempusProject\Houdini\Classes\Template;
|
||||
use TheTempusProject\Bedrock\Functions\Input;
|
||||
use TheTempusProject\Models\Events;
|
||||
use TheTempusProject\Models\Calendars;
|
||||
|
||||
class CalendarLoader extends DefaultLoader {
|
||||
/**
|
||||
* This is the function used to generate any components that may be
|
||||
* needed by this template.
|
||||
*/
|
||||
public function __construct() {
|
||||
$events = new Events;
|
||||
$calendars = new Calendars;
|
||||
Navigation::setCrumbComponent( 'CALENDAR_BREADCRUMBS', Input::get( 'url' ) );
|
||||
Components::set( 'todaysDate', date( 'F d, Y', time()) );
|
||||
Components::set( 'currentDay', date( 'F d, Y', time()) );
|
||||
Components::set( 'weekOf', 'Week of ' . date( 'F d, Y', strtotime( 'this week' ) ) );
|
||||
Components::set( 'year', date( 'Y', time() ));
|
||||
Components::set( 'month', date( 'F', time() ));
|
||||
parent::__construct();
|
||||
}
|
||||
}
|
96
app/plugins/calendar/templates/calendar.tpl
Normal file
96
app/plugins/calendar/templates/calendar.tpl
Normal file
@ -0,0 +1,96 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<!--
|
||||
* app/plugins/calendar/templates/calendar.tpl
|
||||
*
|
||||
* @package TP Calendar
|
||||
* @version 3.0
|
||||
* @author Joey Kimsey <Joey@thetempusproject.com>
|
||||
* @link https://TheTempusProject.com
|
||||
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta property="og:url" content="{CURRENT_URL}">
|
||||
<meta name='twitter:card' content='summary' />
|
||||
<title>{TITLE}</title>
|
||||
<meta itemprop="name" content="{TITLE}">
|
||||
<meta name="twitter:title" content="{TITLE}">
|
||||
<meta property="og:title" content="{TITLE}">
|
||||
<meta name="description" content="{PAGE_DESCRIPTION}">
|
||||
<meta itemprop="description" content="{PAGE_DESCRIPTION}">
|
||||
<meta name="twitter:description" content="{PAGE_DESCRIPTION}">
|
||||
<meta property="og:description" content="{PAGE_DESCRIPTION}">
|
||||
<meta itemprop="image" content="{META_IMAGE}">
|
||||
<meta name="twitter:image" content="{META_IMAGE}">
|
||||
<meta property="og:image" content="{META_IMAGE}">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="author" content="The Tempus Project">
|
||||
{ROBOT}
|
||||
<link rel="alternate" hreflang="en-us" href="alternateURL">
|
||||
<link rel="icon" href="{ROOT_URL}images/favicon.ico">
|
||||
<!-- Required CSS -->
|
||||
<link rel="stylesheet" href="{FONT_AWESOME_URL}font-awesome.min.css" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="{BOOTSTRAP_CDN}css/bootstrap-theme.min.css" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="{BOOTSTRAP_CDN}css/bootstrap.min.css" crossorigin="anonymous">
|
||||
<!-- RSS -->
|
||||
<link rel="alternate" href="{ROOT_URL}blog/rss" title="{TITLE} Feed" type="application/rss+xml" />
|
||||
<!-- Custom styles for this template -->
|
||||
{TEMPLATE_CSS_INCLUDES}
|
||||
<link rel="stylesheet" href="{ROOT_URL}app/plugins/calendar/css/calendar.css" />
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar navbar-inverse navbar-fixed-top" role="navigation">
|
||||
<!--Brand and toggle should get grouped for better mobile display -->
|
||||
<div class="navbar-header">
|
||||
<a href="{ROOT_URL}" class="navbar-brand">{SITENAME}</a>
|
||||
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-ex1-collapse" style="">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="container-fluid">
|
||||
<div class="collapse navbar-collapse navbar-ex1-collapse">
|
||||
{topNavLeft}
|
||||
<div class="navbar-right">
|
||||
<ul class="nav navbar-nav">
|
||||
{topNavRight}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="container-fluid">
|
||||
<div class="foot-pad">
|
||||
{ISSUES}
|
||||
<div class="row">
|
||||
<div class="container">
|
||||
{ERROR}
|
||||
{NOTICE}
|
||||
{SUCCESS}
|
||||
</div>
|
||||
</div>
|
||||
{/ISSUES}
|
||||
<div class="row">
|
||||
<div class="container-fluid calendar-container">
|
||||
<div class="row">
|
||||
{CalendarNav}
|
||||
{CONTENT}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<footer>
|
||||
{COPY}
|
||||
</footer>
|
||||
<!-- Bootstrap core JavaScript and jquery -->
|
||||
<script src="{JQUERY_CDN}jquery.min.js" crossorigin="anonymous"></script>
|
||||
<script src="{BOOTSTRAP_CDN}js/bootstrap.min.js" crossorigin="anonymous"></script>
|
||||
<!-- Custom javascript for this template -->
|
||||
{TEMPLATE_JS_INCLUDES}
|
||||
</body>
|
||||
</html>
|
25
app/plugins/calendar/views/byDay.html
Normal file
25
app/plugins/calendar/views/byDay.html
Normal file
@ -0,0 +1,25 @@
|
||||
<h2 class="pull-left">
|
||||
<a href="{ROOT_URL}calendar/byDay/{calendarID}?day={lastDay}&month={lastDayMonth}" role="button" class="btn btn-primary">
|
||||
<i class="glyphicon glyphicon-chevron-left"></i>
|
||||
</a>
|
||||
<span class="dateDayContainer">{activeDate}</span>
|
||||
<a href="{ROOT_URL}calendar/byDay/{calendarID}?day={nextDay}&month={nextDayMonth}" role="button" class="btn btn-primary">
|
||||
<i class="glyphicon glyphicon-chevron-right"></i>
|
||||
</a>
|
||||
</h2>
|
||||
{dateDropdown}
|
||||
<div class="container-fluid">
|
||||
{LOOP}
|
||||
<div class="hour-row{hourSelected}">
|
||||
<h2 class="hour-header">{hour}:00</h2>
|
||||
{EventCells}
|
||||
<span class="hour-footer">
|
||||
<a href="{ROOT_URL}calendar/createEvent?calendar_id={calendarID}&hour={hour}&day={day}" class="btn btn-sm btn-success" role="button"><i class="glyphicon glyphicon-plus"></i></a>
|
||||
</span>
|
||||
</div>
|
||||
{/LOOP}
|
||||
{ALT}
|
||||
<div class="hour-row{hourSelected}">
|
||||
</div>
|
||||
{/ALT}
|
||||
</div>
|
34
app/plugins/calendar/views/byMonth.html
Normal file
34
app/plugins/calendar/views/byMonth.html
Normal file
@ -0,0 +1,34 @@
|
||||
<h2 class="pull-left">
|
||||
<a href="{ROOT_URL}calendar/byMonth/{calendarID}?month={lastMonth}&year={lastMonthYear}" role="button" class="btn btn-primary">
|
||||
<i class="glyphicon glyphicon-chevron-left"></i>
|
||||
</a>
|
||||
<span class="dateMonthContainer">{dateMonth}</span>
|
||||
<a href="{ROOT_URL}calendar/byMonth/{calendarID}?month={nextMonth}&year={nextMonthYear}" role="button" class="btn btn-primary">
|
||||
<i class="glyphicon glyphicon-chevron-right"></i>
|
||||
</a>
|
||||
</h2>
|
||||
{dateDropdown}
|
||||
<div class="container-fluid">
|
||||
<!-- Header -->
|
||||
<div class="row calendar-row">
|
||||
<div class="col-xs-1 calendar-cell"><h4>Sunday</h4></div>
|
||||
<div class="col-xs-1 calendar-cell"><h4>Monday</h4></div>
|
||||
<div class="col-xs-1 calendar-cell"><h4>Tuesday</h4></div>
|
||||
<div class="col-xs-1 calendar-cell"><h4>Wednesday</h4></div>
|
||||
<div class="col-xs-1 calendar-cell"><h4>Thursday</h4></div>
|
||||
<div class="col-xs-1 calendar-cell"><h4>Friday</h4></div>
|
||||
<div class="col-xs-1 calendar-cell"><h4>Saturday</h4></div>
|
||||
</div>
|
||||
<!-- Week 1 -->
|
||||
{week1Element}
|
||||
<!-- Week 2 -->
|
||||
{week2Element}
|
||||
<!-- Week 3 -->
|
||||
{week3Element}
|
||||
<!-- Week 4 -->
|
||||
{week4Element}
|
||||
<!-- Week 5 -->
|
||||
{week5Element}
|
||||
<!-- Week 6 -->
|
||||
{week6Element}
|
||||
</div>
|
25
app/plugins/calendar/views/byWeek.html
Normal file
25
app/plugins/calendar/views/byWeek.html
Normal file
@ -0,0 +1,25 @@
|
||||
|
||||
<h2 class="pull-left">
|
||||
<a href="{ROOT_URL}calendar/byWeek/{calendarID}?month={lastWeekMonth}&day={lastWeek}&year={lastYear}" role="button" class="btn btn-primary">
|
||||
<i class="glyphicon glyphicon-chevron-left"></i>
|
||||
</a>
|
||||
<span class="dateWeekContainer">{dateWeek}</span>
|
||||
<a href="{ROOT_URL}calendar/byWeek/{calendarID}?month={nextWeekMonth}&day={nextWeek}&year={nextYear}" role="button" class="btn btn-primary">
|
||||
<i class="glyphicon glyphicon-chevron-right"></i>
|
||||
</a>
|
||||
</h2>
|
||||
{dateDropdown}
|
||||
<div class="container-fluid">
|
||||
<!-- Header -->
|
||||
<div class="row calendar-row">
|
||||
<div class="col-xs-1 calendar-cell"><h4>Sunday</h4></div>
|
||||
<div class="col-xs-1 calendar-cell"><h4>Monday</h4></div>
|
||||
<div class="col-xs-1 calendar-cell"><h4>Tuesday</h4></div>
|
||||
<div class="col-xs-1 calendar-cell"><h4>Wednesday</h4></div>
|
||||
<div class="col-xs-1 calendar-cell"><h4>Thursday</h4></div>
|
||||
<div class="col-xs-1 calendar-cell"><h4>Friday</h4></div>
|
||||
<div class="col-xs-1 calendar-cell"><h4>Saturday</h4></div>
|
||||
</div>
|
||||
<!-- Week 1 -->
|
||||
{week1Element}
|
||||
</div>
|
42
app/plugins/calendar/views/byYear.html
Normal file
42
app/plugins/calendar/views/byYear.html
Normal file
@ -0,0 +1,42 @@
|
||||
<h2 class="pull-left">
|
||||
<a href="{ROOT_URL}calendar/byYear/{calendarID}?year={lastYear}" role="button" class="btn btn-primary">
|
||||
<i class="glyphicon glyphicon-chevron-left"></i>
|
||||
</a>
|
||||
<span class="dateYearContainer">{dateYear}</span>
|
||||
<a href="{ROOT_URL}calendar/byYear/{calendarID}?year={nextYear}" role="button" class="btn btn-primary">
|
||||
<i class="glyphicon glyphicon-chevron-right"></i>
|
||||
</a>
|
||||
</h2>
|
||||
{dateDropdown}
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 10%">ID</th>
|
||||
<th style="width: 20%">Time</th>
|
||||
<th style="width: 40%">Title</th>
|
||||
<th style="width: 10%"></th>
|
||||
<th style="width: 10%"></th>
|
||||
<th style="width: 10%"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{LOOP}
|
||||
<tr>
|
||||
<td style="text-align: center;">{ID}</td>
|
||||
<td style="text-align: center;">{DTC}{event_time}{/DTC}</td>
|
||||
<td style="text-align: center;">{title}</td>
|
||||
<td><a href="{ROOT_URL}calendar/event/{ID}" class="btn btn-sm btn-primary" role="button"><i class="glyphicon glyphicon-open"></i></a></td>
|
||||
<td><a href="{ROOT_URL}calendar/editEvent/{ID}" class="btn btn-sm btn-warning" role="button"><i class="glyphicon glyphicon-edit"></i></a></td>
|
||||
<td><a href="{ROOT_URL}calendar/deleteEvent/{ID}" class="btn btn-sm btn-danger" role="button"><i class="glyphicon glyphicon-trash"></i></a></td>
|
||||
</tr>
|
||||
{/LOOP}
|
||||
{ALT}
|
||||
<tr>
|
||||
<td style="text-align: center;" colspan="6">
|
||||
No results to show.
|
||||
</td>
|
||||
</tr>
|
||||
{/ALT}
|
||||
</tbody>
|
||||
</table>
|
||||
<a href="{ROOT_URL}calendar/createEvent" class="btn btn-sm btn-primary" role="button">Create</a>
|
34
app/plugins/calendar/views/calendar/create.html
Normal file
34
app/plugins/calendar/views/calendar/create.html
Normal file
@ -0,0 +1,34 @@
|
||||
<legend>Create Calendar</legend>
|
||||
<form action="" method="post" class="form-horizontal">
|
||||
<input type="hidden" name="token" value="{TOKEN}">
|
||||
<div class="form-group">
|
||||
<label for="title" class="col-lg-3 control-label">Title</label>
|
||||
<div class="col-lg-3">
|
||||
<input type="text" class="form-control" name="title" id="title">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="description" class="col-lg-3 control-label">Description</label>
|
||||
<div class="col-lg-3">
|
||||
<textarea class="form-control" name="description" maxlength="2000" rows="10" cols="50" id="description"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="description" class="col-lg-3 control-label">Timezone</label>
|
||||
<div class="col-lg-3">
|
||||
{timezoneSelect}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="color" class="col-lg-3 control-label">Calendar Color</label>
|
||||
<div class="col-lg-3 select-container" id="colorContainer">
|
||||
{colorSelect}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="submit" class="col-lg-3 control-label"></label>
|
||||
<div class="col-lg-3">
|
||||
<button name="submit" value="submit" type="submit" class="btn btn-lg btn-primary center-block ">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
29
app/plugins/calendar/views/calendar/edit.html
Normal file
29
app/plugins/calendar/views/calendar/edit.html
Normal file
@ -0,0 +1,29 @@
|
||||
<legend>Edit Calendar</legend>
|
||||
<form action="" method="post" class="form-horizontal">
|
||||
<div class="form-group">
|
||||
<label for="title" class="col-lg-3 control-label">Title</label>
|
||||
<div class="col-lg-3">
|
||||
<input type="text" class="form-check-input form-control" name="title" id="title" value="{title}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="description" class="col-lg-3 control-label">Description</label>
|
||||
<div class="col-lg-6">
|
||||
<textarea class="form-control" name="description" maxlength="2000" rows="10" cols="50" id="description">{description}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="description" class="col-lg-3 control-label">Timezone</label>
|
||||
<div class="col-lg-3">
|
||||
{timezoneSelect}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="color" class="col-lg-3 control-label">Calendar Color</label>
|
||||
<div class="col-lg-3 select-container" id="colorContainer">
|
||||
{colorSelect}
|
||||
</div>
|
||||
</div>
|
||||
<input type="hidden" name="token" value="{TOKEN}">
|
||||
<button name="submit" value="submit" type="submit" class="btn btn-lg btn-primary center-block">Submit</button>
|
||||
</form>
|
45
app/plugins/calendar/views/calendar/list.html
Normal file
45
app/plugins/calendar/views/calendar/list.html
Normal file
@ -0,0 +1,45 @@
|
||||
<legend>Calendars</legend>
|
||||
<form action="{ROOT_URL}calendar/deleteCalendar" method="post">
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 5%">ID</th>
|
||||
<th style="width: 20%">Title</th>
|
||||
<th style="width: 50%">Description</th>
|
||||
<th style="width: 5%"></th>
|
||||
<th style="width: 5%"></th>
|
||||
<th style="width: 5%"></th>
|
||||
<th style="width: 5%"></th>
|
||||
<th style="width: 5%">
|
||||
<input type="checkbox" onchange="checkAll(this)" name="check.br" value="CAL_[]"/>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{LOOP}
|
||||
<tr>
|
||||
<td align="center">{ID}</td>
|
||||
<td align="center">{title}</td>
|
||||
<td>{description}</td>
|
||||
<td><a href="{ROOT_URL}calendar/byMonth/{ID}" class="btn btn-sm btn-primary" role="button"><i class="glyphicon glyphicon-share-alt"></i></a></td>
|
||||
<td><a href="{ROOT_URL}calendar/calendar/{ID}" class="btn btn-sm btn-primary" role="button"><i class="glyphicon glyphicon-info-sign"></i></a></td>
|
||||
<td><a href="{ROOT_URL}calendar/editCalendar/{ID}" class="btn btn-sm btn-warning" role="button"><i class="glyphicon glyphicon-edit"></i></a></td>
|
||||
<td><a href="{ROOT_URL}calendar/deleteCalendar/{ID}" class="btn btn-sm btn-danger" role="button"><i class="glyphicon glyphicon-trash"></i></a></td>
|
||||
<td>
|
||||
<input type="checkbox" value="{ID}" name="CAL_[]">
|
||||
</td>
|
||||
</tr>
|
||||
{/LOOP}
|
||||
{ALT}
|
||||
<tr>
|
||||
<td align="center" colspan="7">
|
||||
No results to show.
|
||||
</td>
|
||||
</tr>
|
||||
{/ALT}
|
||||
</tbody>
|
||||
</table>
|
||||
<a href="{ROOT_URL}calendar/createCalendar" class="btn btn-sm btn-primary" role="button">Create</a>
|
||||
<button name="submit" value="submit" type="submit" class="btn btn-sm btn-danger">Delete</button>
|
||||
</form>
|
||||
<br />
|
42
app/plugins/calendar/views/calendar/view.html
Normal file
42
app/plugins/calendar/views/calendar/view.html
Normal file
@ -0,0 +1,42 @@
|
||||
<div class="container col-md-4 col-lg-4">
|
||||
<div class="row">
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">Calendar</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="row">
|
||||
<div class="">
|
||||
<table class="table table-user-primary">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td align="left" width="200"><b>Title</b></td>
|
||||
<td align="right">{title}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Created</b></td>
|
||||
<td align="right">{DTC}{createdAt}{/DTC}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" colspan="2"><b>Description</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">{description}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>TimeZone</b></td>
|
||||
<td align="right">{timezone}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-footer">
|
||||
<a href="{ROOT_URL}calendar/deleteCalendar/{ID}" class="btn btn-md btn-danger" role="button">Delete</a>
|
||||
<a href="{ROOT_URL}calendar/editCalendar/{ID}" class="btn btn-md btn-warning" role="button">Edit</a>
|
||||
<a href="{ROOT_URL}calendar/byMonth/{ID}" class="btn btn-md btn-primary" role="button">View Events</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
20
app/plugins/calendar/views/dateSelect.html
Normal file
20
app/plugins/calendar/views/dateSelect.html
Normal file
@ -0,0 +1,20 @@
|
||||
<div class="form-group">
|
||||
<label for="day" class="col-lg-3 control-label">All-Day Event</label>
|
||||
<div class="col-lg-3">
|
||||
<input class="" type="checkbox" name="allDay" id="allDay" value="true" {CHECKED:allDay=true}>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="month" class="col-lg-3 control-label">Event Start</label>
|
||||
<div class="col-lg-3">
|
||||
<input type="date" name="date" id="date" class="form-control" value="{date}" />
|
||||
<input type="time" name="time" id="time" class="form-control" value="{time}" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="month" class="col-lg-3 control-label">Event End</label>
|
||||
<div class="col-lg-3">
|
||||
<input type="date" name="endDate" id="endDate" class="form-control" value="{endDate}" />
|
||||
<input type="time" name="endTime" id="endTime" class="form-control" value="{endTime}" />
|
||||
</div>
|
||||
</div>
|
37
app/plugins/calendar/views/events/create.html
Normal file
37
app/plugins/calendar/views/events/create.html
Normal file
@ -0,0 +1,37 @@
|
||||
<legend>Create Event</legend>
|
||||
<form action="" method="post" class="form-horizontal">
|
||||
<input type="hidden" name="token" value="{TOKEN}">
|
||||
{calendarSelect}
|
||||
<div class="form-group">
|
||||
<label for="title" class="col-lg-3 control-label">Title</label>
|
||||
<div class="col-lg-3">
|
||||
<input type="text" class="form-control" name="title" id="title">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="description" class="col-lg-3 control-label">Description</label>
|
||||
<div class="col-lg-3">
|
||||
<textarea class="form-control" name="description" maxlength="2000" rows="6" cols="30" id="description"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="location" class="col-lg-3 control-label">Location</label>
|
||||
<div class="col-lg-3">
|
||||
<input type="text" class="form-control" name="location" id="location">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="color" class="col-lg-3 control-label">Event Color</label>
|
||||
<div class="col-lg-3 select-container" id="colorContainer">
|
||||
{colorSelect}
|
||||
</div>
|
||||
</div>
|
||||
{dateSelect}
|
||||
{repeatSelect}
|
||||
<div class="form-group">
|
||||
<label for="submit" class="col-lg-3 control-label"></label>
|
||||
<div class="col-lg-3">
|
||||
<button name="submit" value="submit" type="submit" class="btn btn-lg btn-primary center-block">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
31
app/plugins/calendar/views/events/edit.html
Normal file
31
app/plugins/calendar/views/events/edit.html
Normal file
@ -0,0 +1,31 @@
|
||||
<legend>Edit Event</legend>
|
||||
<form action="" method="post" class="form-horizontal">
|
||||
<div class="form-group">
|
||||
<label for="title" class="col-lg-3 control-label">Title</label>
|
||||
<div class="col-lg-3">
|
||||
<input type="text" class="form-control" name="title" id="title" value="{title}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="description" class="col-lg-3 control-label">Description</label>
|
||||
<div class="col-lg-6">
|
||||
<textarea class="form-control" name="description" maxlength="2000" rows="10" cols="50" id="description">{description}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="location" class="col-lg-3 control-label">Location</label>
|
||||
<div class="col-lg-6">
|
||||
<input type="text" class="form-control" name="location" id="location" value="{location}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="color" class="col-lg-3 control-label">Event Color</label>
|
||||
<div class="col-lg-3 select-container" id="colorContainer">
|
||||
{colorSelect}
|
||||
</div>
|
||||
</div>
|
||||
{dateSelect}
|
||||
{repeatSelect}
|
||||
<input type="hidden" name="token" value="{TOKEN}">
|
||||
<button name="submit" value="submit" type="submit" class="btn btn-lg btn-primary center-block">Submit</button>
|
||||
</form>
|
34
app/plugins/calendar/views/events/list.html
Normal file
34
app/plugins/calendar/views/events/list.html
Normal file
@ -0,0 +1,34 @@
|
||||
{PAGINATION}
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 10%">ID</th>
|
||||
<th style="width: 20%">Time</th>
|
||||
<th style="width: 40%">Title</th>
|
||||
<th style="width: 10%"></th>
|
||||
<th style="width: 10%"></th>
|
||||
<th style="width: 10%"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{LOOP}
|
||||
<tr>
|
||||
<td style="text-align: center;">{ID}</td>
|
||||
<td style="text-align: center;">{DTC}{event_time}{/DTC}</td>
|
||||
<td style="text-align: center;">{title}</td>
|
||||
<td><a href="{ROOT_URL}calendar/event/{ID}" class="btn btn-sm btn-primary" role="button"><i class="glyphicon glyphicon-open"></i></a></td>
|
||||
<td><a href="{ROOT_URL}calendar/editEvent/{ID}" class="btn btn-sm btn-warning" role="button"><i class="glyphicon glyphicon-edit"></i></a></td>
|
||||
<td><a href="{ROOT_URL}calendar/deleteEvent/{ID}" class="btn btn-sm btn-danger" role="button"><i class="glyphicon glyphicon-trash"></i></a></td>
|
||||
</tr>
|
||||
{/LOOP}
|
||||
{ALT}
|
||||
<tr>
|
||||
<td style="text-align: center;" colspan="6">
|
||||
No results to show.
|
||||
</td>
|
||||
</tr>
|
||||
{/ALT}
|
||||
</tbody>
|
||||
</table>
|
||||
{PAGINATION}
|
||||
<a href="{ROOT_URL}calendar/createEvent" class="btn btn-sm btn-primary" role="button">Create</a>
|
52
app/plugins/calendar/views/events/view.html
Normal file
52
app/plugins/calendar/views/events/view.html
Normal file
@ -0,0 +1,52 @@
|
||||
<div class="container col-md-4 col-lg-4">
|
||||
<div class="row">
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">Event</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="row">
|
||||
<table class="table table-user-primary">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="text-align: left;" width="200"><b>Title</b></td>
|
||||
<td style="text-align: right;">{title}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Created</b></td>
|
||||
<td style="text-align: right;">{DTC}{createdAt}{/DTC}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Event Time</b></td>
|
||||
<td style="text-align: right;">{DTC}{event_time}{/DTC}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;" colspan="2"><b>Description</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">{description}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Location</b></td>
|
||||
<td style="text-align: right;">{location}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Frequency</b></td>
|
||||
<td style="text-align: right;">{repeatsText}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Calendar</b></td>
|
||||
<td style="text-align: right;">{calendarName}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-footer">
|
||||
<a href="{ROOT_URL}calendar/deleteEvent/{ID}" class="btn btn-md btn-danger" role="button">Delete</a>
|
||||
<a href="{ROOT_URL}calendar/editEvent/{ID}" class="btn btn-md btn-warning" role="button">Edit</a>
|
||||
<a href="{ROOT_URL}calendar/byMonth/{calendar_id}" class="btn btn-md btn-primary" role="button">View Events</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
16
app/plugins/calendar/views/nav/calendarDropdown.html
Normal file
16
app/plugins/calendar/views/nav/calendarDropdown.html
Normal file
@ -0,0 +1,16 @@
|
||||
<li class="pull-right dropdown">
|
||||
<button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
Calendars <span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="{ROOT_URL}calendar/{currentView}/">All</a></li>
|
||||
<li role="separator" class="divider"></li>
|
||||
{LOOP}
|
||||
<li><a href="{ROOT_URL}calendar/{currentView}/{ID}">{title}</a></li>
|
||||
{/LOOP}
|
||||
<li role="separator" class="divider"></li>
|
||||
<li><a href="{ROOT_URL}calendar/createCalendar">Create Calendar</a></li>
|
||||
<li><a href="{ROOT_URL}calendar/editCalendar/{calendarID}">Edit Calendar</a></li>
|
||||
<li><a href="{ROOT_URL}calendar/deleteCalendar/{calendarID}">Delete Calendar</a></li>
|
||||
</ul>
|
||||
</li>
|
23
app/plugins/calendar/views/nav/cell.html
Normal file
23
app/plugins/calendar/views/nav/cell.html
Normal file
@ -0,0 +1,23 @@
|
||||
<ul class="list-group">
|
||||
{LOOP}
|
||||
<li class="list-group-item btn-{displayColor}">
|
||||
<p style="text-align: center;">{title}</p>
|
||||
<p style="text-align: center;">{DTC}{event_time}{/DTC}</p>
|
||||
<p>
|
||||
<a href="{ROOT_URL}calendar/event/{ID}" class="btn btn-sm btn-primary" role="button"><i class="glyphicon glyphicon-open"></i></a>
|
||||
<a href="{ROOT_URL}calendar/editEvent/{ID}" class="btn btn-sm btn-warning" role="button"><i class="glyphicon glyphicon-edit"></i></a>
|
||||
<a href="{ROOT_URL}calendar/deleteEvent/{ID}" class="btn btn-sm btn-danger" role="button"><i class="glyphicon glyphicon-trash"></i></a>
|
||||
</p>
|
||||
</li>
|
||||
{/LOOP}
|
||||
{ALT}
|
||||
<li class="list-group-item">
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
</li>
|
||||
{/ALT}
|
||||
<a href="{ROOT_URL}calendar/createEvent?calendar_id={calendarID}&month={currentMonth}&day={currentDay}" class="list-group-item list-group-item-success"><i class="glyphicon glyphicon-plus"></i></a>
|
||||
</ul>
|
18
app/plugins/calendar/views/nav/dateDropdown.html
Normal file
18
app/plugins/calendar/views/nav/dateDropdown.html
Normal file
@ -0,0 +1,18 @@
|
||||
<ul class="nav nav-pills">
|
||||
<li class="dropdown pull-right">
|
||||
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
Switch Date <span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<form action="" method="post" class="form-horizontal">
|
||||
<li><input type="date" name="date" id="date" class="form-control" value="{date}" /></li>
|
||||
<li role="separator" class="divider"></li>
|
||||
<li>
|
||||
<button name="submit" value="submit" type="submit" class="btn btn-primary center-block">
|
||||
Select Date
|
||||
</button>
|
||||
</li>
|
||||
</form>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
12
app/plugins/calendar/views/nav/row.html
Normal file
12
app/plugins/calendar/views/nav/row.html
Normal file
@ -0,0 +1,12 @@
|
||||
<span class="hour-body">
|
||||
{LOOP}
|
||||
<div class="hour-cell btn-{displayColor}">
|
||||
<p class="event-title">{title}</p>
|
||||
<a href="{ROOT_URL}calendar/event/{ID}" class="btn btn-sm btn-primary" role="button"><i class="glyphicon glyphicon-open"></i></a>
|
||||
<a href="{ROOT_URL}calendar/editEvent/{ID}" class="btn btn-sm btn-warning" role="button"><i class="glyphicon glyphicon-edit"></i></a>
|
||||
<a href="{ROOT_URL}calendar/deleteEvent/{ID}" class="btn btn-sm btn-danger" role="button"><i class="glyphicon glyphicon-trash"></i></a>
|
||||
</div>
|
||||
{/LOOP}
|
||||
{ALT}
|
||||
{/ALT}
|
||||
</span>
|
8
app/plugins/calendar/views/nav/topTabs.html
Normal file
8
app/plugins/calendar/views/nav/topTabs.html
Normal file
@ -0,0 +1,8 @@
|
||||
<ul class="nav nav-tabs">
|
||||
<li><a href="{ROOT_URL}calendar/byDay/{calendarID}">Daily</a></li>
|
||||
<li><a href="{ROOT_URL}calendar/byWeek/{calendarID}">Weekly</a></li>
|
||||
<li><a href="{ROOT_URL}calendar/byMonth/{calendarID}">Monthly</a></li>
|
||||
<li><a href="{ROOT_URL}calendar/byYear/{calendarID}">Yearly</a></li>
|
||||
<li><a href="{ROOT_URL}calendar/events/{calendarID}">Events</a></li>
|
||||
{calendarDropdown}
|
||||
</ul>
|
9
app/plugins/calendar/views/nav/week.html
Normal file
9
app/plugins/calendar/views/nav/week.html
Normal file
@ -0,0 +1,9 @@
|
||||
<div class="row calendar-row">
|
||||
{LOOP}
|
||||
<div class="col-xs-1 calendar-cell">
|
||||
<h4 class="{highlightedDate}">{day}</h4>{dayEventList}
|
||||
</div>
|
||||
{/LOOP}
|
||||
{ALT}
|
||||
{/ALT}
|
||||
</div>
|
Reference in New Issue
Block a user