diff --git a/Makefile b/Makefile deleted file mode 100644 index 2d7ce65..0000000 --- a/Makefile +++ /dev/null @@ -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) - - diff --git a/README.md b/README.md index c245f44..c5e688b 100644 --- a/README.md +++ b/README.md @@ -2,18 +2,18 @@ Ein Wordpress-Plugin, das auf das Grüne Wordpress-Theme Urwahl3000 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 hier. +* 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 http://www.seneca.muc.de/kal3000-gcal-import/ und installiert es über die WP-Oberfläche wie gewohnt. +2. Als nächstes holt man sich das Plugin unter https://git.verdigado.com/NB-Public/WolKal3000/releases 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. 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 https://calendar.google.com/calendar/ical/gruene.freising%40gmail.com/public/basic.ics. +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 Google-API 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 /usr/share/wordpress/wp-config.php bzw. auf Ubuntu / Debian in /etc/wordpress/config-SITE.php festgelegt. Zur Dokumentation bitte hier entlang. +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 /usr/share/wordpress/wp-config.php bzw. auf Ubuntu / Debian in /etc/wordpress/config-SIT +E.php festgelegt. Zur Dokumentation bitte hier entlang. ## 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! :-) - - - - - - - - - - - - - - diff --git a/gcal-import-admin.php b/gcal-import-admin.php deleted file mode 100644 index 71f00fb..0000000 --- a/gcal-import-admin.php +++ /dev/null @@ -1,201 +0,0 @@ - - -
-

-

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.

- -
- - - -




- - -
- - '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() { -?> -

Wolke-Kalender synchronisieren in eine ausgewählte Terminkategorie von Kal3000. Bitte trage hierfür die entsprechende Export-Adresse des gewünschten Wolke-Kalenders ein.
Falls zu einer Terminkategorie kein Wolke-Kalender synchronisiert werden soll, entsprechendes Feld bitte leer lassen.

-

Erfahre mehr darüber, wie du die Export-Adresse eines Wolke-Kalenders findest. -

-
'; -} - - -function gcal_timer_section_text() { -?> -

In welcher Regelmäßigkeit sollen die Wolke-Kalender synchronisiert werden? Bitte Zeitintervall in Minuten angeben.
- Achtung: Um Änderungen wirksam werden zu lassen, muss das Plugin deaktiviert und wieder aktiviert werden. (Menüpunkt "Plugins")

- Minuten
'; -} - - - -function gcal_geocoding_section_text() { -?> -

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.
Dies nennt sich Geocoding. Dabei handelt es sich um eine experimentelle Funktion von WolKal3000.

- '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 ' ' . $coder['name']; - if ( $coder['option'] == 'official' ) { - echo ''; - } - - echo '
' ; - } -} - - -function gcal_debugging_section_text() { -?> -

Debugging aktivieren? Speicherort: ${APACHE_LOG_DIR}/error.log

- Um die Performance zu verbessern, werden gefundene Geocoding-Daten zwischengespeichert.
- Zu Debugging-Zwecken kann der Zwischenspeicher (Cache) des Plugins gelöscht
- werden, um ein neues Geocoding aller Termin-Orte zu erzwingen.
-

- Debug-Logging aktivieren
'; - // let's make a select box: -?> -
- Geocoding-Cache nach Deaktivieren und Aktivieren des Plugins löschen
';} - - - -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; -*/ -} - - diff --git a/gcal-import-geocode.php b/gcal-import-geocode.php deleted file mode 100644 index 6a40e35..0000000 --- a/gcal-import-geocode.php +++ /dev/null @@ -1,229 +0,0 @@ - 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]); -} - - diff --git a/readme.txt b/readme.txt deleted file mode 100644 index 19bf30e..0000000 --- a/readme.txt +++ /dev/null @@ -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 Urwahl3000 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 http://www.seneca.muc.de/kal3000-gcal-import/ 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 https://calendar.google.com/calendar/ical/gruene.freising%40gmail.com/public/basic.ics. - -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 Google-API 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: [wpcalendar kat=TERMINKATEGORIE]. 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. - diff --git a/wolkal3000-admin.php b/wolkal3000-admin.php new file mode 100644 index 0000000..1e48d52 --- /dev/null +++ b/wolkal3000-admin.php @@ -0,0 +1,202 @@ + + +
+

+

Mit WolKal3000 kannst du dein Kal3000-Plugin automatisch mit Kalendern in der grünen Wolke synchronisieren.

+ +
+ + + +




+ + +
+ + '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() { +?> +

Wolke-Kalender synchronisieren in eine ausgewählte Terminkategorie von Kal3000. Bitte trage hierfür die entsprechende Export-Adresse des gewünschten Wolke-Kalenders ein.
Falls zu einer Terminkategorie kein Wolke-Kalender synchronisiert werden soll, entsprechendes Feld bitte leer lassen.

+

Erfahre mehr darüber, wie du die Export-Adresse eines Wolke-Kalenders findest. +

+' . WOLKAL_SUFFIX . '
'; +} + + +function wolkal3000_timer_section_text() { +?> +

In welcher Regelmäßigkeit sollen die Wolke-Kalender synchronisiert werden? Bitte Zeitintervall in Minuten angeben.
+ Achtung: Um Änderungen wirksam werden zu lassen, muss das Plugin deaktiviert und wieder aktiviert werden. (Menüpunkt "Plugins")

+ Minuten
'; +} + + + +function wolkal3000_geocoding_section_text() { +?> +

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.
Dies nennt sich Geocoding. Dabei handelt es sich um eine experimentelle Funktion von WolKal3000.

+ '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 ' ' . $coder['name']; + echo '
' ; + } +} + + +function wolkal3000_debugging_section_text() { +?> +

Debugging aktivieren? Speicherort: ${APACHE_LOG_DIR}/error.log

+ Um die Performance zu verbessern, werden gefundene Geocoding-Daten zwischengespeichert.
+ Zu Debugging-Zwecken kann der Zwischenspeicher (Cache) des Plugins gelöscht
+ werden, um ein neues Geocoding aller Termin-Orte zu erzwingen.
+

+ Debug-Logging aktivieren
'; + // let's make a select box: +?> +
+ Geocoding-Cache nach Deaktivieren und Aktivieren des Plugins löschen
';} + + + +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; +*/ +} + + diff --git a/wolkal3000-config.php b/wolkal3000-config.php new file mode 100644 index 0000000..b34f232 --- /dev/null +++ b/wolkal3000-config.php @@ -0,0 +1,10 @@ + diff --git a/wolkal3000-geocode.php b/wolkal3000-geocode.php new file mode 100644 index 0000000..f9ce8ba --- /dev/null +++ b/wolkal3000-geocode.php @@ -0,0 +1,158 @@ + 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); +} + diff --git a/gcal-import-worker.php b/wolkal3000-worker.php similarity index 81% rename from gcal-import-worker.php rename to wolkal3000-worker.php index 0cac19d..61f61e9 100644 --- a/gcal-import-worker.php +++ b/wolkal3000-worker.php @@ -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. diff --git a/gcal-import.php b/wolkal3000.php similarity index 51% rename from gcal-import.php rename to wolkal3000.php index 6312041..e23ad49 100644 --- a/gcal-import.php +++ b/wolkal3000.php @@ -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 + * 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 ); } } }