<?php
/***************************************************************************
* InfoFrame (image generator for digital picture frames)
* Copyright (C) 2009 Tobias Kolb
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses/
***************************************************************************/
class CalendarPlugin implements IPlugin
{
private $dbconn = NULL;
private $config = NULL;
public function __construct($dbconn, $config) {
$this->dbconn = $dbconn;
$this->config = $config;
}
public function doUpdate() {
require_once 'google-api-php-client/autoload.php';
session_start();
$client_id = $this->config['client_id'];
$service_account_name = $this->config['account_name'];
try {
$client = new Google_Client();
$client->setApplicationName($this->config['project_name']);
$service = new Google_Service_Calendar($client);
}
catch (Exception $e) {
die ('Folgender Fehler trat auf: ' . $e->getMessage());
}
if (isset($_SESSION['service_token']))
$client->setAccessToken($_SESSION['service_token']);
$key = file_get_contents($this->config['key_file']);
$cred = new Google_Auth_AssertionCredentials(
$service_account_name,
array('https://www.googleapis.com/auth/calendar'),
$key);
$client->setAssertionCredentials($cred);
if ($client->getAuth()->isAccessTokenExpired())
$client->getAuth()->refreshTokenWithAssertion($cred);
$_SESSION['service_token'] = $client->getAccessToken();
//set startDate, endDate, eventParams
$now = new DateTime('NOW');
$clone = clone $now;
$clone = date_modify($clone, '+1 month');
$startDate = date_format($now, DateTime::W3C);
$endDate = date_format($clone, DateTime::W3C);
$eventParams = array(
'timeMin' => $startDate,
'timeMax' => $endDate,
'singleEvents' => 'true');
//get Calendar Id´s
$calendarList = $service->calendarList->listCalendarList();
// Set begin of querys
$insertToken = "REPLACE INTO if_system (name, value) VALUES ";
$insertCalendarData = "INSERT INTO if_calendar (name,color,begin,end,title,location) VALUES ";
$deleteCalendarData = "DELETE FROM if_calendar WHERE ";
/******************** Update every given time without checking for SyncToken ************************/
$forceRefresh = $this->config['force_refresh'];
$updateCalendar = FALSE;
$query = "SELECT * FROM if_system WHERE name = 'CalendarUpdate'";
$result = mysqli_query($this->dbconn, $query);
if (mysqli_num_rows($result) > 0) {
$row = mysqli_fetch_assoc($result);
if ( ($row['name'] == 'CalendarUpdate') && ((time() - $row['value']) >= ($forceRefresh*3600)) ) {
$updateCalendar = TRUE;
$query = "REPLACE INTO if_system (name,value) VALUES ('CalendarUpdate', '".time()."')";
mysqli_query($this->dbconn, $query) or die('CalendarPlugin: '.mysqli_error());
}
}else{
$updateCalendar = TRUE;
$query = "INSERT INTO if_system (name,value) VALUES ('CalendarUpdate', '".time()."')";
mysqli_query($this->dbconn, $query) or die('CalendarPlugin: '.mysqli_error());
}
/*********************************************************************************************************/
$i = 0;
while(TRUE) {
/***************** Loop through each Calendar, get id, and color **************************/
foreach ($calendarList->getItems() as $calendarListEntry) {
$calendarID = $calendarListEntry->getID();
/***************** Get SysncToken to skip this calender at next update if nothing has changed **********/
$events = $service->events->listEvents($calendarID, $eventParams);
//If the syncToken expires, the server will respond with a 410 GONE response code and the client should clear its storage and perform a full synchronization without any syncToken
try{
$NextSyncToken = $events->getNextSyncToken();
}
catch (Exception $e) {
if (strripos($e->getMessage(), "410") !== FALSE){
$NextSyncToken = 'FEHLER';
}else{
die ('Folgender Fehler trat auf: ' . $e->getMessage());
}
}
$SyncToken = '';
//echo $NextSyncToken.PHP_EOL;
if ($updateCalendar == FALSE) {
$query = "SELECT value FROM if_system WHERE name = '".$calendarID."'";
$result = mysqli_query($this->dbconn, $query);
if (mysqli_num_rows($result) > 0) {
$row = mysqli_fetch_assoc($result);
$SyncToken = $row['value'];
}
}
$insertToken .= "('".$calendarID."','".$NextSyncToken."'), ";
/***************** SysncToken check done *****************************************************/
/**************** if SyncToken changed perform update ******************************/
if ($NextSyncToken != $SyncToken) {
$i++;
$deleteCalendarData .= "name='".$calendarListEntry->getSummary()."' OR ";
while(TRUE) {
/************************ Get content from each Calendar *****************/
foreach ($events->getItems() as $event) {
//print_r($event);
if (!empty($event['modelData']['start']['dateTime'])) {
$begin = date_format(date_create($event['modelData']['start']['dateTime']), 'Y-m-d H:i:s');
$end = date_format(date_create($event['modelData']['end']['dateTime']), 'Y-m-d H:i:s');
}else{
$begin = $event['modelData']['start']['date'];
$end = $event['modelData']['end']['date'];
}
$title = $event->getSummary();
$name = $event['modelData']['organizer']['displayName'];
$color = $event->getColorID();
$insertCalendarData .= "('".$name."','".$color."','".$begin."','".$end."','".$title."',''), ";
}
$pageToken = $events->getNextPageToken();
if ($pageToken) {
$optParams = array('pageToken' => $pageToken);
$events = $service->events->listEvents($calendarListEntry->getID(), $optParams);
}else{
break;
}
}
} /********** if SysncToken changed perform update END **********/
} /*********** Loop through each Calendar, get id, and color END *************************/
$pageToken = $calendarList->getNextPageToken();
if ($pageToken) {
$optParams = array('pageToken' => $pageToken);
$calendarList = $service->calendarList->listCalendarList($optParams);
}else{
break;
}
}
/***************************** if SyncToken changed perform SQL-statement *********************/
if ( $i > 0 ) {
mysqli_query($this->dbconn, $this->before_last('OR', $deleteCalendarData)) or die('CalendarPlugin -> insertCalendarData: '.mysqli_error());
mysqli_query($this->dbconn, $this->before_last(',', $insertToken)) or die('CalendarPlugin -> insertToken: '.mysqli_error());
mysqli_query($this->dbconn, $this->before_last(',', $insertCalendarData)) or die('CalendarPlugin -> insertCalendarData: '.mysqli_error());
}
}
public function doOutput($image, $style, $updateData, &$yoffset) {
if ($updateData)
$this->doUpdate();
$query = "SELECT * FROM `if_calendar`
WHERE `end` > NOW()
AND (`begin` <= ADDDATE(NOW(), INTERVAL ".$this->config['number_of_days']." DAY))
ORDER BY `begin` ASC";
$result = mysqli_query($this->dbconn, $query);
if (mysqli_num_rows($result) > 0) {
// define styles
$opt_header = array(
'width' => imagesx($image)-580,
'line_height' => 18,
'align' => ALIGN_LEFT
);
$opt_day = array(
'width' => imagesx($image)-580,
'height' => 14,
'line_height' => 14,
'align' => ALIGN_LEFT
);
$opt_entry = array(
'width' => imagesx($image)-580,
'height' => 12,
'line_height' => 12,
'align' => ALIGN_LEFT,
'word_wrap_hyphen' => '...',
'aggressive_word_wrap' => true,
);
$calendarColor = array ('#00008b', '#0000ff', '#48d1cc', '#ff00ff', '#ff4500',
'#ffff00', '#ffa500', '#00ffff', '#a9a9a9', '#00008b', '#008000', 'ff0000');
// print roundbox
$xleft = 5;
$xend = imagesx($image)-230;
$xoffset = 0;
$yoffset_diff = 8;
$yoffset_abstand = 7;
$titel_zeilen_hoehe = 14;
$tag_zeilen_hoehe = 4;
$inhalt_zeilen_hoehe = 13;
$inhalt_db_zeilen = mysqli_num_rows($result);
roundboxtrans_top($image, $xleft, $xend, $yoffset, $yoffset_diff, $yoffset_end, $radius, $titel_zeilen_hoehe);
// print header
imagettftextboxopt($image, 18, 0, 40, $yoffset, $style['textcolor'], $style['font'], "Nächste Termine", $opt_header);
$icon = ImageCreateFromPNG ( 'resources/icons/clock.png' );
ImageCopy($image, $icon, 10, $yoffset-3, 0, 0, imagesx($icon), imagesy($icon));
ImageDestroy($icon);
$yoffset += 26;
// print calendar
$counter = 0;
$formatDate = "%d.%m.%Y";
$formatTime = "%H:%M";
$today = strftime($formatDate);
$tomorrow = strftime($formatDate, strtotime("+1 day", time()));
$currently_displayed_day = 0;
while ($row = mysqli_fetch_assoc($result)) {
$counter++;
// if end of screen is reached and more than one items left -> cut off and show hint "x more appointments..."
$rest = (mysqli_num_rows($result) - $counter) + 1;
if (($yoffset >= (imagesy($image) - 36)) && ($rest > 1)) {
$text = "... $rest weitere Termine";
roundboxtrans_bottom($image, $xleft, $xend, $yoffset, $yoffset_diff, $yoffset_abstand-3, $yoffset_end, $radius, $bottom_zeilen_hoehe);
imagettftextboxopt($image, 14, 0, 24, $yoffset, $style['textcolor'], $style['fontb'], $text, $opt_entry);
$yoffset += 20;
break;
}
//roundboxtrans_middel($image, $xleft, $xend, $yoffset, $yoffset_abstand, $yoffset_end, $inhalt_zeilen_hoehe4);
// print day name
$begin_date = strftime($formatDate, strtotime($row['begin']));
// if begin day is before today set begin to today
if (strtotime($begin_date) < strtotime($today))
$begin_date = $today;
// now if begin is after $currently_displayed_day update $currently_displayed_day
if (strtotime($begin_date) > $currently_displayed_day) {
// update currently_displayed_day
$currently_displayed_day = strtotime($begin_date);
// print day name
if( $begin_date == $today ) $dayname = "Heute";
else if( $begin_date == $tomorrow ) $dayname = "Morgen";
else $dayname = strftime("%A, ".$formatDate, strtotime($begin_date));
if (isset($last_displayed_day) && ($last_displayed_day != $currently_displayed_day && $breite < 1 && $anzahl_letzter_text < 2) ) {
$breite += 1;
if($xoffset == 0) $xoffset += 77;
$xoffset += 15+strlen($letzter_text)*10;
$yoffset -= 45;
}else{
$xoffset = $breite = 0;
roundboxtrans_middel($image, $xleft, $xend, $yoffset, $yoffset_abstand, $yoffset_end, $tag_zeilen_hoehe);
}
imagettftextboxopt($image, 14, 0, $xoffset+45, $yoffset-3, $style['textcolor'], $style['fontb'], $dayname, $opt_day);
$yoffset += 18;
}
// build appointment time text
$end_date = strftime( $formatDate, strtotime($row['end']));
$begin_time = strftime( $formatTime, strtotime($row['begin']));
$end_time = strftime( $formatTime, strtotime($row['end']));
$text = $row['title'];
//if ($row['location'] != null)
//$text = $text . ", " . $row['location'];
if (($begin_time == "00:00") && ($end_time == "00:00")) {
// all day event (substract 1 second to get the real end date at 23:59)
$end_date = strftime( $formatDate, strtotime($row['end'])-1);
// if all day event is longer than one day -> print end date
if (strtotime($end_date) != $currently_displayed_day)
$text = $text." (bis ".$end_date.")";
}else{
// normal event with start and end time
$text = $text." (".$begin_time." - ";
// if event ends not this day -> display end date additionally to time
if (strtotime($end_date) != $currently_displayed_day)
$text = $text.$end_date.", ";
$text = $text.$end_time.")";
}
if (isset($last_event) && $last_event == $currently_displayed_day && $anzahl_letzter_text < 2) {
$anzahl_letzter_text += 1;
$xoffset += strlen($letzter_text)*10.8;
$yoffset -= 27;
}elseif ($breite < 1) {
$xoffset = 0;
$anzahl_letzter_text = 0;
roundboxtrans_middel($image, $xleft, $xend, $yoffset, $yoffset_abstand, $yoffset_end, $inhalt_zeilen_hoehe);
}
$calenderImage = FALSE;
// ------------------------------------------- Müllabfuhr----------------------------------------
if (($row['name']) == "Nan Di") {
if ($row['color'] == 1){
$icon = ImageCreateFromPNG ('resources/icons/tonne_blau.png');
$calenderImage = TRUE;
$xoffset = $xoffset+30;
$txoffset = $xoffset+20;
}elseif ($row['color'] == 4){
$icon = ImageCreateFromPNG ('resources/icons/schadstoffmobil.png');
$calenderImage = TRUE;
$xoffset = $xoffset+30;
$txoffset = $xoffset+20;
}elseif ($row['color'] == 5){
$icon = ImageCreateFromPNG ('resources/icons/gelber_sack.png');
$calenderImage = TRUE;
$xoffset = $xoffset+30;
$txoffset = $xoffset+20;
}elseif ($row['color'] == 8){
$icon = ImageCreateFromPNG ('resources/icons/tonne_schwarz.png');
$calenderImage = TRUE;
$xoffset = $xoffset+30;
$txoffset = $xoffset+20;
}elseif ($row['color'] == 10){
$icon = ImageCreateFromPNG ('resources/icons/tonne_gruen.png');
$calenderImage = TRUE;
$xoffset = $xoffset+30;
$txoffset = $xoffset+20;
}
// ------------------------------------------- Geburtstag ----------------------------------------
}elseif (($row['name']) == "Geburtstage") {
$icon = ImageCreateFromPNG ( 'resources/icons/birth.png' );
$calenderImage = TRUE;
$xoffset = $xoffset+30;
$txoffset = $xoffset+20;
// ------------------------------------------- Namenstag ----------------------------------------
}elseif (($row['name']) == "Namenstage") {
$icon = ImageCreateFromPNG ( 'resources/icons/name.png' );
$calenderImage = TRUE;
$xoffset = $xoffset+27;
$txoffset = $xoffset+23;
}
// ------------------------------------------- Standard - Button ----------------------------------------
if ($calenderImage == TRUE) {
ImageCopy($image, $icon, $xoffset, $yoffset+1, 0, 0, imagesx($icon), imagesy($icon));
ImageDestroy($icon);
}else{
$xoffset = $xoffset+36;
$txoffset = $xoffset+15;
// determine button color
$colorArray = htmlColorToRgb($calendarColor[$row['color']]);
$color = ImageColorAllocate ($image, $colorArray[0], $colorArray[1], $colorArray[2]);
// print appointment text and button
drawGlassButton($image, $color, $xoffset, $yoffset+8);
}
imagettftextboxopt($image, 12, 0, $txoffset, $yoffset, $style['textcolor'], $style['font'], $text, $opt_entry);
$yoffset += 27;
$last_event = $last_displayed_day = $currently_displayed_day;
$letzter_text = $text;
}
roundboxtrans_bottom($image, $xleft, $xend, $yoffset, $yoffset_diff, $yoffset_abstand-1, $yoffset_end, $radius, $bottom_zeilen_hoehe);
mysqli_free_result($result);
$yoffset += 18;
}
}
private function before_last ($needle, $inthat) {
return substr($inthat, 0, $this->strrevpos($inthat, $needle));
}
private function strrevpos($instr, $needle) {
$rev_pos = strpos (strrev($instr), strrev($needle));
if ($rev_pos===false) return false;
else return strlen($instr) - $rev_pos - strlen($needle);
}
private function calenderColorToRgb($olor) {
}
}