vorkonfiguriert fuer die Wolke (#13)
* redundante readme.txt entfernt * GCAL namespace auf wolkal3000 geändert (Dateinamen, WP options) (dadurch ggf. Co-Existenz mit dem ursprüinglichen GCal-Plugin möglich!) * Vorkonfiguration für die Wolke, man braucht nur die 16-stellige Kalender ID (dadurch Security Verbesserung: kein dynamisches Laden von potentiell nicht vertrauenswürdigen Inhalten) * Google Maps Funktionen entfernt **Bei Migration von <= 0.3.8 bitte das alte Plugin per "uninstall" deinstallieren, damit die Daten im alten Namespace gelöscht werden. Achtung: Die Konfiguration muss (im neuen Namespace) neu vorgenommen werden!** Co-authored-by: Christian Tramnitz <christian.tramnitz@gruene-hochtaunus.de> Reviewed-on: #13 Co-Authored-By: Christian Tramnitz <christian.tramnitz@git@verdigado.com> Co-Committed-By: Christian Tramnitz <christian.tramnitz@git@verdigado.com>
This commit is contained in:
parent
f892b0e308
commit
3f03ea7cda
31
Makefile
31
Makefile
|
@ -1,31 +0,0 @@
|
|||
|
||||
NAME = wolkal3000
|
||||
ICALPARSER = icalparser
|
||||
|
||||
##this shouldn't be here
|
||||
|
||||
#INSTALLDIR = /usr/share/wordpress/wp-content/plugins/$(NAME)
|
||||
#SSHACCOUNT = root@192.168.20.30
|
||||
VERSION = 0.3.3
|
||||
|
||||
|
||||
# Make sure we always ship the latest icalparser version
|
||||
icalparser:
|
||||
if [ -d icalparser ] ; then \
|
||||
cd icalparser && git pull ; \
|
||||
else \
|
||||
git clone https://github.com/OzzyCzech/icalparser ; \
|
||||
fi
|
||||
|
||||
|
||||
release: icalparser
|
||||
cd .. ; \
|
||||
rm -f $(NAME)-$(VERSION).zip ; \
|
||||
zip -9 -r $(NAME)-$(VERSION).zip $(NAME)/$(ICALPARSER)/readme.md $(NAME)/$(ICALPARSER)/LICENSE $(NAME)/$(ICALPARSER)/src/* $(NAME)/$(ICALPARSER)/tools/* $(NAME)/*.php $(NAME)/readme.* $(NAME)/README.*
|
||||
|
||||
|
||||
install: icalparser
|
||||
rsync --delete -C -av ./ $(SSHACCOUNT):$(INSTALLDIR)
|
||||
ssh $(SSHACCOUNT) chown -R www-data:www-data $(INSTALLDIR)
|
||||
|
||||
|
48
README.md
48
README.md
|
@ -2,18 +2,18 @@
|
|||
|
||||
Ein Wordpress-Plugin, das auf das Grüne Wordpress-Theme <a href="https://www.urwahl3000.de/">Urwahl3000</a> aufsetzt und eine Integration beliebig vieler öffentlicher ICS-Kalender ermöglicht.
|
||||
|
||||
Version: 0.3.8
|
||||
Version: 0.3.9
|
||||
|
||||
## Warnung
|
||||
|
||||
Nicht produktiv verwenden. Nur zu Testzwecken.
|
||||
Das hier ist noch in einem frühen Entwicklungsstadium aber durch die Begrenzung auf eine (vertrauenswürdige!) Quelle, sollte sich möglicher Schaden in Grenzen halten.
|
||||
|
||||
## Motivation
|
||||
|
||||
Für eine solche Integration gibt es eine Reihe von Motivatoren:
|
||||
|
||||
* Manche (viele?) Seitenadmins scheuen dem Umgang mit einem Blog- oder CMS-System. Die Terminpflege auszulagern erleichtert den Admins den Umgang mit dem Kalendersystem und senkt die Hemmschwelle.
|
||||
* (Öffentliche) ICS-Kalender lassen sich auf einfache Weise auch per Smartphone administrieren. Dazu muss der Admin lediglich in GCal entsprechende Admin-Zugänge z.B. für den Ortssprecher oder den News-Redakteur vergeben. Ebenso lassen sich solche Kalender leicht von jedermann in den eigenen Kalender einbinden, um jederzeit die aktuelle Terminübersicht greifbar zu haben. Eine weiter führende Dokumentation findet sich <a href="https://www.gruene-freising.de/... ">hier</a>.
|
||||
* Termine werden in Regel bereits in einem Kalender gepflegt. Die Arbeit diese auch noch manuell in das CMS zu übernehmen entfällt.
|
||||
* Der Umgang mit Terminen im Quellsystem (z.B. der Wolke) ist u.U. leichter handzuhaben als im CMS
|
||||
* So schön Urwahl3000 ist - der auf wpCalendar basierende kal3000 Kalender unterstützt keine Serientermine. Mit diesem Plugin ist das kein Problem mehr, da es Serientermine im Google Kalender automatisch als Serie von Einzelterminen anlegt.
|
||||
|
||||
## Eigenschaften
|
||||
|
@ -21,28 +21,32 @@ Für eine solche Integration gibt es eine Reihe von Motivatoren:
|
|||
* Administration in Wordpress über die Admin-Oberfläche.
|
||||
* Einbinden beliebig vieler ICS-Kalender.
|
||||
* Zuordnung dieser ICS-Kalender zu bereits angelegten Terminkategorien, beispielsweise KV Allgemein, AG Klima etc..
|
||||
* ~~Geocoding von Veranstaltungsorten, wie sie aus Google Kalender übernommen werden. Derart angelegte Termine werden auf der Übersichtskarte richtig angezeigt.~~ - Wollen wir nicht
|
||||
* Multi-Site fähig
|
||||
|
||||
|
||||
## Voraussetzungen / Installation
|
||||
|
||||
1. Um eine auf Urwahl3000 und Wordpress basierende KV- oder OV-Seite betreiben zu können, braucht man zunächst eine irgendwo gehostete aktuelle Wordpress-Umgebung. Dazu wird auf die Dokumentation von Urwahl3000 verwiesen.
|
||||
|
||||
2. Als nächstes holt man sich das Plugin unter <a href="http://www.seneca.muc.de/kal3000-gcal-import/">http://www.seneca.muc.de/kal3000-gcal-import/</a> und installiert es über die WP-Oberfläche wie gewohnt.
|
||||
2. Als nächstes holt man sich das Plugin unter <a href="https://git.verdigado.com/NB-Public/WolKal3000/releases">https://git.verdigado.com/NB-Public/WolKal3000/releases</a> und installiert es über die WP-Oberfläche wie gewohnt.
|
||||
|
||||
Hinweis: kal3000-gcal-import nutzt für das Parsen von ICAL-Files und -Feeds das PHP-Modul <a href="https://github.com/OzzyCzech/icalparser">icalparser</a>. Die Verwendung und die Einbindung in die Release-ZIP-Files erfolgt mit freundlicher Genehmigung des Autors Roman Ožana.
|
||||
Hinweis: WolKal3000 nutzt für das Parsen von ICAL-Files und -Feeds das PHP-Modul icalparser (https://github.com/OzzyCzech/icalparser). Bei einem Clone des Repositories sollte daher rekursiv inkl. Submodules gecloned werden, alternativ muss icalparserer manuell im WolKal3000-Plugin-Verzeichnis installiert werden.
|
||||
|
||||
## Konfiguration
|
||||
|
||||
1. in WP legt man Terminkategorien an, z.B. eine pro OV und eine für den KV, plus weitere nach Bedarf. Das funktioniert am besten mit einer entsprechenden Seitenhierarchie wie auf https://www.gruene-freising.de/... (Beispiele folgen).
|
||||
1. In der Konfiguration (wolkal3000-config.php) sind die globalen Konfigurationsvariablen WOLKAL_PREFIX und WOLKAL_SUFFIX ggf. anzupassen. Für die Grüne Wolke der Netzbegrünung sind die Default Werte ausreichend:
|
||||
define ('WOLKAL_PREFIX', 'https://wolke.netzbegruenung.de/remote.php/dav/public-calendars/');
|
||||
define ('WOLKAL_SUFFIX', '?export');
|
||||
|
||||
2. Im Admin-Teil des Plugins unter "Einstellungen / GCal Importer" erscheinen die angelegten Terminkategorien. Jeder Kategorie weist man dann einen öffentlichen Google-Kalender in Form des "public ics"-Links zu, beispielsweise <a href="https://calendar.google.com/calendar/ical/gruene.freising%40gmail.com/public/basic.ics">https://calendar.google.com/calendar/ical/gruene.freising%40gmail.com/public/basic.ics</a>.
|
||||
2. in WP legt man Terminkategorien an, z.B. eine pro Kampagne oder Verband aus dem die Nachrichten kommen.
|
||||
|
||||
3. Im Admin-Teil kann man das Zeitintervall einstellen, mit dem die Kalender synchronisiert werden. Standardeinstellung ist 60 Minuten. Bitte beachten, dass der Wordpress-Scheduler die Zeitintervalle nur ungefähr und abhängig von der Seitenaktivität einhält.
|
||||
3. Im Admin-Teil des Plugins unter "Einstellungen / WolKal3000" erscheinen die angelegten Terminkategorien. Jeder Kategorie weist man dann einen öffentlichen (keine Authentifizierung möglich!) Kalender in Form der 16-stelligen öffentlichen Kalender Freigabe-ID zu, beispielsweise "SEZ0123456789ABC".
|
||||
|
||||
4. Im Admin-Teil kann man das Geocoding aktivieren. Derzeit ist nur ein inoffizieller Weg über Google Maps verfügbar, den Google nicht gerne sieht. Das offizielle <a href="https://developers.google.com/maps/documentation/geocoding/start">Google-API</a> erfordert einen API-Key, der bei intensiver Nutzung nicht kostenlos ist. Auf die Google-Policy wird hingewiesen. Außerdem ist OpenStreetMap verfügbar, aber es kann nicht sehr gut mit den Lokationen aus Google Maps umgehen. Im Moment ist es benutzbar, funktioniert aber nicht zuverlässig.
|
||||
4. Im Admin-Teil kann man das Zeitintervall einstellen, mit dem die Kalender synchronisiert werden. Standardeinstellung ist 60 Minuten. Bitte beachten, dass der Wordpress-Scheduler die Zeitintervalle nur ungefähr und abhängig von der Seitenaktivität einhält.
|
||||
|
||||
5. Speichern und fertig.
|
||||
5. Im Admin-Teil kann man das Geocoding aktivieren. Derzeit ist nur ein experimenteller Weg über OpenStreetMap verfügbar.
|
||||
|
||||
6. Speichern und fertig.
|
||||
|
||||
Unter "Debugging" finden sich zwei weitere Einstellungen:
|
||||
|
||||
|
@ -50,7 +54,6 @@ Unter "Debugging" finden sich zwei weitere Einstellungen:
|
|||
|
||||
2. Die zweite Einstellung löscht den Geocoding-Cache bei jedem Plugin-Neustart, um das Geocoding für jede Lokation neu zu erzwingen, beispielsweise wenn man die Geocoding-Methode geändert hat.
|
||||
|
||||
|
||||
## Benutzung
|
||||
|
||||
Um die Termine in WP anzuzeigen, gibt es zwei Wege:
|
||||
|
@ -64,7 +67,8 @@ Mit "Aktivieren" beginnt das Plugin sofort mit der Synchronisation.
|
|||
|
||||
## Proxy-Konfiguration
|
||||
|
||||
Das Plugin benötigt den Zugriff nach "draußen", um ICAL-Feeds zu holen oder auf Google Maps zuzugreifen. Wenn Du mit Deinem Wordpress-Server z.B. in einem Firmennetz bist, musst Du möglicherweise über einen Proxy nach draußen gehen. In Wordpress werden Proxy-Einstellungen in <code>/usr/share/wordpress/wp-config.php</code> bzw. auf Ubuntu / Debian in <code>/etc/wordpress/config-SITE.php</code> festgelegt. Zur Dokumentation bitte <a href="https://developer.wordpress.org/reference/classes/wp_http_proxy/">hier entlang</a>.
|
||||
Das Plugin benötigt den Zugriff nach "draußen", um ICAL-Feeds zu holen oder auf OpenStreetMap zuzugreifen. Wenn Du mit Deinem Wordpress-Server hinter einer Firewall bist, musst Du möglicherweise über einen Proxy nach draußen gehen. In Wordpress werden Proxy-Einstellungen in <code>/usr/share/wordpress/wp-config.php</code> bzw. auf Ubuntu / Debian in <code>/etc/wordpress/config-SIT
|
||||
E.php</code> festgelegt. Zur Dokumentation bitte <a href="https://developer.wordpress.org/reference/classes/wp_http_proxy/">hier entlang</a>.
|
||||
|
||||
## Support
|
||||
|
||||
|
@ -72,23 +76,9 @@ Bitte ein Ticket (issue) auf https://git.verdigado.com/NB-Public/WolKal3000/issu
|
|||
|
||||
## Bekannte Fehler
|
||||
|
||||
Vermutlich viele. Ich bin alles andere als ein begnadeter Programmierer.
|
||||
siehe Support
|
||||
|
||||
## Internationalization
|
||||
|
||||
Since this plugin is only relevant for people using the Urwahl3000 theme, and this includes only members of Bündnis 90 / Die Grünen, the user interface of the plugin will only be available in German. Should a demand for other languages arise, feel free to contact me - contributions welcome! :-)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,201 +0,0 @@
|
|||
<?php
|
||||
|
||||
defined( 'ABSPATH' ) or die( 'No script kiddies please!' );
|
||||
|
||||
|
||||
/**
|
||||
* Display the admin table
|
||||
*
|
||||
* @since 0.1.0
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Quellen:
|
||||
* https://codex.wordpress.org/Creating_Options_Pages
|
||||
* http://ottopress.com/2009/wordpress-settings-api-tutorial/
|
||||
*/
|
||||
|
||||
add_action('admin_menu', 'gcal_admin_add_page');
|
||||
|
||||
function gcal_admin_add_page() {
|
||||
add_options_page( 'WolKal3000 – Synchronisation von Kal3000 mit Wolke-Kalendern', 'WolKal3000', 'manage_options', 'kal3000-gcal-import', 'gcal_options_page');
|
||||
}
|
||||
|
||||
function gcal_options_page() {
|
||||
|
||||
if ( !current_user_can( 'manage_options' ) ) {
|
||||
wp_die( __( 'You do not have sufficient permissions to access this page.' ) );
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<div class="wrap">
|
||||
<h1><?= esc_html(get_admin_page_title()); ?></h1>
|
||||
<p>Mit WolKal3000 kannst du dein Kal3000-Plugin automatisch mit Kalendern in der grünen Wolke synchronisieren. Darüber hinaus kannst du jede andere ICS-Datei verwenden.</p>
|
||||
|
||||
<form action="options.php" method="post">
|
||||
<?php settings_fields('gcal_options'); ?>
|
||||
<?php do_settings_sections('gcal'); ?>
|
||||
<input name="Submit" type="submit" value="<?php esc_attr_e('Save Changes'); ?>" />
|
||||
</br></br></br><hr></br>
|
||||
<?php do_settings_sections('gcal2'); ?>
|
||||
<input name="Submit" type="submit" value="<?php esc_attr_e('Save Changes'); ?>" />
|
||||
</form></div>
|
||||
|
||||
<?php
|
||||
}
|
||||
|
||||
add_action('admin_init', 'gcal_admin_init');
|
||||
|
||||
function gcal_admin_init(){
|
||||
register_setting( 'gcal_options', 'gcal_options', 'gcal_options_validate' );
|
||||
add_settings_section('gcal_feeds', 'Wolke-Kalender einer Terminkategorie zuordnen', 'gcal_feeds_section_text', 'gcal');
|
||||
|
||||
// settings fields dynamisch pro Feed generieren, nur ein Callback mit Args nutzen.
|
||||
$terms = get_terms( array(
|
||||
'taxonomy' => 'termine_type',
|
||||
'hide_empty' => false, )
|
||||
);
|
||||
foreach($terms as $term){
|
||||
$unique_id = 'gcal_feed_' . $term->name;
|
||||
$feed_name = $term->name;
|
||||
add_settings_field($unique_id, 'Terminkategorie "'.$feed_name.'"', 'gcal_feeds_setting_string', 'gcal', 'gcal_feeds', array($unique_id));
|
||||
}
|
||||
|
||||
add_settings_section('gcal_timer', 'Synchronisationsintervall', 'gcal_timer_section_text', 'gcal');
|
||||
add_settings_field('gcal_timer', 'Synchronisiere alle …', 'gcal_timer_setting_string', 'gcal', 'gcal_timer');
|
||||
|
||||
add_settings_section('gcal_geocoding', 'Geocoding (EXPERIMENTELL)', 'gcal_geocoding_section_text', 'gcal2');
|
||||
add_settings_field('gcal_geocoding', 'Geocoding-Methode', 'gcal_geocoding_setting_string', 'gcal2', 'gcal_geocoding');
|
||||
|
||||
add_settings_section('gcal_debugging', 'Entwickler*innenoptionen', 'gcal_debugging_section_text', 'gcal2');
|
||||
add_settings_field('gcal_debugging', 'Debugging', 'gcal_debugging_setting_string', 'gcal2', 'gcal_debugging');
|
||||
}
|
||||
|
||||
|
||||
function gcal_feeds_section_text() {
|
||||
?>
|
||||
<p><b>Wolke-Kalender synchronisieren in eine ausgewählte Terminkategorie von Kal3000. Bitte trage hierfür die entsprechende Export-Adresse des gewünschten Wolke-Kalenders ein.</b></br><b>Falls zu einer Terminkategorie kein Wolke-Kalender synchronisiert werden soll, entsprechendes Feld bitte leer lassen.</b></p>
|
||||
<p><b><a href="hilfeseite" target="_blank">Erfahre mehr darüber, wie du die Export-Adresse eines Wolke-Kalenders findest.</a></b>
|
||||
</p>
|
||||
<?php
|
||||
}
|
||||
|
||||
|
||||
|
||||
function gcal_feeds_setting_string($args) {
|
||||
$options = get_option('gcal_options');
|
||||
$placeholder = "z.B. https://wolke.netzbegruenung.de/remote.php/dav/public-calendars/xxxxxxxxxxxxxxxx?export";
|
||||
// die id entspricht dem unique_id in add_settings_field.
|
||||
// der name wird options.php als Name der zu setzenden Option übergeben
|
||||
// der Value ist der inhalt von der $option[unique_id].
|
||||
echo '<input type="text" id="' . $args[0] . '" name="gcal_options[' . $args[0] . ']" value="' . $options[$args[0]] . '" size="80" maxlength="256" placeholder="' . $placeholder . '" > </br>';
|
||||
}
|
||||
|
||||
|
||||
function gcal_timer_section_text() {
|
||||
?>
|
||||
<p><b>In welcher Regelmäßigkeit sollen die Wolke-Kalender synchronisiert werden? Bitte Zeitintervall in Minuten angeben.</b></br>
|
||||
<b>Achtung: Um Änderungen wirksam werden zu lassen, muss das Plugin deaktiviert und wieder aktiviert werden. (Menüpunkt "Plugins")</b></p>
|
||||
<?php
|
||||
}
|
||||
|
||||
|
||||
function gcal_timer_setting_string() {
|
||||
$options = get_option('gcal_options');
|
||||
$placeholder = "default 60";
|
||||
echo '<input type="text" id="gcal_timer" name="gcal_options[gcal_timer]" value="' . $options['gcal_timer'] . '" size="6" maxlength="6" placeholder="' . $placeholder . '" > Minuten </br>';
|
||||
}
|
||||
|
||||
|
||||
|
||||
function gcal_geocoding_section_text() {
|
||||
?>
|
||||
<p>Damit der Termin-Ort auf einer Karte eingezeichnet werden kann, müssen die Ortsinformationen von der Textform in geografische Länge und Breite umgerechnet werden.</br>Dies nennt sich Geocoding. Dabei handelt es sich um eine experimentelle Funktion von WolKal3000.</p>
|
||||
<?php
|
||||
}
|
||||
|
||||
|
||||
function gcal_geocoding_setting_string() {
|
||||
$options = get_option('gcal_options');
|
||||
$current = ( isset ($options['gcal_geocoding']) ? $options['gcal_geocoding'] : 'off' ); // default off
|
||||
$apikey = ( isset ($options['gcal_apikey']) ? $options['gcal_apikey'] : '' ); // default empty
|
||||
|
||||
$coders = array(
|
||||
array(
|
||||
'option' => 'off',
|
||||
'name' => 'deaktiviert',
|
||||
), /*
|
||||
array(
|
||||
'option' => 'official',
|
||||
'name' => 'Google official - erfordert einen API Key --> ',
|
||||
),
|
||||
array(
|
||||
'option' => 'inofficial',
|
||||
'name' => 'Google inofficial',
|
||||
), */
|
||||
array(
|
||||
'option' => 'osm',
|
||||
'name' => 'OpenStreetMap (EXPERIMENTELL)',
|
||||
),
|
||||
);
|
||||
|
||||
foreach ( $coders as $coder ) {
|
||||
$checked = ( $current == $coder['option'] ? 'checked' : '' );
|
||||
echo '<input type="radio" id="gcal_geocoding" name="gcal_options[gcal_geocoding]" value ="' . $coder['option'] . '" ' . $checked . '> ' . $coder['name'];
|
||||
if ( $coder['option'] == 'official' ) {
|
||||
echo '<input type="text" size="48" id="gcal_geocoding" name="gcal_options[gcal_apikey]" value="' . $apikey . '">';
|
||||
}
|
||||
|
||||
echo '</br>' ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function gcal_debugging_section_text() {
|
||||
?>
|
||||
<p>Debugging aktivieren? Speicherort: ${APACHE_LOG_DIR}/error.log</br></br>
|
||||
Um die Performance zu verbessern, werden gefundene Geocoding-Daten zwischengespeichert. </br>
|
||||
Zu Debugging-Zwecken kann der Zwischenspeicher (Cache) des Plugins gelöscht </br>
|
||||
werden, um ein neues Geocoding aller Termin-Orte zu erzwingen. </br>
|
||||
</p>
|
||||
<?php
|
||||
}
|
||||
|
||||
|
||||
|
||||
function gcal_debugging_setting_string($args) {
|
||||
$options = get_option('gcal_options');
|
||||
// example from https://code.tutsplus.com/tutorials/the-wordpress-settings-api-part-8-validation-sanitisation-and-input-i--wp-25361
|
||||
// echo '<input type="checkbox" id="gcal_debugging" name="gcal_options[gcal_debugging]" value="1"' . checked( 1, $options['gcal_debugging'], false ) . '> Debug-Logging aktivieren </br>';
|
||||
// let's make a select box:
|
||||
?>
|
||||
<select id="gcal_debugging" name="gcal_options[gcal_debugging]">
|
||||
<option value=0 <?php selected($options['gcal_debugging'], NONE); ?>>off</option>
|
||||
<option value=1 <?php selected($options['gcal_debugging'], CRIT); ?>>critical</option>
|
||||
<option value=2 <?php selected($options['gcal_debugging'], WARN); ?>>critical + warnings</option>
|
||||
<option value=3 <?php selected($options['gcal_debugging'], INFO); ?>>critical + warnings + info</option>
|
||||
</select> </br>
|
||||
<?php
|
||||
// actual logging is done by gcal_error_log()
|
||||
// Cache reset on restart
|
||||
echo '</br><input type="checkbox" id="gcal_reset_cache" name="gcal_options[gcal_reset_cache]" value="1"' . checked( 1, $options['gcal_reset_cache'], false ) . '> Geocoding-Cache nach Deaktivieren und Aktivieren des Plugins löschen </br>';}
|
||||
|
||||
|
||||
|
||||
function gcal_options_validate($input) {
|
||||
return $input;
|
||||
|
||||
// TODO
|
||||
|
||||
/*
|
||||
$newinput['text_string'] = trim($input['text_string']);
|
||||
if(!preg_match('/^[a-z0-9]{32}$/i', $newinput['text_string'])) {
|
||||
$newinput['text_string'] = '';
|
||||
}
|
||||
return $newinput;
|
||||
*/
|
||||
}
|
||||
|
||||
|
|
@ -1,229 +0,0 @@
|
|||
<?php
|
||||
|
||||
defined( 'ABSPATH' ) or die( 'No script kiddies please!' );
|
||||
|
||||
|
||||
function gcal_import_geocity($location) {
|
||||
|
||||
// Wenn die Adresse im Feld Stadt steht, wird sie richtig angezeigt, ergo:
|
||||
$pattern = '/(.*), ([0-9]{5} [^,]+)/';
|
||||
preg_match ($pattern, $location, $matches);
|
||||
if ( empty ($matches[2])) {
|
||||
return ($location);
|
||||
} else {
|
||||
return ($matches[2]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function gcal_import_geoshow($location) {
|
||||
|
||||
// later
|
||||
// not NULL so kal3000_the_termin_geo() displays a map if lat/lon are available.
|
||||
// Hotel-Gasthof Maisberger, Bahnhofstraße 54, 85375 Neufahrn bei Freising, Deutschland
|
||||
// alles bis ", [0-9]{5}" ist geoshow
|
||||
// alles ab [0-9]{5}[\,]+ ist geocity.
|
||||
$pattern = '/(.*), ([0-9]{5} [^,]+)/';
|
||||
preg_match ($pattern, $location, $matches);
|
||||
return ($matches[1]);
|
||||
|
||||
}
|
||||
|
||||
|
||||
function gcal_import_geocode($location) {
|
||||
|
||||
// we try to cache results as we will need many times the same results especially for recurring events.
|
||||
// we will use a hash for the location because the hash has a fixed length, while the location has not.
|
||||
// This table will grow indefinitely over time, so we need to add a timestamp field and remove
|
||||
// entries that are older than, say, 30 days each time.
|
||||
// this will also cope with Google subtly changing location strings in Maps over time.
|
||||
// new entries will thus replace outdated ones over time.
|
||||
|
||||
/*
|
||||
Caching neu: in wp_options-> gcal_options ein Array geocache anlegen. Darunter für jeden hash ein Array schreiben, also:
|
||||
|
||||
Datenmodell:
|
||||
|
||||
$geocache = array (
|
||||
hash1 = array (
|
||||
'gcal_geo_lat' => '',
|
||||
'gcal_geo_lon' => '',
|
||||
'gcal_geo_timestamp' => 0,
|
||||
),
|
||||
hash2 = array ...
|
||||
);
|
||||
|
||||
|
||||
Schreiben:
|
||||
$options = get_options ( 'gcal_options' );
|
||||
|
||||
$geocache = $options ( 'geocache' );
|
||||
$geocache['hashx'] = array ( $lat, $lon, time(), );
|
||||
|
||||
$options ( 'geocache' ) = $geocache;
|
||||
|
||||
Löschen:
|
||||
|
||||
foreach ( $geocache as $key => $value ) {
|
||||
if ( $key['gcal_geo_timestamp'] < time() - 2592000 ) {
|
||||
unset ( $options['geocache']['hashx'] )
|
||||
}
|
||||
}
|
||||
|
||||
set_options ( 'gcal_options' );
|
||||
|
||||
Suchen: if ( isset ( $options['geocache']['hashx'] ) ) ...
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
if ( '' == $location ) {
|
||||
return array ('', '');
|
||||
}
|
||||
// check the cache first
|
||||
global $wpdb;
|
||||
$table = $wpdb->prefix.GCAL_GEO_TABLE;
|
||||
$hash = hash ('md5', $location);
|
||||
$query = "SELECT gcal_geo_lat, gcal_geo_lon FROM $table WHERE gcal_geo_hash = '$hash'";
|
||||
$result = $wpdb->get_row( $query, ARRAY_N );
|
||||
if ( $wpdb->num_rows == 1 ) { // it should only be a single row!
|
||||
gcal_error_log (INFO, "geocode cache hit hash $hash lat $result[0] lon $result[1]");
|
||||
} else {
|
||||
// do the housekeeping first, before we create a new caching entry.
|
||||
// remove all cache entries which are older than 30 days.
|
||||
$outdated = time() - 2592000; // 30 Tage
|
||||
$query = "DELETE FROM $table WHERE gcal_geo_timestamp < $outdated";
|
||||
$wpdb->query($query);
|
||||
|
||||
$options = get_option('gcal_options');
|
||||
$result = array ('', '');
|
||||
|
||||
switch ( $options['gcal_geocoding'] ) {
|
||||
case "official" :
|
||||
$result = gcal_import_geocode_official($location);
|
||||
break;
|
||||
case "inofficial" :
|
||||
$result = gcal_import_geocode_inofficial($location);
|
||||
break;
|
||||
case "osm" :
|
||||
$result = gcal_import_geocode_osm($location);
|
||||
break;
|
||||
}
|
||||
|
||||
$file = dirname (__FILE__) . "/geocode-result-$hash.txt";
|
||||
file_put_contents ($file, var_export ($result, TRUE));
|
||||
// do the caching now, but only if both values are set.
|
||||
// $wpdb_insert does all the sanitizing for us.
|
||||
$lat = $result[0];
|
||||
$lon = $result[1];
|
||||
if ('' != $lat && '' != $lon) {
|
||||
$wpdb->insert($table, array(
|
||||
'gcal_geo_location' => substr( $location, 0, 128 ),
|
||||
'gcal_geo_hash' => $hash,
|
||||
'gcal_geo_lat' => $lat,
|
||||
'gcal_geo_lon' => $lon,
|
||||
'gcal_geo_timestamp' => time(),
|
||||
));
|
||||
gcal_error_log (INFO, "geocoded and cached lat=$lat lon=$lon for location $location");
|
||||
}
|
||||
// error handling?
|
||||
}
|
||||
return ($result);
|
||||
}
|
||||
|
||||
|
||||
function gcal_import_geocode_official($location) {
|
||||
$options = get_option('gcal_options');
|
||||
if ( ! isset ( $options['gcal_apikey'] ) || '' == $options['gcal_apikey'] ) { // ??? we should handle this in the admin frontend.
|
||||
gcal_error_log (WARN, "using Google official geocoding but provided no APIKEY");
|
||||
return array ('','');
|
||||
} else {
|
||||
$apikey = $options['gcal_apikey'];
|
||||
$location = urlencode($location);
|
||||
$useragent = 'Mozilla/5.0 (X11; Linux x86_64; rv:57.0) Gecko/20100101 Firefox/57.0';
|
||||
// https://developers.google.com/maps/documentation/geocoding/start
|
||||
$url = "https://maps.googleapis.com/maps/api/geocode/json?address=$location&key=$apikey";
|
||||
|
||||
$response = curl_get_remote($url);
|
||||
$decoded = json_decode($response, true);
|
||||
$lat = $decoded['results']['0']['geometry']['location']['lat'];
|
||||
$lon = $decoded['results']['0']['geometry']['location']['lng'];
|
||||
gcal_error_log (INFO, __FUNCTION__ . " found lat $lat lon $lon");
|
||||
return array ($lat, $lon);
|
||||
/*
|
||||
{
|
||||
"error_message" : "The provided API key is invalid.",
|
||||
"results" : [],
|
||||
"status" : "REQUEST_DENIED"
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function gcal_import_geocode_osm($location) {
|
||||
// https://wiki.openstreetmap.org/wiki/Nominatim
|
||||
// https://nominatim.openstreetmap.org/search?q=Hotel+Gumberger+Gasthof+GmbH&format=json'
|
||||
$location = urlencode($location);
|
||||
gcal_error_log (INFO, "gcal_import_geocode_osm: location $location");
|
||||
// the main problem with Nominatim is that it doesn't understand GCal location information very well.
|
||||
// we ought to cut off the location name and the country, i.e. zip code, city & street address only
|
||||
$url = 'https://nominatim.openstreetmap.org/search?q="' . $location . '"&format=json';
|
||||
$response = wp_remote_get($url);
|
||||
$json = wp_remote_retrieve_body($response);
|
||||
$http_code = wp_remote_retrieve_response_code($response);
|
||||
// we need to catch errors
|
||||
|
||||
// https://www.php.net/manual/en/function.json-decode.php
|
||||
$decoded = json_decode($json, true);
|
||||
// TODO error handling e.g. if we get no usable values.
|
||||
/*
|
||||
$file = dirname (__FILE__) . '/json-decoded.txt';
|
||||
// should simply be ->lat and -> lon
|
||||
file_put_contents ($file, var_export ($decoded, TRUE));
|
||||
// The first array level ([0]) is only needed because OSM returns a JSON with enclosing [].
|
||||
*/
|
||||
$lat = $decoded['0']['lat'];
|
||||
$lon = $decoded['0']['lon'];
|
||||
gcal_error_log (INFO, "gcal_import_geocode_osm found lat=$lat lon=$lon loc $location");
|
||||
return array ($lat, $lon);
|
||||
}
|
||||
|
||||
|
||||
function gcal_import_geocode_inofficial($location) {
|
||||
|
||||
$attempts = 0;
|
||||
$success = false;
|
||||
// we'll need to be easy with GMaps in order no to get a 429 Too Many Requests reply.
|
||||
// max 3 retries with 2 second pauses, else we give up.
|
||||
while ($success == false && $attempts < 3) {
|
||||
// @ = 'ignore_errors' => TRUE
|
||||
$url = "https://maps.google.com/maps?q=" . urlencode ($location);
|
||||
// we use wp-remote.* instead of file_get_contents because it does many high level things e.g. redirects
|
||||
$response = wp_remote_get($url);
|
||||
$result = wp_remote_retrieve_body($response);
|
||||
$http_code = wp_remote_retrieve_response_code($response);
|
||||
if (200 == $http_code) {
|
||||
$success = true;
|
||||
} elseif (429 == $http_code) {
|
||||
time.sleep(2);
|
||||
++$attempts;
|
||||
gcal_error_log (INFO, "got $attempts HTTP 429 Too Many Requests on $url");
|
||||
} else {
|
||||
gcal_error_log (WARN, "Unspecified HTTP error $http_code");
|
||||
return array ('', '');
|
||||
}
|
||||
}
|
||||
|
||||
// ok so $result seems to be valid.
|
||||
// and now we need to look for:
|
||||
$pattern = '#www.google.com/maps/preview/place/[^/]+/@([\d\.]+),([\d\.]+),.*#';
|
||||
preg_match ($pattern, $result, $matches);
|
||||
|
||||
// and return the result:
|
||||
return array ($matches[1], $matches[2]);
|
||||
}
|
||||
|
||||
|
88
readme.txt
88
readme.txt
|
@ -1,88 +0,0 @@
|
|||
=== Kal3000 Google Calender Importer ===
|
||||
Contributors: hmilz
|
||||
Tags: kal3000, urwahl3000, calendar
|
||||
Donate link: https://www.paypal.me/HaraldMilz
|
||||
Requires at least: 4.0
|
||||
Tested up to: 4.9
|
||||
Requires PHP: 7.3
|
||||
Stable tag: 0.2.0
|
||||
License: GPLv3 or later
|
||||
License URI: https://www.gnu.org/licenses/gpl-3.0
|
||||
|
||||
Imports and Merges an Arbitrary Number of Public Google Calendars into Kal3000.
|
||||
|
||||
== Beschreibung ==
|
||||
Ein Wordpress-Plugin, das auf das Grüne Wordpress-Theme <a href="http://kre8tiv.de/urwahl3000/">Urwahl3000</a> aufsetzt und eine Integration beliebig vieler öffentlicher Google-Kalender ermöglicht.
|
||||
|
||||
Das hier ist noch "work in progress", und es ist noch nicht produktiv benutzbar! Das Plugin könnte Dein Wordpress zerschießen, Deinen Kreis- oder Ortsverband versehentlich auflösen oder den Klimawandel beschleunigen! Aber für mich funktioniert es schon recht ordentlich.
|
||||
|
||||
* Administration in Wordpress über die Admin-Oberfläche.
|
||||
* Einbinden beliebig vieler Google-Kalender.
|
||||
* Zuordnung dieser Google-Kalender zu bereits angelegten Terminkategorien, beispielsweise je OV.
|
||||
* Geocoding von Veranstaltungsorten, wie sie aus Google Kalender übernommen werden. Derart angelegte Termine werden auf der Übersichtskarte richtig angezeigt.
|
||||
|
||||
|
||||
== Installation ==
|
||||
|
||||
1. Um eine auf Urwahl3000 und Wordpress basierende KV- oder OV-Seite betreiben zu können, braucht man zunächst eine irgendwo gehostete aktuelle Wordpress-Umgebung. Dazu wird auf die Dokumentation von Urwahl3000 verwiesen.
|
||||
|
||||
2. Als nächstes holt man sich das Plugin unter <a href="http://www.seneca.muc.de/kal3000-gcal-import/">http://www.seneca.muc.de/kal3000-gcal-import/</a> und installiert es über die WP-Oberfläche wie gewohnt.
|
||||
|
||||
Hinweis: kal3000-gcal-import nutzt für das Parsen von ICAL-Files und -Feeds das PHP-Modul icalparser (https://github.com/OzzyCzech/icalparser). Die Verwendung und die Einbindung in die Release-ZIP-Files erfolgt mit freundlicher Genehmigung des Autors Roman Ožana.
|
||||
|
||||
== Konfiguration ==
|
||||
|
||||
1. in WP legt man Terminkategorien an, z.B. eine pro OV und eine für den KV, plus weitere nach Bedarf. Das funktioniert am besten mit einer entsprechenden Seitenhierarchie wie auf https://www.gruene-freising.de/... .
|
||||
|
||||
2. Im Admin-Teil des Plugins unter "Einstellungen / GCal Importer" erscheinen die angelegten Terminkategorien. Jeder Kategorie weist man dann einen öffentlichen Google-Kalender in Form des "public ics"-Links zu, beispielsweise <a href="https://calendar.google.com/calendar/ical/gruene.freising%40gmail.com/public/basic.ics">https://calendar.google.com/calendar/ical/gruene.freising%40gmail.com/public/basic.ics</a>.
|
||||
|
||||
3. Im Admin-Teil kann man das Zeitintervall einstellen, mit dem die Kalender synchronisiert werden. Standardeinstellung ist 60 Minuten. Bitte beachten, dass der Wordpress-Scheduler die Zeitintervalle nur ungefähr und abhängig von der Seitenaktivität einhält.
|
||||
|
||||
4. Im Admin-Teil kann man das Geocoding aktivieren. Derzeit ist nur ein inoffizieller Weg über Google Maps verfügbar, den Google nicht gerne sieht. Das offizielle <a href="https://developers.google.com/maps/documentation/geocoding/start">Google-API</a> erfordert einen API-Key, der bei intensiver Nutzung nicht kostenlos ist. Auf die Google-Policy wird hingewiesen. Außerdem ist OpenStreetMap verfügbar, aber es kann nicht sehr gut mit den Lokationen aus Google Maps umgehen. Im Moment ist es benutzbar, funktioniert aber nicht zuverlässig.
|
||||
|
||||
5. Speichern und fertig.
|
||||
|
||||
Unter "Debugging" finden sich zwei weitere Einstellungen:
|
||||
|
||||
1. zum einen kann man ein Debug-Logging aktivieren, mit dem das Plugin Einträge in ${APACHE_LOG_DIR}/error.log schreibt. NONE schreibt nichts, CRIT (critical) am wenigsten, INFO (alles) am meisten.
|
||||
|
||||
2. Die zweite Einstellung löscht den Geocoding-Cache bei jedem Plugin-Neustart, um das Geocoding für jede Lokation neu zu erzwingen, beispielsweise wenn man die Geocoding-Methode geändert hat.
|
||||
|
||||
== Benutzung ==
|
||||
|
||||
Um die Termine in WP anzuzeigen, gibt es zwei Wege: Das Termine-Widget in der rechten Spalte zeigt immer alle Termine an. Darüber hinaus kann man beispielsweise pro OV eine Unterseite mit dem Titel "OV Termine" anlegen, in der folgender Shortcode steht: <code>[wpcalendar kat=TERMINKATEGORIE]</code>. Auf dieser Seite werden dann nur die Termine des dazugehörigen OV angezeigt.
|
||||
|
||||
Mit "Aktivieren" beginnt das Plugin sofort mit der Synchronisation.
|
||||
|
||||
|
||||
== Frequently Asked Questions ==
|
||||
|
||||
Keine bisher.
|
||||
|
||||
== Changelog ==
|
||||
|
||||
= 0.3.1 =
|
||||
* multi-level debugging
|
||||
* OSM geocoding (unstable)
|
||||
* secret events handling
|
||||
* using cURL for more stability in some places
|
||||
* added geocoding cache reset on restart option
|
||||
* geoshow / geocity mapping
|
||||
|
||||
= 0.3 =
|
||||
* new branch
|
||||
* added OpenStreetMap geocoding
|
||||
|
||||
= 0.2 =
|
||||
* First fully functioning release.
|
||||
|
||||
= 0.1 =
|
||||
* Initial release.
|
||||
|
||||
== Upgrade Notice ==
|
||||
= 0.2 =
|
||||
Upgrade notices describe the reason a user should upgrade
|
||||
|
||||
= 0.1 =
|
||||
This version fixes a security related bug. Upgrade immediately.
|
||||
|
202
wolkal3000-admin.php
Normal file
202
wolkal3000-admin.php
Normal file
|
@ -0,0 +1,202 @@
|
|||
<?php
|
||||
|
||||
defined( 'ABSPATH' ) or die( 'No script kiddies please!' );
|
||||
|
||||
require_once dirname( __FILE__ ) . "/wolkal3000-config.php";
|
||||
|
||||
/**
|
||||
* Display the admin table
|
||||
*
|
||||
* @since 0.1.0
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Quellen:
|
||||
* https://codex.wordpress.org/Creating_Options_Pages
|
||||
* http://ottopress.com/2009/wordpress-settings-api-tutorial/
|
||||
*/
|
||||
|
||||
add_action('admin_menu', 'wolkal3000_admin_add_page');
|
||||
|
||||
function wolkal3000_admin_add_page() {
|
||||
add_options_page( 'WolKal3000 – Synchronisation von Kal3000 mit Wolke-Kalendern', 'WolKal3000', 'manage_options', 'wolkal3000', 'wolkal3000_options_page');
|
||||
}
|
||||
|
||||
function wolkal3000_options_page() {
|
||||
|
||||
if ( !current_user_can( 'manage_options' ) ) {
|
||||
wp_die( __( 'You do not have sufficient permissions to access this page.' ) );
|
||||
}
|
||||
if ( !defined('WOLKAL_PREFIX') ) {
|
||||
wp_die( __( 'WOLKAL_PREFIX is not configured in wolkal3000-config.php, please check the installation steps!' ) );
|
||||
}
|
||||
if ( !file_exists(__DIR__ . '/icalparser/src/IcalParser.php')) {
|
||||
wp_die( __( 'icalparser is not properly installed, please check the installation steps!' ) );
|
||||
}
|
||||
?>
|
||||
|
||||
<div class="wrap">
|
||||
<h1><?= esc_html(get_admin_page_title()); ?></h1>
|
||||
<p>Mit WolKal3000 kannst du dein Kal3000-Plugin automatisch mit Kalendern in der grünen Wolke synchronisieren.</p>
|
||||
|
||||
<form action="options.php" method="post">
|
||||
<?php settings_fields('wolkal3000_options'); ?>
|
||||
<?php do_settings_sections('wolkal3000'); ?>
|
||||
<input name="Submit" type="submit" value="<?php esc_attr_e('Save Changes'); ?>" />
|
||||
</br></br></br><hr></br>
|
||||
<?php do_settings_sections('wolkal3000_adv'); ?>
|
||||
<input name="Submit" type="submit" value="<?php esc_attr_e('Save Changes'); ?>" />
|
||||
</form></div>
|
||||
|
||||
<?php
|
||||
}
|
||||
|
||||
add_action('admin_init', 'wolkal3000_admin_init');
|
||||
|
||||
function wolkal3000_admin_init(){
|
||||
register_setting( 'wolkal3000_options', 'wolkal3000_options', 'wolkal3000_options_validate' );
|
||||
add_settings_section('wolkal3000_feeds', 'Wolke-Kalender einer Terminkategorie zuordnen', 'wolkal3000_feeds_section_text', 'wolkal3000');
|
||||
|
||||
// settings fields dynamisch pro Feed generieren, nur ein Callback mit Args nutzen.
|
||||
$terms = get_terms( array(
|
||||
'taxonomy' => 'termine_type',
|
||||
'hide_empty' => false, )
|
||||
);
|
||||
foreach($terms as $term){
|
||||
$unique_id = 'wolkal3000_feed_' . $term->name;
|
||||
$feed_name = $term->name;
|
||||
add_settings_field($unique_id, 'Terminkategorie "'.$feed_name.'"', 'wolkal3000_feeds_setting_string', 'wolkal3000', 'wolkal3000_feeds', array($unique_id));
|
||||
}
|
||||
|
||||
add_settings_section('wolkal3000_timer', 'Synchronisationsintervall', 'wolkal3000_timer_section_text', 'wolkal3000');
|
||||
add_settings_field('wolkal3000_timer', 'Synchronisiere alle …', 'wolkal3000_timer_setting_string', 'wolkal3000', 'wolkal3000_timer');
|
||||
|
||||
add_settings_section('wolkal3000_geocoding', 'Geocoding (EXPERIMENTELL)', 'wolkal3000_geocoding_section_text', 'wolkal3000_adv');
|
||||
add_settings_field('wolkal3000_geocoding', 'Geocoding-Methode', 'wolkal3000_geocoding_setting_string', 'wolkal3000_adv', 'wolkal3000_geocoding');
|
||||
|
||||
add_settings_section('wolkal3000_debugging', 'Entwickler*innenoptionen', 'wolkal3000_debugging_section_text', 'wolkal3000_adv');
|
||||
add_settings_field('wolkal3000_debugging', 'Debugging', 'wolkal3000_debugging_setting_string', 'wolkal3000_adv', 'wolkal3000_debugging');
|
||||
}
|
||||
|
||||
|
||||
function wolkal3000_feeds_section_text() {
|
||||
?>
|
||||
<p><b>Wolke-Kalender synchronisieren in eine ausgewählte Terminkategorie von Kal3000. Bitte trage hierfür die entsprechende Export-Adresse des gewünschten Wolke-Kalenders ein.</b></br><b>Falls zu einer Terminkategorie kein Wolke-Kalender synchronisiert werden soll, entsprechendes Feld bitte leer lassen.</b></p>
|
||||
<p><b><a href="https://confluence.netzbegruenung.de/pages/viewpage.action?pageId=40730689" target="_blank">Erfahre mehr darüber, wie du die Export-Adresse eines Wolke-Kalenders findest.</a></b>
|
||||
</p>
|
||||
<?php
|
||||
}
|
||||
|
||||
|
||||
|
||||
function wolkal3000_feeds_setting_string($args) {
|
||||
$options = get_option('wolkal3000_options');
|
||||
$placeholder = "ABCDEFGHIKLMNOPQ";
|
||||
// die id entspricht dem unique_id in add_settings_field.
|
||||
// der name wird options.php als Name der zu setzenden Option übergeben
|
||||
// der Value ist der inhalt von der $option[unique_id].
|
||||
echo WOLKAL_PREFIX . '<input type="text" id="' . $args[0] . '" name="wolkal3000_options[' . $args[0] . ']" value="' . $options[$args[0]] . '" size="16" maxlength="16" placeholder="' . $placeholder . '" >' . WOLKAL_SUFFIX . '</br>';
|
||||
}
|
||||
|
||||
|
||||
function wolkal3000_timer_section_text() {
|
||||
?>
|
||||
<p><b>In welcher Regelmäßigkeit sollen die Wolke-Kalender synchronisiert werden? Bitte Zeitintervall in Minuten angeben.</b></br>
|
||||
<b>Achtung: Um Änderungen wirksam werden zu lassen, muss das Plugin deaktiviert und wieder aktiviert werden. (Menüpunkt "Plugins")</b></p>
|
||||
<?php
|
||||
}
|
||||
|
||||
|
||||
function wolkal3000_timer_setting_string() {
|
||||
$options = get_option('wolkal3000_options');
|
||||
$placeholder = "default 60";
|
||||
echo '<input type="text" id="wolkal3000_timer" name="wolkal3000_options[wolkal3000_timer]" value="' . $options['wolkal3000_timer'] . '" size="6" maxlength="4" placeholder="' . $placeholder . '" > Minuten </br>';
|
||||
}
|
||||
|
||||
|
||||
|
||||
function wolkal3000_geocoding_section_text() {
|
||||
?>
|
||||
<p>Damit der Termin-Ort auf einer Karte eingezeichnet werden kann, müssen die Ortsinformationen von der Textform in geografische Länge und Breite umgerechnet werden.</br>Dies nennt sich Geocoding. Dabei handelt es sich um eine experimentelle Funktion von WolKal3000.</p>
|
||||
<?php
|
||||
}
|
||||
|
||||
|
||||
function wolkal3000_geocoding_setting_string() {
|
||||
$options = get_option('wolkal3000_options');
|
||||
$current = ( isset ($options['wolkal3000_geocoding']) ? $options['wolkal3000_geocoding'] : 'off' ); // default off
|
||||
|
||||
$coders = array(
|
||||
array(
|
||||
'option' => 'off',
|
||||
'name' => 'deaktiviert',
|
||||
), /*
|
||||
array(
|
||||
'option' => 'official',
|
||||
'name' => 'Google official - erfordert einen API Key --> ',
|
||||
),
|
||||
array(
|
||||
'option' => 'inofficial',
|
||||
'name' => 'Google inofficial',
|
||||
), */
|
||||
array(
|
||||
'option' => 'osm',
|
||||
'name' => 'OpenStreetMap (EXPERIMENTELL)',
|
||||
),
|
||||
);
|
||||
|
||||
foreach ( $coders as $coder ) {
|
||||
$checked = ( $current == $coder['option'] ? 'checked' : '' );
|
||||
echo '<input type="radio" id="wolkal3000_geocoding" name="wolkal3000_options[wolkal3000_geocoding]" value ="' . $coder['option'] . '" ' . $checked . '> ' . $coder['name'];
|
||||
echo '</br>' ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function wolkal3000_debugging_section_text() {
|
||||
?>
|
||||
<p>Debugging aktivieren? Speicherort: ${APACHE_LOG_DIR}/error.log</br></br>
|
||||
Um die Performance zu verbessern, werden gefundene Geocoding-Daten zwischengespeichert. </br>
|
||||
Zu Debugging-Zwecken kann der Zwischenspeicher (Cache) des Plugins gelöscht </br>
|
||||
werden, um ein neues Geocoding aller Termin-Orte zu erzwingen. </br>
|
||||
</p>
|
||||
<?php
|
||||
}
|
||||
|
||||
|
||||
|
||||
function wolkal3000_debugging_setting_string($args) {
|
||||
$options = get_option('wolkal3000_options');
|
||||
// example from https://code.tutsplus.com/tutorials/the-wordpress-settings-api-part-8-validation-sanitisation-and-input-i--wp-25361
|
||||
// echo '<input type="checkbox" id="wolkal3000_debugging" name="wolkal3000_options[wolkal3000_debugging]" value="1"' . checked( 1, $options['wolkal3000_debugging'], false ) . '> Debug-Logging aktivieren </br>';
|
||||
// let's make a select box:
|
||||
?>
|
||||
<select id="wolkal3000_debugging" name="wolkal3000_options[wolkal3000_debugging]">
|
||||
<option value=0 <?php selected($options['wolkal3000_debugging'], NONE); ?>>off</option>
|
||||
<option value=1 <?php selected($options['wolkal3000_debugging'], CRIT); ?>>critical</option>
|
||||
<option value=2 <?php selected($options['wolkal3000_debugging'], WARN); ?>>critical + warnings</option>
|
||||
<option value=3 <?php selected($options['wolkal3000_debugging'], INFO); ?>>critical + warnings + info</option>
|
||||
</select> </br>
|
||||
<?php
|
||||
// actual logging is done by wolkal3000_error_log()
|
||||
// Cache reset on restart
|
||||
echo '</br><input type="checkbox" id="wolkal3000_reset_cache" name="wolkal3000_options[wolkal3000_reset_cache]" value="1"' . checked( 1, $options['wolkal3000_reset_cache'], false ) . '> Geocoding-Cache nach Deaktivieren und Aktivieren des Plugins löschen </br>';}
|
||||
|
||||
|
||||
|
||||
function wolkal3000_options_validate($input) {
|
||||
return $input;
|
||||
|
||||
// TODO
|
||||
|
||||
/*
|
||||
$newinput['text_string'] = trim($input['text_string']);
|
||||
if(!preg_match('/^[a-z0-9]{32}$/i', $newinput['text_string'])) {
|
||||
$newinput['text_string'] = '';
|
||||
}
|
||||
return $newinput;
|
||||
*/
|
||||
}
|
||||
|
||||
|
10
wolkal3000-config.php
Normal file
10
wolkal3000-config.php
Normal file
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
define ('WOLKAL_PREFIX', 'https://wolke.netzbegruenung.de/remote.php/dav/public-calendars/');
|
||||
define ('WOLKAL_SUFFIX', '?export');
|
||||
define ('WOLKAL3000_GEO_TABLE', 'wolkal3000_geocache');
|
||||
// For wolkal3000_error_log
|
||||
define ('INFO', 3);
|
||||
define ('WARN', 2);
|
||||
define ('CRIT', 1);
|
||||
define ('NONE', 0);
|
||||
?>
|
158
wolkal3000-geocode.php
Normal file
158
wolkal3000-geocode.php
Normal file
|
@ -0,0 +1,158 @@
|
|||
<?php
|
||||
|
||||
defined( 'ABSPATH' ) or die( 'No script kiddies please!' );
|
||||
|
||||
|
||||
function wolkal3000_geocity($location) {
|
||||
|
||||
// Wenn die Adresse im Feld Stadt steht, wird sie richtig angezeigt, ergo:
|
||||
$pattern = '/(.*), ([0-9]{5} [^,]+)/';
|
||||
preg_match ($pattern, $location, $matches);
|
||||
if ( empty ($matches[2])) {
|
||||
return ($location);
|
||||
} else {
|
||||
return ($matches[2]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function wolkal3000_geoshow($location) {
|
||||
|
||||
// later
|
||||
// not NULL so kal3000_the_termin_geo() displays a map if lat/lon are available.
|
||||
// Hotel-Gasthof Maisberger, Bahnhofstraße 54, 85375 Neufahrn bei Freising, Deutschland
|
||||
// alles bis ", [0-9]{5}" ist geoshow
|
||||
// alles ab [0-9]{5}[\,]+ ist geocity.
|
||||
$pattern = '/(.*), ([0-9]{5} [^,]+)/';
|
||||
preg_match ($pattern, $location, $matches);
|
||||
return ($matches[1]);
|
||||
|
||||
}
|
||||
|
||||
|
||||
function wolkal3000_geocode($location) {
|
||||
|
||||
// we try to cache results as we will need many times the same results especially for recurring events.
|
||||
// we will use a hash for the location because the hash has a fixed length, while the location has not.
|
||||
// This table will grow indefinitely over time, so we need to add a timestamp field and remove
|
||||
// entries that are older than, say, 30 days each time.
|
||||
// this will also cope with Google subtly changing location strings in Maps over time.
|
||||
// new entries will thus replace outdated ones over time.
|
||||
|
||||
/*
|
||||
Caching neu: in wp_options-> wolkal3000_options ein Array geocache anlegen. Darunter für jeden hash ein Array schreiben, also:
|
||||
|
||||
Datenmodell:
|
||||
|
||||
$geocache = array (
|
||||
hash1 = array (
|
||||
'wolkal3000_geo_lat' => '',
|
||||
'wolkal3000_geo_lon' => '',
|
||||
'wolkal3000_geo_timestamp' => 0,
|
||||
),
|
||||
hash2 = array ...
|
||||
);
|
||||
|
||||
|
||||
Schreiben:
|
||||
$options = get_options ( 'wolkal3000_options' );
|
||||
|
||||
$geocache = $options ( 'geocache' );
|
||||
$geocache['hashx'] = array ( $lat, $lon, time(), );
|
||||
|
||||
$options ( 'geocache' ) = $geocache;
|
||||
|
||||
Löschen:
|
||||
|
||||
foreach ( $geocache as $key => $value ) {
|
||||
if ( $key['wolkal3000_geo_timestamp'] < time() - 2592000 ) {
|
||||
unset ( $options['geocache']['hashx'] )
|
||||
}
|
||||
}
|
||||
|
||||
set_options ( 'wolkal3000_options' );
|
||||
|
||||
Suchen: if ( isset ( $options['geocache']['hashx'] ) ) ...
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
if ( '' == $location ) {
|
||||
return array ('', '');
|
||||
}
|
||||
// check the cache first
|
||||
global $wpdb;
|
||||
$table = $wpdb->prefix.WOLKAL3000_GEO_TABLE;
|
||||
$hash = hash ('md5', $location);
|
||||
$query = "SELECT wolkal3000_geo_lat, wolkal3000_geo_lon FROM $table WHERE wolkal3000_geo_hash = '$hash'";
|
||||
$result = $wpdb->get_row( $query, ARRAY_N );
|
||||
if ( $wpdb->num_rows == 1 ) { // it should only be a single row!
|
||||
wolkal3000_error_log (INFO, "geocode cache hit hash $hash lat $result[0] lon $result[1]");
|
||||
} else {
|
||||
// do the housekeeping first, before we create a new caching entry.
|
||||
// remove all cache entries which are older than 30 days.
|
||||
$outdated = time() - 2592000; // 30 Tage
|
||||
$query = "DELETE FROM $table WHERE wolkal3000_geo_timestamp < $outdated";
|
||||
$wpdb->query($query);
|
||||
|
||||
$options = get_option('wolkal3000_options');
|
||||
$result = array ('', '');
|
||||
|
||||
switch ( $options['wolkal3000_geocoding'] ) {
|
||||
case "osm" :
|
||||
$result = wolkal3000_geocode_osm($location);
|
||||
break;
|
||||
}
|
||||
|
||||
$file = dirname (__FILE__) . "/geocode-result-$hash.txt";
|
||||
file_put_contents ($file, var_export ($result, TRUE));
|
||||
// do the caching now, but only if both values are set.
|
||||
// $wpdb_insert does all the sanitizing for us.
|
||||
$lat = $result[0];
|
||||
$lon = $result[1];
|
||||
if ('' != $lat && '' != $lon) {
|
||||
$wpdb->insert($table, array(
|
||||
'wolkal3000_geo_location' => substr( $location, 0, 128 ),
|
||||
'wolkal3000_geo_hash' => $hash,
|
||||
'wolkal3000_geo_lat' => $lat,
|
||||
'wolkal3000_geo_lon' => $lon,
|
||||
'wolkal3000_geo_timestamp' => time(),
|
||||
));
|
||||
wolkal3000_error_log (INFO, "geocoded and cached lat=$lat lon=$lon for location $location");
|
||||
}
|
||||
// error handling?
|
||||
}
|
||||
return ($result);
|
||||
}
|
||||
|
||||
|
||||
function wolkal3000_geocode_osm($location) {
|
||||
// https://wiki.openstreetmap.org/wiki/Nominatim
|
||||
// https://nominatim.openstreetmap.org/search?q=Hotel+Gumberger+Gasthof+GmbH&format=json'
|
||||
$location = urlencode($location);
|
||||
wolkal3000_error_log (INFO, "wolkal3000_geocode_osm: location $location");
|
||||
// the main problem with Nominatim is that it doesn't understand calendar location information very well.
|
||||
// we ought to cut off the location name and the country, i.e. zip code, city & street address only
|
||||
$url = 'https://nominatim.openstreetmap.org/search?q="' . $location . '"&format=json';
|
||||
$response = wp_remote_get($url);
|
||||
$json = wp_remote_retrieve_body($response);
|
||||
$http_code = wp_remote_retrieve_response_code($response);
|
||||
// we need to catch errors
|
||||
|
||||
// https://www.php.net/manual/en/function.json-decode.php
|
||||
$decoded = json_decode($json, true);
|
||||
// TODO error handling e.g. if we get no usable values.
|
||||
/*
|
||||
$file = dirname (__FILE__) . '/json-decoded.txt';
|
||||
// should simply be ->lat and -> lon
|
||||
file_put_contents ($file, var_export ($decoded, TRUE));
|
||||
// The first array level ([0]) is only needed because OSM returns a JSON with enclosing [].
|
||||
*/
|
||||
$lat = $decoded['0']['lat'];
|
||||
$lon = $decoded['0']['lon'];
|
||||
wolkal3000_error_log (INFO, "wolkal3000_geocode_osm found lat=$lat lon=$lon loc $location");
|
||||
return array ($lat, $lon);
|
||||
}
|
||||
|
|
@ -7,7 +7,7 @@ defined( 'ABSPATH' ) or die( 'No script kiddies please!' );
|
|||
// we'll set this as category => proxy, link => link, active => 0;
|
||||
// in the admin page, all entries will be displayed with a checkbox for activating, deactivating, deleting.
|
||||
|
||||
require_once __DIR__ . "/gcal-import-geocode.php";
|
||||
require_once __DIR__ . "/wolkal3000-geocode.php";
|
||||
|
||||
|
||||
/**
|
||||
|
@ -17,7 +17,7 @@ require_once __DIR__ . "/gcal-import-geocode.php";
|
|||
*
|
||||
*/
|
||||
|
||||
function gcal_import_worker() {
|
||||
function wolkal3000_worker() {
|
||||
|
||||
/*
|
||||
* retrieve the proxy from the db, and if it exists, construct a context.
|
||||
|
@ -26,16 +26,16 @@ function gcal_import_worker() {
|
|||
* http://www.pirob.com/2013/06/php-using-getheaders-and-filegetcontents-functions-behind-proxy.html
|
||||
*/
|
||||
|
||||
gcal_error_log (INFO, __FUNCTION__ . " started");
|
||||
$options = get_option('gcal_options');
|
||||
wolkal3000_error_log (INFO, __FUNCTION__ . " started");
|
||||
$options = get_option('wolkal3000_options');
|
||||
$terms = get_terms( array(
|
||||
'taxonomy' => 'termine_type',
|
||||
'hide_empty' => false, )
|
||||
);
|
||||
foreach($terms as $term){
|
||||
$unique_id = 'gcal_feed_' . $term->name;
|
||||
$unique_id = 'wolkal3000_feed_' . $term->name;
|
||||
if ( empty ( $options[$unique_id] ) || $options[$unique_id] == '' ) {
|
||||
gcal_error_log (INFO, "link for event category $term->name is not known; next");
|
||||
wolkal3000_error_log (INFO, "link for event category $term->name is not known; next");
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -50,11 +50,11 @@ The update and delete logic goes as follows:
|
|||
Apparently, they were deleted on the remote end.
|
||||
*/
|
||||
|
||||
// so we look for all published event posts in the GCal event category
|
||||
// so we look for all published event posts in the calendar event category
|
||||
$args = array (
|
||||
'post_type' => 'termine',
|
||||
'post_status' => 'publish',
|
||||
'meta_key' => '_gcal_category',
|
||||
'meta_key' => '_wolkal3000_category',
|
||||
'meta_value' => $term->name,
|
||||
);
|
||||
$post_ids = get_posts( $args );
|
||||
|
@ -62,13 +62,13 @@ The update and delete logic goes as follows:
|
|||
if(is_array($post_ids)) {
|
||||
foreach( $post_ids as $post_id ) {
|
||||
$id = $post_id->ID;
|
||||
update_post_meta( $id, '_gcal_recent', 'false' );
|
||||
update_post_meta( $id, '_wolkal3000_recent', 'false' );
|
||||
}
|
||||
}
|
||||
// now we process the current feed.
|
||||
$link = $options[$unique_id];
|
||||
gcal_error_log (INFO, "importing event category $term->name");
|
||||
gcal_import_do_import($term->name, $link);
|
||||
$link = WOLKAL_PREFIX . $options[$unique_id] . WOLKAL_SUFFIX;
|
||||
wolkal3000_error_log (INFO, "importing event category $term->name");
|
||||
wolkal3000_do_import($term->name, $link);
|
||||
|
||||
// look if there are any published event posts in the current event category which were not posted anew or updated (ie recent == false)
|
||||
$args = array (
|
||||
|
@ -76,11 +76,11 @@ The update and delete logic goes as follows:
|
|||
'post_status' => 'publish',
|
||||
'meta_query' => array(
|
||||
array(
|
||||
'key' => '_gcal_category',
|
||||
'key' => '_wolkal3000_category',
|
||||
'value' => $term->name,
|
||||
),
|
||||
array(
|
||||
'key' => '_gcal_recent',
|
||||
'key' => '_wolkal3000_recent',
|
||||
'value' => 'false',
|
||||
),
|
||||
)
|
||||
|
@ -91,14 +91,14 @@ The update and delete logic goes as follows:
|
|||
foreach( $post_ids as $post_id ) {
|
||||
$id = $post_id->ID;
|
||||
wp_trash_post( $id );
|
||||
gcal_error_log (INFO, "Event post $id gelöscht.");
|
||||
wolkal3000_error_log (INFO, "Event post $id gelöscht.");
|
||||
}
|
||||
}
|
||||
}
|
||||
gcal_error_log (INFO, __FUNCTION__ . " finished");
|
||||
wolkal3000_error_log (INFO, __FUNCTION__ . " finished");
|
||||
}
|
||||
|
||||
add_action( 'gcal_import_worker_hook', 'gcal_import_worker' );
|
||||
add_action( 'wolkal3000_worker_hook', 'wolkal3000_worker' );
|
||||
|
||||
|
||||
require_once __DIR__ . '/icalparser/src/IcalParser.php';
|
||||
|
@ -116,7 +116,7 @@ function curl_get_remote($url) {
|
|||
if ( curl_errno($ch) ) {
|
||||
// $info = curl_getinfo($ch);
|
||||
$message = __FUNCTION__ . ": cURL error " . curl_error($ch);
|
||||
// gcal_error_log (WARN, $message);
|
||||
// wolkal3000_error_log (WARN, $message);
|
||||
curl_close($ch);
|
||||
throw new \RuntimeException($message);
|
||||
}
|
||||
|
@ -126,7 +126,7 @@ function curl_get_remote($url) {
|
|||
}
|
||||
|
||||
|
||||
function gcal_import_do_import($category, $link) {
|
||||
function wolkal3000_do_import($category, $link) {
|
||||
|
||||
$my_latlon = array('', '');
|
||||
$cal = new \om\IcalParser();
|
||||
|
@ -152,7 +152,7 @@ function gcal_import_do_import($category, $link) {
|
|||
if ($r['DTEND'] < $now) {
|
||||
continue;
|
||||
} else {
|
||||
gcal_error_log (INFO, "processing $summary on $dtstart");
|
||||
wolkal3000_error_log (INFO, "processing $summary on $dtstart");
|
||||
}
|
||||
|
||||
// The zeitstempel. No idea what it's for, but kal3000 seems to use it.
|
||||
|
@ -176,11 +176,11 @@ function gcal_import_do_import($category, $link) {
|
|||
}
|
||||
|
||||
// geocoden
|
||||
$options = get_option('gcal_options');
|
||||
if ( $options['gcal_geocoding'] != "off" ) {
|
||||
$options = get_option('wolkal3000_options');
|
||||
if ( $options['wolkal3000_geocoding'] != "off" ) {
|
||||
|
||||
$location = urldecode ($r['LOCATION']);
|
||||
$my_latlon = gcal_import_geocode($location);
|
||||
$my_latlon = wolkal3000_geocode($location);
|
||||
$file = dirname (__FILE__) . "/latlon-$hash.txt";
|
||||
file_put_contents ($file, var_export ($my_latlon, TRUE));
|
||||
}
|
||||
|
@ -222,7 +222,7 @@ function gcal_import_do_import($category, $link) {
|
|||
// create image attachment and associate with new post
|
||||
$attach = $r['ATTACH'];
|
||||
$summary = $r['SUMMARY'];
|
||||
gcal_error_log (INFO, "found attachment $attach for $summary");
|
||||
wolkal3000_error_log (INFO, "found attachment $attach for $summary");
|
||||
}
|
||||
|
||||
if ( isset ( $r['CLASS'] ) && 'PRIVATE' == $r['CLASS']) {
|
||||
|
@ -260,20 +260,20 @@ function gcal_import_do_import($category, $link) {
|
|||
$post->meta_input = array(
|
||||
'_wpcal_from' => $r['DTSTART']->format('d.m.Y H:i'),
|
||||
'_bis' => $r['DTEND']->format('d.m.Y H:i'),
|
||||
'_geostadt' => gcal_import_geocity($r['LOCATION']),
|
||||
'_geoshow' => gcal_import_geoshow($r['LOCATION']),
|
||||
'_geostadt' => wolkal3000_geocity($r['LOCATION']),
|
||||
'_geoshow' => wolkal3000_geoshow($r['LOCATION']),
|
||||
'_lat' => $my_latlon[0],
|
||||
'_lon' => $my_latlon[1],
|
||||
'_zoom' => '7',
|
||||
'_veranstalter' => '',
|
||||
'_veranstalterlnk' => '',
|
||||
'_zeitstempel' => $zeitstempel,
|
||||
'_gcal_uid' => $r['UID'],
|
||||
'_gcal_recent' => 'true',
|
||||
// '_gcal_created' => $r['LAST-MODIFIED']->format('U'),
|
||||
// '_gcal_created' => $r['LAST-MODIFIED']->format('d.m.Y H:i'),
|
||||
// '_gcal_created' => $r['LAST-MODIFIED']->format('U'),
|
||||
'_gcal_category' => $category,
|
||||
'_wolkal3000_uid' => $r['UID'],
|
||||
'_wolkal3000_recent' => 'true',
|
||||
// '_wolkal3000_created' => $r['LAST-MODIFIED']->format('U'),
|
||||
// '_wolkal3000_created' => $r['LAST-MODIFIED']->format('d.m.Y H:i'),
|
||||
// '_wolkal3000_created' => $r['LAST-MODIFIED']->format('U'),
|
||||
'_wolkal3000_category' => $category,
|
||||
'_secretevent' => $secretevent,
|
||||
);
|
||||
|
||||
|
@ -285,7 +285,7 @@ function gcal_import_do_import($category, $link) {
|
|||
'post_status' => 'publish',
|
||||
'meta_query' => array(
|
||||
array(
|
||||
'key' => '_gcal_uid',
|
||||
'key' => '_wolkal3000_uid',
|
||||
'value' => $r['UID'],
|
||||
),
|
||||
array(
|
||||
|
@ -302,7 +302,7 @@ function gcal_import_do_import($category, $link) {
|
|||
$post_id = wp_insert_post( $post );
|
||||
if ( is_wp_error( $post_id ) ) {
|
||||
$message = $post_id->get_error_message();
|
||||
gcal_error_log ( WARN, $message );
|
||||
wolkal3000_error_log ( WARN, $message );
|
||||
} else {
|
||||
update_post_meta( $post_id, '_edit_last', $user_id );
|
||||
$now = time();
|
||||
|
@ -310,12 +310,12 @@ function gcal_import_do_import($category, $link) {
|
|||
update_post_meta( $post_id, '_edit_lock', $lock );
|
||||
// and assign the taxonomy type and event category.
|
||||
wp_set_object_terms( $post_id, $category, 'termine_type' );
|
||||
gcal_error_log (INFO, "posted new post $post_id");
|
||||
wolkal3000_error_log (INFO, "posted new post $post_id");
|
||||
}
|
||||
} else {
|
||||
// good, the post exists already.
|
||||
$id = $post_ids[0]->ID;
|
||||
$created = get_post_meta( $id, '_gcal_created', true );
|
||||
$created = get_post_meta( $id, '_wolkal3000_created', true );
|
||||
$lastmodified = $r['LAST-MODIFIED']->format('U');
|
||||
// was it updated on the remote calendar? (was if modified after it was created remotely?)
|
||||
if ( $lastmodified > $created ) {
|
||||
|
@ -323,17 +323,17 @@ function gcal_import_do_import($category, $link) {
|
|||
$post->ID = $id ;
|
||||
$post_id = wp_update_post( $post, false );
|
||||
// and update the _created field
|
||||
update_post_meta ( $id, '_gcal_created', $lastmodified );
|
||||
gcal_error_log (INFO, "updated post $post_id");
|
||||
update_post_meta ( $id, '_wolkal3000_created', $lastmodified );
|
||||
wolkal3000_error_log (INFO, "updated post $post_id");
|
||||
} elseif ( $lastmodified < $created ) {
|
||||
// iiiiek! A time reversal or a secret time machine! That should not happen!
|
||||
gcal_error_log (WARN, "post $id last-modified : created $lastmodified < $created ");
|
||||
wolkal3000_error_log (WARN, "post $id last-modified : created $lastmodified < $created ");
|
||||
} // else both are equal, and we do nothing except setting recent to true.
|
||||
update_post_meta ( $id, '_gcal_recent', 'true' );
|
||||
update_post_meta ( $id, '_wolkal3000_recent', 'true' );
|
||||
}
|
||||
} else {
|
||||
$file = dirname (__FILE__) . '/get_posts-' . $post->post_name . '.txt';
|
||||
gcal_error_log (WARN, "hmmm, get_posts() did not return an array. Logging to $file");
|
||||
wolkal3000_error_log (WARN, "hmmm, get_posts() did not return an array. Logging to $file");
|
||||
file_put_contents ($file, var_export ($post_ids, TRUE));
|
||||
}
|
||||
// and on the next entry.
|
|
@ -3,8 +3,8 @@
|
|||
* Plugin Name: WolKal3000 – Termin-Synchronisation
|
||||
* Plugin URI: https://git.netzbegruenung.de/NB-Public/WolKal3000/
|
||||
* Description: Synchronisation des Kal3000-Plugins mit Wolke-Kalendern und ICS-Dateien
|
||||
* Version: 0.3.8
|
||||
* Author: Harald Milz & Netzbegrünung <hm@seneca.muc.de>
|
||||
* Version: 0.3.9
|
||||
* Author: Harald Milz & Netzbegrünung e.V.
|
||||
* License: GPLv3
|
||||
* License URI: https://www.gnu.org/licenses/gpl-3.0
|
||||
* Domain Path: /languages
|
||||
|
@ -25,30 +25,20 @@
|
|||
|
||||
defined( 'ABSPATH' ) or die( 'No script kiddies please!' );
|
||||
|
||||
define ('GCAL_GEO_TABLE', 'gcal_import_geocache');
|
||||
|
||||
// For gcal_error_log
|
||||
define ('INFO', 3);
|
||||
define ('WARN', 2);
|
||||
define ('CRIT', 1);
|
||||
define ('NONE', 0);
|
||||
|
||||
|
||||
// The real work goes here.
|
||||
require_once dirname( __FILE__ ) . "/gcal-import-worker.php";
|
||||
require_once dirname( __FILE__ ) . "/gcal-import-admin.php";
|
||||
|
||||
require_once dirname( __FILE__ ) . "/wolkal3000-worker.php";
|
||||
require_once dirname( __FILE__ ) . "/wolkal3000-admin.php";
|
||||
|
||||
// create custom scheduler from custom option
|
||||
add_filter( 'cron_schedules', 'gcal_cron_interval' );
|
||||
add_filter( 'cron_schedules', 'wolkal3000_cron_interval' );
|
||||
|
||||
function gcal_cron_interval( $schedules ) {
|
||||
$options = get_option('gcal_options');
|
||||
$current = ( isset ($options['gcal_timer']) ? $options['gcal_timer'] : 60 ); // default 60 minutes
|
||||
function wolkal3000_cron_interval( $schedules ) {
|
||||
$options = get_option('wolkal3000_options');
|
||||
$current = ( isset ($options['wolkal3000_timer']) ? $options['wolkal3000_timer'] : 60 ); // default 60 minutes
|
||||
$interval = 60 * $current; // wir speichern Minuten
|
||||
$schedules['gcal_interval'] = array(
|
||||
$schedules['wolkal3000_interval'] = array(
|
||||
'interval' => $interval,
|
||||
'display' => esc_html__( 'GCal fetch interval' ),
|
||||
'display' => esc_html__( 'Calendar fetch interval' ),
|
||||
);
|
||||
return $schedules;
|
||||
}
|
||||
|
@ -60,47 +50,47 @@ function gcal_cron_interval( $schedules ) {
|
|||
*
|
||||
* @since 0.1.0
|
||||
*
|
||||
* - gcal_category - name of the calendar, for later per-unit display
|
||||
* - gcal_link - the public or private .ics link
|
||||
* - gcal_veranstalter - ?
|
||||
* - gcal_active - flag if a calendar is active or not. Default active.
|
||||
* - wolkal3000_category - name of the calendar, for later per-unit display
|
||||
* - wolkal3000_link - the public or private .ics link
|
||||
* - wolkal3000_veranstalter - ?
|
||||
* - wolkal3000_active - flag if a calendar is active or not. Default active.
|
||||
*
|
||||
* Since there is no install hook in WP, we will use the activation hook for both.
|
||||
*/
|
||||
|
||||
function gcal_import_activate()
|
||||
function wolkal3000_activate()
|
||||
{
|
||||
global $wpdb;
|
||||
// CREATE geocoding caching table if it does not exist already.
|
||||
// the location field will be used only during development and debugging, and will be omitted in production.
|
||||
$table = $wpdb->prefix.GCAL_GEO_TABLE;
|
||||
$table = $wpdb->prefix.WOLKAL3000_GEO_TABLE;
|
||||
$query = "CREATE TABLE IF NOT EXISTS $table (
|
||||
id INT(9) NOT NULL AUTO_INCREMENT,
|
||||
gcal_geo_location VARCHAR(128) NOT NULL,
|
||||
gcal_geo_hash VARCHAR(40) NOT NULL,
|
||||
gcal_geo_lat VARCHAR(20) NOT NULL,
|
||||
gcal_geo_lon VARCHAR(20) NOT NULL,
|
||||
gcal_geo_timestamp INT(16) NOT NULL,
|
||||
wolkal3000_geo_location VARCHAR(128) NOT NULL,
|
||||
wolkal3000_geo_hash VARCHAR(40) NOT NULL,
|
||||
wolkal3000_geo_lat VARCHAR(20) NOT NULL,
|
||||
wolkal3000_geo_lon VARCHAR(20) NOT NULL,
|
||||
wolkal3000_geo_timestamp INT(16) NOT NULL,
|
||||
UNIQUE KEY id (id)
|
||||
);";
|
||||
$wpdb->query($query);
|
||||
|
||||
// and start the scheduler;
|
||||
if ( ! wp_next_scheduled( 'gcal_import_worker_hook' ) ) {
|
||||
wp_schedule_event( time(), 'gcal_interval', 'gcal_import_worker_hook' );
|
||||
if ( ! wp_next_scheduled( 'wolkal3000_worker_hook' ) ) {
|
||||
wp_schedule_event( time(), 'wolkal3000_interval', 'wolkal3000_worker_hook' );
|
||||
}
|
||||
|
||||
gcal_error_log (INFO, "gcal_import activated");
|
||||
wolkal3000_error_log (INFO, "wolkal3000 activated");
|
||||
|
||||
// empty geocode cache if option is set.
|
||||
$options = get_option('gcal_options');
|
||||
if ( isset ( $options['gcal_reset_cache'] ) && '1' == $options['gcal_reset_cache'] ) {
|
||||
$options = get_option('wolkal3000_options');
|
||||
if ( isset ( $options['wolkal3000_reset_cache'] ) && '1' == $options['wolkal3000_reset_cache'] ) {
|
||||
$wpdb->query("DELETE IGNORE FROM $table WHERE 1=1");
|
||||
gcal_error_log (INFO, "emptied geocoding cache");
|
||||
wolkal3000_error_log (INFO, "emptied geocoding cache");
|
||||
}
|
||||
}
|
||||
|
||||
register_activation_hook( __FILE__, 'gcal_import_activate' );
|
||||
register_activation_hook( __FILE__, 'wolkal3000_activate' );
|
||||
|
||||
|
||||
/**
|
||||
|
@ -110,14 +100,14 @@ register_activation_hook( __FILE__, 'gcal_import_activate' );
|
|||
*
|
||||
*/
|
||||
|
||||
function gcal_import_deactivate()
|
||||
function wolkal3000_deactivate()
|
||||
{
|
||||
// clean up! Many plugins forget the housekeeping when deactivating.
|
||||
wp_clear_scheduled_hook('gcal_import_worker_hook');
|
||||
gcal_error_log (INFO, "gcal_import deactivated");
|
||||
wp_clear_scheduled_hook('wolkal3000_worker_hook');
|
||||
wolkal3000_error_log (INFO, "wolkal3000 deactivated");
|
||||
}
|
||||
|
||||
register_deactivation_hook( __FILE__, 'gcal_import_deactivate' );
|
||||
register_deactivation_hook( __FILE__, 'wolkal3000_deactivate' );
|
||||
|
||||
|
||||
/**
|
||||
|
@ -127,21 +117,21 @@ register_deactivation_hook( __FILE__, 'gcal_import_deactivate' );
|
|||
*
|
||||
*/
|
||||
|
||||
function gcal_import_uninstall()
|
||||
function wolkal3000_uninstall()
|
||||
{
|
||||
// clean up! Many plugins forget the housekeeping when uninstalling.
|
||||
gcal_error_log (INFO, "uninstalling gcal_import");
|
||||
wolkal3000_error_log (INFO, "uninstalling wolkal3000");
|
||||
// can we uninstall without deactivating first?
|
||||
// gcal_import_deactivate;
|
||||
// wolkal3000_deactivate;
|
||||
global $wpdb;
|
||||
// drop the geocache table
|
||||
$table = $wpdb->prefix.GCAL_GEO_TABLE ;
|
||||
$table = $wpdb->prefix.WOLKAL3000_GEO_TABLE ;
|
||||
$wpdb->query( "DROP TABLE IF EXISTS $table" );
|
||||
// and the options.
|
||||
delete_option ( 'gcal_options' );
|
||||
delete_option ( 'wolkal3000_options' );
|
||||
}
|
||||
|
||||
register_uninstall_hook( __FILE__, 'gcal_import_uninstall' );
|
||||
register_uninstall_hook( __FILE__, 'wolkal3000_uninstall' );
|
||||
|
||||
|
||||
/*
|
||||
|
@ -150,12 +140,12 @@ register_uninstall_hook( __FILE__, 'gcal_import_uninstall' );
|
|||
* @since 0.3.0
|
||||
*/
|
||||
|
||||
function gcal_error_log($level, $args) {
|
||||
function wolkal3000_error_log($level, $args) {
|
||||
$levels = array ( 'NONE', 'CRIT', 'WARN', 'INFO' );
|
||||
$options = get_option('gcal_options');
|
||||
if ( isset ( $options['gcal_debugging'] )) {
|
||||
if ( $level <= (int) $options['gcal_debugging'] ) {
|
||||
error_log ( "GCal [" . $levels[$level] . "] " . $args );
|
||||
$options = get_option('wolkal3000_options');
|
||||
if ( isset ( $options['wolkal3000_debugging'] )) {
|
||||
if ( $level <= (int) $options['wolkal3000_debugging'] ) {
|
||||
error_log ( "WolKal3000 [" . $levels[$level] . "] " . $args );
|
||||
}
|
||||
}
|
||||
}
|
Reference in a new issue