6 Commits

17 changed files with 1058 additions and 160 deletions

View File

@@ -17,7 +17,8 @@ class Plugin extends PluginBase {
public function registerComponents() { public function registerComponents() {
return [ return [
'NicoSt\GCalendar\Components\Upcoming' => 'upcoming', 'NicoSt\GCalendar\Components\Upcoming' => 'upcoming',
'NicoSt\GCalendar\Components\EmbeddedCalendar' => 'embeddedCalendar' 'NicoSt\GCalendar\Components\EmbeddedCalendar' => 'embeddedCalendar',
'NicoSt\GCalendar\Components\Download' => 'download'
]; ];
} }

View File

@@ -3,6 +3,7 @@
class EventEntity { class EventEntity {
var $calendar_name; var $calendar_name;
var $calendar_description;
var $event_name; var $event_name;
var $location; var $location;
var $description; var $description;
@@ -23,6 +24,20 @@ class EventEntity {
public function setCalendarName($calendar_name) { public function setCalendarName($calendar_name) {
$this->calendar_name = $calendar_name; $this->calendar_name = $calendar_name;
} }
/**
* @return mixed
*/
public function getCalendarDescription() {
return $this->calendar_description;
}
/**
* @param mixed $calendar_description
*/
public function setCalendarDescription($calendar_description) {
$this->calendar_description = $calendar_description;
}
/** /**
* @return mixed * @return mixed

View File

@@ -35,7 +35,7 @@ class GoogleCalendarService {
); );
try { try {
Log::debug('G-Calendar: Call google with #getCalendar.'); Log::debug('G-Calendar: Call google with #getCalendar for calendar with id: ' . $calendarId);
$response = $this->service->events->listEvents($calendarId, $params); $response = $this->service->events->listEvents($calendarId, $params);
Cache::put($this->cacheKeyCalendarGet.$calendarId, $response, $cacheTime); Cache::put($this->cacheKeyCalendarGet.$calendarId, $response, $cacheTime);

95
components/Download.php Normal file
View File

@@ -0,0 +1,95 @@
<?php namespace NicoSt\GCalendar\Components;
use Cms\Classes\ComponentBase;
use NicoSt\GCalendar\Classes\GoogleCalendarService;
class Download extends ComponentBase {
private $calPropSeparator = '§§';
private $googleIcalUrl = 'https://calendar.google.com/calendar/ical/%s/public/basic.ics';
/**
* Returns information about this component, including name and description.
*/
public function componentDetails() {
return [
'name' => 'nicost.gcalendar::lang.component.download.name',
'description' => 'nicost.gcalendar::lang.component.download.description'
];
}
public function defineProperties() {
$calendars = $this->calendarProperties();
$customProperties = [];
$result = array_merge($customProperties, $calendars);
return $result;
}
public function getCalendarDownloads() {
// Calenders from config
$calendarList = $this->getCalendarsFromProperties();
$data = [];
foreach($calendarList as $calendarData) {
$calendar = [];
$calendar['link'] = sprintf($this->googleIcalUrl, $calendarData['id']);
$calendar['title'] = $calendarData['title'];
array_push($data, $calendar);
}
return $data;
}
private function getCalendarsFromProperties() {
$calendars = [];
foreach($this->properties as $key => $value){
$exp_key = explode($this->calPropSeparator, $key);
if($exp_key[0] == 'cal' && $this->property($key) == true){
$calendar = [];
$calendar['id'] = $exp_key[1];
$calendar['title'] = $exp_key[2];
array_push($calendars, $calendar);
}
}
return $calendars;
}
private function calendarProperties() {
$service = new GoogleCalendarService();
$calendars = $service->calendarList();
if (isset($calendars['error'])) {
$calendars = '';
}
$calendarProperties = [];
if (!empty($calendars)) {
foreach ($calendars as &$calendar) {
$calendarData = [];
$calendarData['id'] = $calendar->id;
$calendarData['title'] = $calendar->summary;
$property = $this->createProperty($calendarData);
$calendarProperties = array_merge($calendarProperties, $property);
}
}
return $calendarProperties;
}
private function createProperty(array $calendarData) {
return [
'cal'.$this->calPropSeparator.$calendarData['id'].$this->calPropSeparator.$calendarData['title'] => [
'title' => $calendarData['title'],
'type' => 'checkbox',
'group' => 'nicost.gcalendar::lang.component.download.groups.calendars',
// Default to setting from config
'default' => 0,
]
];
}
}

View File

@@ -176,6 +176,7 @@ class EmbeddedCalendar extends ComponentBase {
$data += ['wkst' => 2]; $data += ['wkst' => 2];
} }
// Calenders from config
$calendarList = $this->getCalendarsFromProperties(); $calendarList = $this->getCalendarsFromProperties();
$dataParams = http_build_query($data); $dataParams = http_build_query($data);
@@ -220,9 +221,9 @@ class EmbeddedCalendar extends ComponentBase {
$exp_key = explode($this->calPropSeparator, $key); $exp_key = explode($this->calPropSeparator, $key);
if($exp_key[0] == 'cal' && $this->property($key) == true){ if($exp_key[0] == 'cal' && $this->property($key) == true){
$calendar = []; $calendar = [];
$calendar['src'] = $exp_key[2];
$calendar['color'] = $exp_key[1]; $calendar['color'] = $exp_key[1];
$calendars[] = $calendar; $calendar['src'] = $exp_key[2];
array_push($calendars, $calendar);
} }
} }
@@ -230,7 +231,6 @@ class EmbeddedCalendar extends ComponentBase {
} }
private function calendarProperties() { private function calendarProperties() {
// ToDo: Add cache => https://octobercms.com/docs/services/cache
$service = new GoogleCalendarService(); $service = new GoogleCalendarService();
$calendars = $service->calendarList(); $calendars = $service->calendarList();

View File

@@ -41,7 +41,7 @@ class Upcoming extends ComponentBase {
]; ];
} }
public function events() { public function getEvents() {
$connector = new GoogleCalendarService(); $connector = new GoogleCalendarService();
$maxEvents = $this->property('maxEvents'); $maxEvents = $this->property('maxEvents');
$calendarEvents = $connector->allEventList($maxEvents); $calendarEvents = $connector->allEventList($maxEvents);
@@ -71,6 +71,7 @@ class Upcoming extends ComponentBase {
$eventObject = new EventEntity(); $eventObject = new EventEntity();
$eventObject->setCalendarName($calendarEvent->summary); $eventObject->setCalendarName($calendarEvent->summary);
$eventObject->setEventName($event->summary); $eventObject->setEventName($event->summary);
$eventObject->setCalendarDescription($calendarEvent->description);
$eventObject->setLocation($event->location); $eventObject->setLocation($event->location);
$eventObject->setDescription($event->description); $eventObject->setDescription($event->description);
$eventObject->setStartTime($event->start->dateTime); $eventObject->setStartTime($event->start->dateTime);

View File

@@ -0,0 +1,5 @@
<h3>Click on a calendar to download it and import it to you're device.</h3>
{% set calendars = __SELF__.calendarDownloads %}
{% for calendar in calendars %}
<a href="{{ calendar.link }}" target="_blank">{{ calendar.title }}</a><br />
{% endfor %}

View File

@@ -1,4 +1,4 @@
{% set events = upcoming.events %} {% set events = __SELF__.events %}
{% if not events.error and events is not empty %} {% if not events.error and events is not empty %}
<table> <table>

View File

@@ -1,5 +1,5 @@
{ {
"name": "nicost/oc-gcalendar-plugin", "name": "nicost/gcalendar-plugin",
"type": "october-plugin", "type": "october-plugin",
"description": "OctoberCMS calendar plugin which uses the Google Calendar API to provide event data.", "description": "OctoberCMS calendar plugin which uses the Google Calendar API to provide event data.",
"keywords": ["october", "cms", "google", "calendar", "events", "schedule", "kalender"], "keywords": ["october", "cms", "google", "calendar", "events", "schedule", "kalender"],
@@ -11,6 +11,7 @@
], ],
"require": { "require": {
"php": ">=7.0", "php": ">=7.0",
"composer/installers": "~1.0",
"google/apiclient": "^2.0", "google/apiclient": "^2.0",
"mobiledetect/mobiledetectlib": "^2.8" "mobiledetect/mobiledetectlib": "^2.8"
} }

779
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,35 @@
<?php namespace NicoSt\GCalendar\FormWidgets;
use Backend\Classes\FormWidgetBase;
use Cache;
use Log;
use Flash;
use Lang;
use NicoSt\GCalendar\Models\Settings;
class ClearCacheButton extends FormWidgetBase {
protected $defaultAlias = 'clearCacheButton';
private $cacheKeyCalendarList = 'GCalendar-CalendarList';
private $cacheKeyCalendarGet = 'GCalendar-CalendarGet#';
public function render() {
return $this->makePartial('clearCacheButton');
}
// Clear cache for all saved calendars
public function onClearCache() {
$calendarSelectors = Settings::get('calendar_selector', []);
foreach ($calendarSelectors as &$selector) {
Cache::forget($this->cacheKeyCalendarGet.$selector['id']);
}
Cache::forget($this->cacheKeyCalendarList);
Log::info('G-Calendar: Cache cleared!');
Flash::success(Lang::get('nicost.gcalendar::lang.widget.clearCacheButton.success'));
}
}

View File

@@ -38,7 +38,7 @@ class OAuth extends FormWidgetBase {
$this->vars['auth_url'] = $authUrl; $this->vars['auth_url'] = $authUrl;
return $this->makePartial('gaccess'); return $this->makePartial('gaccess');
} }
Log::info('G-Calendar: Access token not expired.'); Log::info('G-Calendar: Access token not expired.');

View File

@@ -0,0 +1,5 @@
<button type="button"
data-request="onClearCache"
class="btn btn-default">
<?= e(trans('nicost.gcalendar::lang.widget.clearCacheButton.buttonText')) ?>
</button>

View File

@@ -3,8 +3,165 @@
'name' => 'G-Calendar', 'name' => 'G-Calendar',
'description' => 'Kalender Plugin basierend auf der Google API.', 'description' => 'Kalender Plugin basierend auf der Google API.',
], ],
'component' => [
'upcoming' => [
'name' => 'Bevorstehende Termine',
'description' => 'Listet alle bevorstehenden Termine.'
],
'embeddedCalendar' => [
'name' => 'Eingebetteter Kalender',
'description' => 'Eingebetteter Google Kalender.',
'groups' => [
'calendars' => 'Kalender',
'toggleElements' => 'Toggle Elements'
],
'properties' => [
'calendarTitle' => [
'title' => 'Kalender Title'
],
'width' => [
'title' => 'Breite',
'validationMessage' => 'Die Breite muss Numerisch sein und darf nicht mehr als vier Ziffern umfassen.'
],
'height' => [
'title' => 'Höhe',
'validationMessage' => 'Die Höhe muss Numerisch sein und darf nicht mehr als vier Ziffern umfassen.'
],
'timezone' => [
'title' => 'Zeitzone'
],
'language' => [
'title' => 'Sprache'
],
'viewMode' => [
'title' => 'Anzeigemodus',
'placeholder' => 'Wähle einen Anzeigemodus',
'description' => 'Wähle "Dynamisch" um die "Agenda Ansicht" für Mobile Geräte und die "Monatsansicht" für Desktop zu nutzen.',
'month' => 'Monatsansicht',
'week' => 'Wochenansicht',
'agenda' => 'Agenda Ansicht',
'dynamic' => 'Dynamisch'
],
'weekStart' => [
'title' => 'Woche starte am:',
'sat' => 'Samstag',
'sun' => 'Sonntag',
'mon' => 'Montag'
],
'bgcolor' => [
'title' => 'Hintergrundfarbe',
'description' => 'Definiert die Hintergrundfarbe des Kopfbereichs.',
'validationMessage' => 'Hintergrundfarbe muss als Hexadecimal Code angegeben werden.'
],
'showTitle' => [
'title' => 'Titel Anzeigen'
],
'showPrint' => [
'title' => 'Drucker Optionen Anzeigen'
],
'showTimezone' => [
'title' => 'Zeitzone Anzeigen'
],
'showNav' => [
'title' => 'Navigation Anzeigen'
],
'showDate' => [
'title' => 'Datum Anzeigen'
],
'showTabs' => [
'title' => 'Tabs Anzeigen'
],
'showCalendarList' => [
'title' => 'Kalender Liste Anzeigen'
]
]
],
'download' => [
'name' => 'Download Kalender',
'description' => 'Kalender als "ICS-Datei" downloaden.',
'groups' => [
'calendars' => 'Kalender'
]
]
],
'widget' => [
'clearCacheButton' => [
'buttonText' => 'Cache löschen',
'success' => 'Cache wurde gelöscht!'
]
],
'settings' => [ 'settings' => [
'label' => 'G-Calendar', 'label' => 'G-Calendar',
'description' => 'Einstellungen für das G-Kalender Plugin' 'description' => 'Einstellungen für das G-Calendar Plugin.',
'tab' => [
'client' => 'Client Konfiguration',
'calendars' => 'Kalender',
'settings' => 'Einstellungen'
],
'fields' => [
'applicationName' => [
'label' => 'Anzeigename',
'comment' => 'Optional.'
],
'clientId' => [
'label' => 'Client ID',
'comment' => 'Die "Client ID" steht in den "OAuth Credentials". (https://console.cloud.google.com/apis/credentials)'
],
'clientSecret' => [
'label' => 'Client Secret',
'comment' => 'Der "Client Secret" code steht in den "OAuth Credentials". (https://console.cloud.google.com/apis/credentials)'
],
'accessToken' => [
'label' => 'Access Token',
'comment' => 'Wird automatisch beim Speichern der "Client ID" und "Client Secret" generiert.'
],
'cacheTime' => [
'label' => 'Google Calendar API Cache.',
'comment' => 'Anfragen an die Google Calendar API werden zwischengespeichert um die Anzahl der Anfragen zu reduzieren. (\'0\') um den Cache zu deaktivieren. (Angabe in Minuten)'
],
'section' => [
'accessToken' => 'Access Token',
'cacheControl' => 'Cache Einstellungen',
'notification' => 'Benachrichtigung'
],
'notification' => [
'switch' => [
'label' => 'Benachrichtigung Einblenden',
'on' => 'An',
'off' => 'Aus'
],
'text' => [
'label' => 'Nachricht'
]
]
],
'button' => [
'requestToken' => 'Access Token Anfragen',
'clearToken' => 'Access Token Löschen'
],
'calendarList' => [
'emptyList' => 'Kein Kalender gefunden. Verbinde G-Calendar mit deinem Google Account um deine Kalender hier anzuzeigen.',
'columnName' => 'Name',
'columnRole' => 'Rolle',
'columnId' => 'ID'
],
'gaccess' => [
'text' => 'Klicke auf den unten stehenden Link um G-Calendar zugriff auch deine Kalender zu gewähren.',
'button' => 'Zugriff Gewähren.'
],
'oauth' => [
'tokenNotValid' => 'Access Token <b>ungültig</b>.',
'tokenValid' => 'Access Token gültig.'
]
], ],
'message' => [
'accessTokenNotExpired' => 'Access Token nicht abgelaufen.',
'accessTokenRemoved' => 'Access Token erfolgreich entfernt.'
]
]; ];

View File

@@ -1,7 +1,7 @@
<?php return [ <?php return [
'plugin' => [ 'plugin' => [
'name' => 'G-Calendar', 'name' => 'G-Calendar',
'description' => 'Calendar plugin which uses the google API.', 'description' => 'Calendar plugin which uses the google API.'
], ],
'component' => [ 'component' => [
@@ -18,21 +18,21 @@
], ],
'properties' => [ 'properties' => [
'calendarTitle' => [ 'calendarTitle' => [
'title' => 'Calendar Title', 'title' => 'Calendar Title'
], ],
'width' => [ 'width' => [
'title' => 'Width', 'title' => 'Width',
'validationMessage' => 'The width must be numeric and not longer than 4 characters.', 'validationMessage' => 'The width must be numeric and not longer than 4 characters.'
], ],
'height' => [ 'height' => [
'title' => 'Height', 'title' => 'Height',
'validationMessage' => 'The height must be numeric and not longer than 4 characters.', 'validationMessage' => 'The height must be numeric and not longer than 4 characters.'
], ],
'timezone' => [ 'timezone' => [
'title' => 'Timezone', 'title' => 'Timezone'
], ],
'language' => [ 'language' => [
'title' => 'Language Code', 'title' => 'Language Code'
], ],
'viewMode' => [ 'viewMode' => [
'title' => 'View Mode', 'title' => 'View Mode',
@@ -55,28 +55,41 @@
'validationMessage' => 'Background color must be a hexadecimal color code.' 'validationMessage' => 'Background color must be a hexadecimal color code.'
], ],
'showTitle' => [ 'showTitle' => [
'title' => 'Show Title', 'title' => 'Show Title'
], ],
'showPrint' => [ 'showPrint' => [
'title' => 'Show Print Option', 'title' => 'Show Print Option'
], ],
'showTimezone' => [ 'showTimezone' => [
'title' => 'Show Timezone', 'title' => 'Show Timezone'
], ],
'showNav' => [ 'showNav' => [
'title' => 'Show Navigation', 'title' => 'Show Navigation'
], ],
'showDate' => [ 'showDate' => [
'title' => 'Show Date', 'title' => 'Show Date'
], ],
'showTabs' => [ 'showTabs' => [
'title' => 'Show Tabs', 'title' => 'Show Tabs'
], ],
'showCalendarList' => [ 'showCalendarList' => [
'title' => 'Show Calendar List', 'title' => 'Show Calendar List'
], ]
] ]
],
'download' => [
'name' => 'Download Calendar',
'description' => 'Download calendar as "ICS-File".',
'groups' => [
'calendars' => 'Calendars'
]
]
],
'widget' => [
'clearCacheButton' => [
'buttonText' => 'Clear Cache',
'success' => 'Cache cleared!'
] ]
], ],
@@ -96,11 +109,11 @@
], ],
'clientId' => [ 'clientId' => [
'label' => 'Client ID', 'label' => 'Client ID',
'comment' => 'The Client ID can be found in the OAuth Credentials under Service Account.' 'comment' => 'The Client ID can be found in the OAuth Credentials under Service Account. (https://console.cloud.google.com/apis/credentials)'
], ],
'clientSecret' => [ 'clientSecret' => [
'label' => 'Client Secret', 'label' => 'Client Secret',
'comment' => 'The Client Secret key can be found in the OAuth Credentials.' 'comment' => 'The Client Secret can be found in the OAuth Credentials. (https://console.cloud.google.com/apis/credentials)'
], ],
'accessToken' => [ 'accessToken' => [
'label' => 'Access Token', 'label' => 'Access Token',
@@ -111,8 +124,20 @@
'comment' => 'Cache Google Calendar API requests in minutes. Enter \'0\' to disable caching.' 'comment' => 'Cache Google Calendar API requests in minutes. Enter \'0\' to disable caching.'
], ],
'section' => [ 'section' => [
'accessToken' => 'Access Token' 'accessToken' => 'Access Token',
'cacheControl' => 'Cache control',
'notification' => 'Notification'
], ],
'notification' => [
'switch' => [
'label' => 'Display Notification',
'on' => 'On',
'off' => 'Off'
],
'text' => [
'label' => 'Notification Content'
]
]
], ],
'button' => [ 'button' => [

View File

@@ -1,7 +1,7 @@
tabs: tabs:
fields: fields:
# Tab: Google Client # Tab: Client Configuration
application_name: application_name:
label: 'nicost.gcalendar::lang.settings.fields.applicationName.label' label: 'nicost.gcalendar::lang.settings.fields.applicationName.label'
tab: 'nicost.gcalendar::lang.settings.tab.client' tab: 'nicost.gcalendar::lang.settings.tab.client'
@@ -14,12 +14,14 @@ tabs:
type: text type: text
comment: 'nicost.gcalendar::lang.settings.fields.clientId.comment' comment: 'nicost.gcalendar::lang.settings.fields.clientId.comment'
span: left span: left
required: true
client_secret: client_secret:
label: 'nicost.gcalendar::lang.settings.fields.clientSecret.label' label: 'nicost.gcalendar::lang.settings.fields.clientSecret.label'
tab: 'nicost.gcalendar::lang.settings.tab.client' tab: 'nicost.gcalendar::lang.settings.tab.client'
type: text type: text
comment: 'nicost.gcalendar::lang.settings.fields.clientSecret.comment' comment: 'nicost.gcalendar::lang.settings.fields.clientSecret.comment'
span: left span: left
required: true
google_oauth: google_oauth:
label: 'nicost.gcalendar::lang.settings.fields.section.accessToken' label: 'nicost.gcalendar::lang.settings.fields.section.accessToken'
tab: 'nicost.gcalendar::lang.settings.tab.client' tab: 'nicost.gcalendar::lang.settings.tab.client'
@@ -28,14 +30,43 @@ tabs:
tab: 'nicost.gcalendar::lang.settings.tab.client' tab: 'nicost.gcalendar::lang.settings.tab.client'
type: NicoSt\GCalendar\FormWidgets\OAuth type: NicoSt\GCalendar\FormWidgets\OAuth
# Tab: Calendars
calendar_selector: calendar_selector:
tab: 'nicost.gcalendar::lang.settings.tab.calendars' tab: 'nicost.gcalendar::lang.settings.tab.calendars'
type: NicoSt\GCalendar\FormWidgets\CalendarSelector type: NicoSt\GCalendar\FormWidgets\CalendarSelector
# Tab: Settings
cache_control:
label: 'nicost.gcalendar::lang.settings.fields.section.cacheControl'
tab: 'nicost.gcalendar::lang.settings.tab.settings'
type: section
cache_time: cache_time:
label: 'nicost.gcalendar::lang.settings.fields.cacheTime.label' label: 'nicost.gcalendar::lang.settings.fields.cacheTime.label'
tab: 'nicost.gcalendar::lang.settings.tab.settings' tab: 'nicost.gcalendar::lang.settings.tab.settings'
comment: 'nicost.gcalendar::lang.settings.fields.cacheTime.comment' comment: 'nicost.gcalendar::lang.settings.fields.cacheTime.comment'
type: number type: number
span: left span: left
default: 15 default: 15
clear_cache:
tab: 'nicost.gcalendar::lang.settings.tab.settings'
type: NicoSt\GCalendar\FormWidgets\ClearCacheButton
notification:
label: 'nicost.gcalendar::lang.settings.fields.section.notification'
tab: 'nicost.gcalendar::lang.settings.tab.settings'
type: section
notification_show:
label: 'nicost.gcalendar::lang.settings.fields.notification.switch.label'
tab: 'nicost.gcalendar::lang.settings.tab.settings'
type: switch
on: nicost.gcalendar::lang.settings.fields.notification.switch.on
off: nicost.gcalendar::lang.settings.fields.notification.switch.off
notification_text:
label: 'nicost.gcalendar::lang.settings.fields.notification.text.label'
tab: 'nicost.gcalendar::lang.settings.tab.settings'
type: richeditor
size: huge
toolbarButtons: bold|italic|underline||insertLink||undo|redo||html
trigger:
action: show
field: notification_show
condition: checked

View File

@@ -1,3 +1,9 @@
1.0.0: 1.0.0:
- Initialize plugin. - Initialize plugin.
- Prepare for October marketplace. - Prepare for October marketplace.
1.1.0:
- Add new "Download" component to display a list of calendars to be downloaded as ics-file.
- Update dependencies
- Fix some minor bugs
1.1.1:
- Compatibility with October CMS 2