1c3b1bf17SMark C. Prins<?php 2c3b1bf17SMark C. Prins/* 331a26af0SMark C. Prins * Copyright (c) 2011-2016 Mark C. Prins <mprins@users.sf.net> 4c3b1bf17SMark C. Prins * 5c3b1bf17SMark C. Prins * Permission to use, copy, modify, and distribute this software for any 6c3b1bf17SMark C. Prins * purpose with or without fee is hereby granted, provided that the above 7c3b1bf17SMark C. Prins * copyright notice and this permission notice appear in all copies. 8c3b1bf17SMark C. Prins * 9c3b1bf17SMark C. Prins * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10c3b1bf17SMark C. Prins * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11c3b1bf17SMark C. Prins * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12c3b1bf17SMark C. Prins * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13c3b1bf17SMark C. Prins * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14c3b1bf17SMark C. Prins * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15c3b1bf17SMark C. Prins * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16c3b1bf17SMark C. Prins */ 17c3b1bf17SMark C. Prins 18c3b1bf17SMark C. Prins/** 19a42972efSMark C. Prins * DokuWiki Plugin geotag (Action Component). 20c3b1bf17SMark C. Prins * 2162d582daSMark C. Prins * @license BSD license 2230c0df9cSMark C. Prins * @author Mark C. Prins <mprins@users.sf.net> 23c3b1bf17SMark C. Prins */ 24c3b1bf17SMark C. Prinsclass action_plugin_geotag extends DokuWiki_Action_Plugin { 25c3b1bf17SMark C. Prins 2681dae509SMark C. Prins /** 2781dae509SMark C. Prins * Register for events. 2881dae509SMark C. Prins * 292b579309SMark C. Prins * @param Doku_Event_Handler $controller 302b579309SMark C. Prins * DokuWiki's event controller object. Also available as global $EVENT_HANDLER 3181dae509SMark C. Prins */ 322b579309SMark C. Prins public function register(Doku_Event_Handler $controller) { 332be1c2ecSMark Prins $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'handleMetaheaderOutput'); 3494769ee6SMark C. Prins if($this->getConf('toolbar_icon')) { 352be1c2ecSMark Prins $controller->register_hook('TOOLBAR_DEFINE', 'AFTER', $this, 'insertButton', array()); 3694769ee6SMark C. Prins } 37*3dfca210SMark Prins $controller->register_hook('PLUGIN_POPULARITY_DATA_SETUP', 'AFTER', $this, 'popularity'); 38c3b1bf17SMark C. Prins } 39c3b1bf17SMark C. Prins 4081dae509SMark C. Prins /** 412b579309SMark C. Prins * Retrieve metadata and add to the head of the page using appropriate meta tags. 422b579309SMark C. Prins * 432b579309SMark C. Prins * @param Doku_Event $event 442b579309SMark C. Prins * the DokuWiki event. $event->data is a two-dimensional 45a9539fccSMark C. Prins * array of all meta headers. The keys are meta, link and script. 46a42972efSMark C. Prins * 472ca95f77SMark Prins * @see https://www.dokuwiki.org/devel:event:tpl_metaheader_output 4881dae509SMark C. Prins */ 492ca95f77SMark Prins public function handleMetaheaderOutput(Doku_Event $event) { 50c3b1bf17SMark C. Prins global $ID; 512ca95f77SMark Prins $title = p_get_metadata($ID, 'title', METADATA_RENDER_USING_SIMPLE_CACHE); 522ca95f77SMark Prins $geotags = p_get_metadata($ID, 'geo', METADATA_RENDER_USING_SIMPLE_CACHE) ?? array(); 532ca95f77SMark Prins $region = $geotags ['region'] ?? NULL; 542ca95f77SMark Prins $lat = $geotags ['lat'] ?? NULL; 552ca95f77SMark Prins $lon = $geotags ['lon'] ?? NULL; 562ca95f77SMark Prins $alt = $geotags ['alt'] ?? NULL; 572ca95f77SMark Prins $country = $geotags ['country'] ?? NULL; 582ca95f77SMark Prins $placename = $geotags ['placename'] ?? NULL; 592ca95f77SMark Prins $geohash = $geotags ['geohash'] ?? NULL; 60c3b1bf17SMark C. Prins 61a42972efSMark C. Prins if(!empty ($region)) { 622b579309SMark C. Prins $event->data ['meta'] [] = array( 632b579309SMark C. Prins 'name' => 'geo.region', 642b579309SMark C. Prins 'content' => $region 652b579309SMark C. Prins ); 66a42972efSMark C. Prins } 67a42972efSMark C. Prins if(!empty ($placename)) { 682b579309SMark C. Prins $event->data ['meta'] [] = array( 692b579309SMark C. Prins 'name' => 'geo.placename', 702b579309SMark C. Prins 'content' => $placename 712b579309SMark C. Prins ); 72a42972efSMark C. Prins } 73a42972efSMark C. Prins if(!(empty ($lat) && empty ($lon))) { 742b579309SMark C. Prins if(!empty ($alt)) { 752b579309SMark C. Prins $event->data ['meta'] [] = array( 762b579309SMark C. Prins 'name' => 'geo.position', 772b579309SMark C. Prins 'content' => $lat . ';' . $lon . ';' . $alt 782b579309SMark C. Prins ); 798eb104d9SMark C. Prins } else { 808eb104d9SMark C. Prins $event->data ['meta'] [] = array( 818eb104d9SMark C. Prins 'name' => 'geo.position', 828eb104d9SMark C. Prins 'content' => $lat . ';' . $lon 838eb104d9SMark C. Prins ); 842b579309SMark C. Prins } 85a42972efSMark C. Prins } 86a42972efSMark C. Prins if(!empty ($country)) { 872b579309SMark C. Prins $event->data ['meta'] [] = array( 882b579309SMark C. Prins 'name' => 'geo.country', 892b579309SMark C. Prins 'content' => $country 902b579309SMark C. Prins ); 91a42972efSMark C. Prins } 92dfaf64a7SMark C. Prins if(!(empty ($lat) && empty ($lon))) { 932b579309SMark C. Prins $event->data ['meta'] [] = array( 942b579309SMark C. Prins 'name' => "ICBM", 952b579309SMark C. Prins 'content' => $lat . ', ' . $lon 962b579309SMark C. Prins ); 9742b5f05aSMark C. Prins // icbm is generally useless without a DC.title, 9842b5f05aSMark C. Prins // so we copy that from title unless it's empty... 99a42972efSMark C. Prins if(!(empty ($title))) { 100b7214539SMark C. Prins /* 101b7214539SMark C. Prins * don't specify the DC namespace as this is incomplete; it should be done at the 102b7214539SMark C. Prins * template level as it also needs a 'profile' attribute on the head/container, 103b7214539SMark C. Prins * see: http://dublincore.org/documents/dc-html/#sect-3.1.1 1041fdb6e09SMark Prins * $event->data ['link'] [] = array ('rel' => 'schema.DC', 1051fdb6e09SMark Prins * 'href' => 'http://purl.org/dc/elements/1.1/'); 106b7214539SMark C. Prins */ 1072b579309SMark C. Prins $event->data ['meta'] [] = array( 1082b579309SMark C. Prins 'name' => "DC.title", 1092b579309SMark C. Prins 'content' => $title 1102b579309SMark C. Prins ); 111a42972efSMark C. Prins } 112a42972efSMark C. Prins } 113a42972efSMark C. Prins if(!empty ($geohash)) { 1142b579309SMark C. Prins $event->data ['meta'] [] = array( 1152b579309SMark C. Prins 'name' => 'geo.geohash', 1162b579309SMark C. Prins 'content' => $geohash 1172b579309SMark C. Prins ); 118c3b1bf17SMark C. Prins } 119dfaf64a7SMark C. Prins } 120dfaf64a7SMark C. Prins 12181dae509SMark C. Prins /** 12294769ee6SMark C. Prins * Inserts the toolbar button. 123a42972efSMark C. Prins * 1242b579309SMark C. Prins * @param Doku_Event $event 1252b579309SMark C. Prins * the DokuWiki event 12694769ee6SMark C. Prins */ 1272be1c2ecSMark Prins public function insertButton(Doku_Event $event, $param) { 12894769ee6SMark C. Prins $event->data [] = array( 12994769ee6SMark C. Prins 'type' => 'format', 13094769ee6SMark C. Prins 'title' => $this->getLang('toolbar_desc'), 13194769ee6SMark C. Prins 'icon' => '../../plugins/geotag/images/geotag.png', 13294769ee6SMark C. Prins 'open' => '{{geotag>lat:', 13394769ee6SMark C. Prins 'sample' => '52.2345', 1342b579309SMark C. Prins 'close' => ', lon:7.521, alt: , placename: , country: , region: }}' 13594769ee6SMark C. Prins ); 13694769ee6SMark C. Prins } 137*3dfca210SMark Prins 138*3dfca210SMark Prins /** 139*3dfca210SMark Prins * Add geotag popularity data. 140*3dfca210SMark Prins * 141*3dfca210SMark Prins * @param Doku_Event $event 142*3dfca210SMark Prins * the DokuWiki event 143*3dfca210SMark Prins */ 144*3dfca210SMark Prins final public function popularity(Doku_Event $event): void { 145*3dfca210SMark Prins global $updateVersion; 146*3dfca210SMark Prins $plugin_info = $this->getInfo(); 147*3dfca210SMark Prins $event->data['geotag']['version'] = $plugin_info['date']; 148*3dfca210SMark Prins $event->data['geotag']['dwversion'] = $updateVersion; 149*3dfca210SMark Prins $event->data['geotag']['combinedversion'] = $updateVersion . '_' . $plugin_info['date']; 150*3dfca210SMark Prins } 151c3b1bf17SMark C. Prins} 152