1<?php
2/*
3 * Copyright (c) 2011 Mark C. Prins <mprins@users.sf.net>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18/**
19 * DokuWiki Plugin geotag (Action Component).
20 *
21 * @license BSD license
22 * @author  Mark C. Prins <mprins@users.sf.net>
23 */
24class action_plugin_geotag extends DokuWiki_Action_Plugin
25{
26
27    /**
28     * Register for events.
29     *
30     * @param Doku_Event_Handler $controller
31     *          DokuWiki's event controller object. Also available as global $EVENT_HANDLER
32     */
33    final public function register(Doku_Event_Handler $controller): void
34    {
35        $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'handleMetaheaderOutput');
36        if ($this->getConf('toolbar_icon')) {
37            $controller->register_hook('TOOLBAR_DEFINE', 'AFTER', $this, 'insertButton', array());
38        }
39        $controller->register_hook('PLUGIN_POPULARITY_DATA_SETUP', 'AFTER', $this, 'popularity');
40    }
41
42    /**
43     * Retrieve metadata and add to the head of the page using appropriate meta tags.
44     *
45     * @param Doku_Event $event
46     *          the DokuWiki event. $event->data is a two-dimensional
47     *          array of all meta headers. The keys are meta, link and script.
48     *
49     * @see https://www.dokuwiki.org/devel:event:tpl_metaheader_output
50     */
51    final public function handleMetaheaderOutput(Doku_Event $event): void
52    {
53        global $ID;
54        $title     = p_get_metadata($ID, 'title', METADATA_RENDER_USING_SIMPLE_CACHE);
55        $geotags   = p_get_metadata($ID, 'geo', METADATA_RENDER_USING_SIMPLE_CACHE) ?? array();
56        $region    = $geotags ['region'] ?? null;
57        $lat       = $geotags ['lat'] ?? null;
58        $lon       = $geotags ['lon'] ?? null;
59        $alt       = $geotags ['alt'] ?? null;
60        $country   = $geotags ['country'] ?? null;
61        $placename = $geotags ['placename'] ?? null;
62        $geohash   = $geotags ['geohash'] ?? null;
63
64        if (!empty ($region)) {
65            $event->data ['meta'] [] = array(
66                'name'    => 'geo.region',
67                'content' => $region
68            );
69        }
70        if (!empty ($placename)) {
71            $event->data ['meta'] [] = array(
72                'name'    => 'geo.placename',
73                'content' => $placename
74            );
75        }
76        if (!(empty ($lat) && empty ($lon))) {
77            if (!empty ($alt)) {
78                $event->data ['meta'] [] = array(
79                    'name'    => 'geo.position',
80                    'content' => $lat . ';' . $lon . ';' . $alt
81                );
82            } else {
83                $event->data ['meta'] [] = array(
84                    'name'    => 'geo.position',
85                    'content' => $lat . ';' . $lon
86                );
87            }
88        }
89        if (!empty ($country)) {
90            $event->data ['meta'] [] = array(
91                'name'    => 'geo.country',
92                'content' => $country
93            );
94        }
95        if (!(empty ($lat) && empty ($lon))) {
96            $event->data ['meta'] [] = array(
97                'name'    => "ICBM",
98                'content' => $lat . ', ' . $lon
99            );
100            // icbm is generally useless without a DC.title,
101            // so we copy that from title unless it's empty...
102            if (!(empty ($title))) {
103                /*
104                 * don't specify the DC namespace as this is incomplete; it should be done at the
105                 * template level as it also needs a 'profile' attribute on the head/container,
106                 * see: https://dublincore.org/documents/dc-html/#sect-3.1.1
107                 * $event->data ['link'] [] = array ('rel' => 'schema.DC',
108                 * 'href' => 'http://purl.org/dc/elements/1.1/');
109                 */
110                $event->data ['meta'] [] = array(
111                    'name'    => "DC.title",
112                    'content' => $title
113                );
114            }
115        }
116        if (!empty ($geohash)) {
117            $event->data ['meta'] [] = array(
118                'name'    => 'geo.geohash',
119                'content' => $geohash
120            );
121        }
122    }
123
124    /**
125     * Inserts the toolbar button.
126     *
127     * @param Doku_Event $event
128     *          the DokuWiki event
129     */
130    final public function insertButton(Doku_Event $event, array $param): void
131    {
132        $event->data [] = array(
133            'type'   => 'format',
134            'title'  => $this->getLang('toolbar_desc'),
135            'icon'   => '../../plugins/geotag/images/geotag.png',
136            'open'   => '{{geotag>lat:',
137            'sample' => '52.2345',
138            'close'  => ', lon:7.521, alt: , placename: , country: , region: }}'
139        );
140    }
141
142    /**
143     * Add geotag popularity data.
144     *
145     * @param Doku_Event $event
146     *          the DokuWiki event
147     */
148    final public function popularity(Doku_Event $event): void
149    {
150        global $updateVersion;
151        $plugin_info                              = $this->getInfo();
152        $event->data['geotag']['version']         = $plugin_info['date'];
153        $event->data['geotag']['dwversion']       = $updateVersion;
154        $event->data['geotag']['combinedversion'] = $updateVersion . '_' . $plugin_info['date'];
155    }
156}
157