Created
February 4, 2015 07:05
-
-
Save b4oshany/26966b8673d081d8c7d8 to your computer and use it in GitHub Desktop.
Full Calendar
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace libs\schedule; | |
require_once "setup.php"; | |
use libs\vecni\Vecni; | |
use libs\mongodb\Model; | |
use libs\user\User; | |
use libs\location\Location; | |
use libs\schedule\Event; | |
class Calendar extends Model{ | |
# Basic calendars information, | |
public $title; // Title of the calendar. | |
public $description; // Description of the calendar. | |
public $creator; // Creator of the calendar. | |
public static $collection = "calendar"; // name of collection to be used | |
/** | |
* __callstatic is triggered when invoking inaccessible methods in an static context | |
* This method will initiate the mongodb connection and select the desired database | |
* In addition, it will initiate the collection model for the user data. | |
*/ | |
public static function setUp(){ | |
parent::setUp(); | |
$collection = self::$collection; | |
self::$model = self::$mongodb->$collection; | |
} | |
/** | |
* Set the collection settings for monogodb | |
* such as the unique attributes in the collection | |
*/ | |
public static function collectionSettings(){ | |
self::$mongodb->calendar->createIndex( | |
array("title"=>1, | |
"creator"=>1 | |
), | |
array("unique"=>1) | |
); | |
} | |
/** | |
* Create a new calendar | |
* @param mixed $title - calendar title | |
* @param mixed $description - calendar description | |
* @return Event - event obejct with the start time, title and description attached to it | |
*/ | |
public static function create($title, $description=""){ | |
# create a new event object and set the values of the title, description and start time | |
$new_cal = new self(); | |
$new_cal->title = $title; | |
$new_cal->description = $description; | |
$date = new \DateTime('NOW'); | |
$new_cal->date_created = $date; | |
$new_cal->creator = User::get_current_user_db()->get_MongoId(); | |
$new_cal->save(); | |
return $new_cal; | |
} | |
/** | |
* Set the duration of the event | |
* @param mixed $duration duration of the event which will determine the end time | |
* @return Event - new created event | |
*/ | |
public function create_event($title, \DateTime $start_time, $description){ | |
$new_event = Event::create($title, $start_time, $description); | |
$new_event->default_calendar = $this->get_MongoId(); | |
$new_event->subscribe_calendar[0] = $this->get_MongoId(); | |
$new_event->save(); | |
return $new_event; | |
} | |
public function get_month_events(\DateTime $from = null, \DateTime $to = null){ | |
if(!isset($from)){ | |
$from = new \DateTime('NOW'); | |
} | |
$from->sub(new \DateInterval('P1M')); | |
if(!isset($to)){ | |
$to = clone $from; | |
$to->add(new \DateInterval('P3M')); | |
} | |
return Event::find(array( | |
'$or'=>array( | |
array( | |
"subscribe_calendar"=>array( | |
'$all'=>array($this->get_MongoId()) | |
) | |
), | |
array("default_calendar"=>$this->get_MongoId()) | |
), | |
"start_time.date" =>array( | |
'$gte'=>$from->format("Y-m-d H:i:s"), | |
'$lte'=>$to->format("Y-m-d H:i:s") | |
) | |
)); | |
} | |
public function get_calendar_events(\DateTime $from = null, \DateTime $to = null){ | |
$events = $this->get_month_events($from, $to); | |
$calendar_format = array(); | |
foreach($events as $event){ | |
array_push($calendar_format, $event->get_calendar_format()); | |
} | |
return $calendar_format; | |
} | |
public function get_event($event_id){ | |
$event_object_id = self::create_MongoId($event_id); | |
$event = Event::find_one(array( | |
"_id"=>$event_object_id, | |
"subscribe_calendar"=>array( | |
'$all'=>array($this->get_MongoId()) | |
) | |
)); | |
if(isset($event)){ | |
return $event; | |
} | |
return null; | |
} | |
/** | |
* Calculate the ending time of the event based on the duration and start time | |
* @return date end time of the event | |
*/ | |
public function get_end_time(){ | |
$date = $this->start_time; | |
date_add($date, date_interval_create_from_date_string($this->duration)); | |
return $date; | |
} | |
/** | |
* Set the location of the event | |
* @param Location|string $venue - set the location of the venue, if Location, then there will be | |
* an associated location object with the event address and cordinates on map, else it's a stirng | |
* that will be displayed | |
*/ | |
public function change_venue($venue = " "){ | |
if($venue instanceof Location || $venue instanceof string){ | |
$this->venue = $venue; | |
}else{ | |
throw new \Exception("Incorrect type, venue must be a Location object or String"); | |
} | |
} | |
} | |
Calendar::setUp(); | |
Calendar::collectionSettings(); | |
?> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace libs\schedule; | |
require_once "setup.php"; | |
use libs\vecni\Vecni; | |
use libs\mongodb\Model; | |
use libs\mongodb\MongoIdRef; | |
use libs\user\User; | |
use libs\location\Location; | |
use libs\schedule\Calendar; | |
class Event extends Model{ | |
public static $collection = "event"; | |
# Basic event information | |
public $title; // title of the event | |
public $venue; // location of the event | |
public $description; // description of the event | |
public $start_time; // start time of the event | |
public $duration; // duration of the event which will determine the end time | |
public $recurrence_type; // type of recurrency event, such as hourly, daily, weekly, etc | |
public $end_date; // ending date for the recurrent event should stop | |
public $creator; // creator of the event | |
public $attendees; // attendees of the event | |
public $default_calendar; // main calendar | |
public $subscribe_calendar; | |
/** | |
* __callstatic is triggered when invoking inaccessible methods in an static context | |
* This method will initiate the mongodb connection and select the desired database | |
* In addition, it will initiate the collection model for the user data. | |
*/ | |
public static function setUp(){ | |
parent::setUp(); | |
$collection = self::$collection; | |
self::$model = self::$mongodb->$collection; | |
} | |
/** | |
* Set the collection settings for monogodb | |
* such as the unique attributes in the collection | |
*/ | |
public static function collectionSettings(){ | |
self::$mongodb->user->createIndex( | |
array("title"=>1, | |
"calendar"=>1, | |
"creator"=>1 | |
), | |
array("unique"=>1) | |
); | |
} | |
public function enforce_constraints(){ | |
$this->start_time = self::cast("DateTime", $this->start_time); | |
$this->duration = self::cast("DateInterval", $this->duration); | |
} | |
public function __construct(){ | |
$this->duration = new \DateInterval("PT1H"); | |
$this->subscribe_calendar = array(); | |
} | |
/** | |
* Create a new event | |
* @param mixed $title - event title | |
* @param mixed $description - event description | |
* @param date $start_time - the time which the event will start | |
* @return Event - event obejct with the start time, title and description attached to it | |
*/ | |
public static function create($title, \DateTime $start_time, $description=""){ | |
# create a new event object and set the values of the title, description and start time | |
$new_event = new self(); | |
$new_event->title = $title; | |
$new_event->description = $description; | |
$new_event->start_time = $start_time; | |
$new_event->creator = User::get_current_user_db()->get_MongoId(); | |
return $new_event; | |
} | |
/** | |
* Add a calendar that subscribes to this event. | |
* @param MongoId $calendar_ref - Calendar document ref. | |
* @return bool - true if the update is successful else false. | |
*/ | |
public function add_calendar_subscription(\MongoId $calendar_id){ | |
if($this->update(array( | |
'$addToSet'=>array('subscribe_calendar'=>$calendar_id) | |
))){ | |
return true; | |
} | |
return false; | |
} | |
/** | |
* Set the duration of the event, which is a DateInterval that will be used | |
* as the DateTime add method parameter | |
* @param int $hours - number of hours for the event duration | |
* @param int $mins - number of minutes for the event duration | |
* @param int $secs - number of seconds for the event duration | |
*/ | |
public function set_duration_time($hours = 0, $mins = 0, $secs = 0){ | |
$this->duration->h = $hours; // set duration hours | |
$this->duration->i = $mins; // set duration minutes | |
$this->duration->s = $secs; // set duration seconds | |
} | |
/** | |
* Calculate the ending time of the event based on the duration and start time | |
* @return DateTime - end time of the event | |
*/ | |
public function get_end_time(){ | |
$date = $this->start_time; | |
$date->add($this->duration); | |
return $date; | |
} | |
/** | |
* Set the location of the event | |
* @param Location|string $venue - set the location of the venue, if Location, then there will be | |
* an associated location object with the event address and cordinates on map, else it's a stirng | |
* that will be displayed | |
*/ | |
public function change_venue($venue = " "){ | |
if($venue instanceof Location || $venue instanceof string){ | |
$this->venue = $venue; | |
}else{ | |
throw new \Exception("Incorrect type, venue must be a Location object or String"); | |
} | |
} | |
/** | |
* Get a basic event summary for the calendar which includes, the title, description, | |
* start and end time of the event as well as the event creator name and id | |
* @return array - event data | |
*/ | |
public function get_calendar_format(){ | |
$event_data = array(); | |
$event_data["start"] = $this->start_time->format("c"); | |
$end_time = $this->get_end_time(); | |
$event_data["end"] = $end_time->format("c"); | |
$event_data["title"] = $this->title; | |
$event_data["description"] = $this->description; | |
$event_data["id"] = $this->id; | |
$user = User::find_one( | |
array("_id"=>$this->creator), | |
array("first_name", "last_namee") | |
); | |
$event_data["creator"] = array( | |
"name"=>"$user->first_name $user->last_name", | |
"id"=>"$user->id" | |
); | |
return $event_data; | |
} | |
} | |
Event::setUp(); | |
Event::collectionSettings(); | |
?> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var Schedule = function(){ | |
this.date = new Date; | |
this.d = this.date.getDate(), | |
this.m = this.date.getMonth(), | |
this.y = this.date.getFullYear(), | |
this.url = 'calendar/event', | |
this.curColor = "#00c0ef", | |
this.event_source = [ | |
// your event source | |
{ | |
url: this.url, // use the `url` property | |
color: 'yellow', // an option! | |
textColor: 'black', // an option! | |
cache: true | |
} | |
// any other sources... | |
], | |
/* initialize the external events | |
-----------------------------------------------------------------*/ | |
this.ini_events = function(ele) { | |
ele.each(function() { | |
// create an Event Object (http://arshaw.com/fullcalendar/docs/event_data/Event_Object/) | |
// it doesn't need to have a start or end | |
var eventObject = { | |
title: $.trim($(this).text()) // use the element's text as the event title | |
}; | |
// store the Event Object in the DOM element so we can get to it later | |
$(this).data('eventObject', eventObject); | |
// make the event draggable using jQuery UI | |
$(this).draggable({ | |
zIndex: 1070, | |
revert: true, // will cause the event to go back to its | |
revertDuration: 0 // original position after the drag | |
}); | |
}); | |
} | |
this.ini_calendar = function(){ | |
var schedule = this; | |
$('#calendar').fullCalendar({ | |
header: { | |
left: 'prev,next today', | |
center: 'title', | |
right: 'month,agendaWeek,agendaDay' | |
}, | |
buttonText: {//This is to add icons to the visible buttons | |
prev: "previous", | |
next: "next", | |
today: 'today', | |
month: 'month', | |
week: 'week', | |
day: 'day' | |
}, | |
dayClick: function(date, jsEvent, view ) { | |
$('#calendar').fullCalendar( 'changeView', "agendaDay"); | |
$('#calendar').fullCalendar( 'gotoDate', date); | |
}, | |
eventRender: function(event, element){ | |
element.attr("id", event.id); | |
}, | |
eventClick: function(calEvent, jsEvent, view) { | |
console.log(calid); | |
$.post("calendar/"+calid+"/event/"+calEvent.id, | |
function(data){ | |
$("#remote-modal .modal-content").html(data); | |
$("#remote-modal").modal('show'); | |
}); | |
}, | |
//Random default events | |
eventSources: schedule.event_source, | |
editable: true, | |
droppable: true, // this allows things to be dropped onto the calendar !!! | |
drop: function(date, allDay) { // this function is called when something is dropped | |
// retrieve the dropped element's stored Event Object | |
var originalEventObject = $(this).data('eventObject'); | |
// we need to copy it, so that multiple events don't have a reference to the same object | |
var copiedEventObject = $.extend({}, originalEventObject); | |
// assign it the date that was reported | |
copiedEventObject.start = date; | |
copiedEventObject.allDay = allDay; | |
copiedEventObject.backgroundColor = $(this).css("background-color"); | |
copiedEventObject.borderColor = $(this).css("border-color"); | |
// render the event on the calendar | |
// the last `true` argument determines if the event "sticks" (http://arshaw.com/fullcalendar/docs/event_rendering/renderEvent/) | |
$('#calendar').fullCalendar('renderEvent', copiedEventObject, true); | |
// is the "remove after drop" checkbox checked? | |
if ($('#drop-remove').is(':checked')) { | |
// if so, remove the element from the "Draggable Events" list | |
$(this).remove(); | |
} | |
} | |
}); | |
} | |
this.color_picker = function(){ | |
var schedule = this; | |
/* ADDING EVENTS */ | |
schedule.currColor = "#f56954"; //Red by default | |
//Color chooser button | |
var colorChooser = $("#color-chooser-btn"); | |
$("#color-chooser > li > a").click(function(e) { | |
e.preventDefault(); | |
//Save color | |
schedule.currColor = $(this).css("color"); | |
//Add color effect to button | |
colorChooser | |
.css({"background-color": schedule.currColor, "border-color": schedule.currColor}) | |
.html($(this).text()+' <span class="caret"></span>'); | |
}); | |
this.curr | |
} | |
this.add_event_onclick = function(){ | |
var schedule = this; | |
$(document).on("submit", "form[name=new_event]", function(e){ | |
e.preventDefault(); | |
$.post("calendar/event/create", $(this).serialize(), function(data){ | |
$('#calendar').fullCalendar('renderEvent', data, true); | |
flash_notification("Your event has been created", "success"); | |
}); | |
}); | |
} | |
} | |
$(function() { | |
var schedule = new Schedule(); | |
schedule.ini_events($('#external-events div.external-event')); | |
schedule.ini_calendar(); | |
schedule.color_picker(); | |
schedule.add_event_onclick(); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Request the addition of universities to Tattle Tale | |
*/ | |
Vecni::set_route("/calendar/create", "calendar_create"); | |
function calendar_create(){ | |
global $twig; | |
if(User::is_login()){ | |
if($title = Request::POST("calendar_title")){ | |
$calendar = Calendar::create($title); | |
if(Request::is_async()){ | |
return Response::json_response(200, $calendar->id); | |
} | |
Vecni::redirect("Vecni::$host/calendar/schedule?calid=$calendar->id"); | |
} | |
return $twig->render('calendar_create.html', | |
array( | |
"html_class"=>"calendar_create", | |
"title"=>"Create Calendar" | |
) | |
); | |
}else{ | |
return signin_require("You need to signin first, before you can add a university"); | |
} | |
} | |
/** | |
* Scheduling page for users | |
*/ | |
Vecni::set_route("/calendar/schedule", "view_schedule"); | |
function view_schedule($message=""){ | |
global $twig; | |
if(User::is_login()){ | |
$current_user = User::get_current_user_db(); | |
$calendar = $current_user->get_default_calendar(); | |
return $twig->render('scheduling.html', | |
array( | |
"html_class"=>"calendar_view", | |
"title"=>"Schedules", | |
"calendar"=>$calendar | |
) | |
); | |
}else{ | |
return signin_require("You need to signin first, before can view schedules"); | |
} | |
} | |
/** | |
* get events for the calendars | |
*/ | |
Vecni::set_route("/calendar/event", "get_events"); | |
function get_events(){ | |
if($cal_id = Request::GET("calid")){ | |
$calendar = Calendar::get_by_id($cal_id); | |
}else{ | |
$current_user = User::get_current_user_db(); | |
$calendar = $current_user->get_default_calendar(); | |
$events = $calendar->get_calendar_events(); | |
return Response::json_feed($events); | |
} | |
} | |
/* view events */ | |
Vecni::set_route("/calendar/{calendar_id}/event/{event_id}", "view_event"); | |
function view_event(){ | |
global $twig; | |
if(($cal_id = Request::GET("calendar_id")) && | |
($event_id = Request::GET("event_id")) | |
){ | |
$calendar = Calendar::get_by_id($cal_id); | |
$event = $calendar->get_event($event_id); | |
if(Request::is_async()){ | |
return $twig->render("bit/views/event_view.html", | |
array( | |
"event"=>$event, | |
"calendar"=>$calendar | |
) | |
); | |
}else{ | |
return $twig->render('bit/views/event_view.html', | |
array( | |
"event"=>$event, | |
"calendar"=>$calendar | |
) | |
); | |
} | |
} | |
return "No event found"; | |
} | |
/* view events */ | |
Vecni::set_route("/calendar/{calendar_id}/event/{event_id}/edit", "event_edit"); | |
function event_edit(){ | |
global $twig; | |
if(($cal_id = Request::GET("calendar_id")) && | |
($event_id = Request::GET("event_id")) | |
){ | |
$calendar = Calendar::get_by_id($cal_id); | |
$event = $calendar->get_event($event_id); | |
if(Request::is_async()){ | |
return $twig->render("bit/views/event_view.html", | |
array( | |
"event"=>$event, | |
"calendar"=>$calendar | |
) | |
); | |
}else{ | |
return $twig->render('bit/views/event_view.html', | |
array( | |
"event"=>$event, | |
"calendar"=>$calendar | |
) | |
); | |
} | |
} | |
} | |
/** | |
* get events for the calendars | |
*/ | |
Vecni::set_route("/calendar/event/create", "create_event"); | |
function create_event(){ | |
if(($start_time = Request::POST("event_start_time")) && | |
($title = Request::POST("event_title")) && | |
($start_date = Request::POST("event_start_date")) | |
){ | |
$description = Request::POST("event_description", ""); | |
$duration = "2 hours"; | |
$current_user = User::get_current_user_db(); | |
$calendar = $current_user->get_default_calendar(); | |
$date = DateTime::createFromFormat('G:i Y-m-d', | |
"$start_time $start_date"); | |
if($date){ | |
$event = $calendar->create_event($title, $date, $description); | |
if(!empty($event)){ | |
$event_data = $event->get_calendar_format(); | |
return Response::json_feed($event_data); | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace libs\vecni; | |
require_once "__autoload.php"; | |
require_once "Request.php"; | |
class Response{ | |
public static function init(){ | |
if(!isset($_SESSION["access_key"])){ | |
$_SESSION["access_key"] = uniqid('vecni_'); | |
} | |
} | |
public static function json_response($status_code=200, $message="ok"){ | |
header('Content-Type: application/json'); | |
return json_encode(array('status'=>$status_code, | |
'message'=>$message)); | |
} | |
public static function json_feed($message=""){ | |
header('Content-Type: application/json'); | |
return json_encode($message); | |
} | |
public static function abort($message = null){ | |
header("Connection: close", true); | |
if(!empty($message)){ | |
if(Request::is_async()){ | |
header("Message: $message"); | |
}else{ | |
echo $message; | |
} | |
} | |
header("HTTP/1.0 404 Not Found"); | |
} | |
} | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment