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