xref: /plugin/geotag/action.php (revision d5b4dd3624c6feb4ad359a7f5f4b048015b9ee07)
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 *
29 * @phpcs:disable Squiz.Classes.ValidClassName.NotPascalCase
30 */
31class action_plugin_geotag extends ActionPlugin
32{
33    /**
34     * Register for events.
35     *
36     * @param EventHandler $controller
37     *          DokuWiki's event controller object. Also available as global $EVENT_HANDLER
38     */
39    final public function register(EventHandler $controller): void
40    {
41        $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'handleMetaheaderOutput');
42        if ($this->getConf('toolbar_icon')) {
43            $controller->register_hook('TOOLBAR_DEFINE', 'AFTER', $this, 'insertButton', []);
44        }
45        $controller->register_hook('PLUGIN_POPULARITY_DATA_SETUP', 'AFTER', $this, 'popularity');
46    }
47
48    /**
49     * Retrieve metadata and add to the head of the page using appropriate meta tags.
50     *
51     * @param Event $event
52     *          the DokuWiki event. $event->data is a two-dimensional
53     *          array of all meta headers. The keys are meta, link and script.
54     *
55     * @see https://www.dokuwiki.org/devel:event:tpl_metaheader_output
56     */
57    final public function handleMetaheaderOutput(Event $event): void
58    {
59        global $ID;
60        $title = p_get_metadata($ID, 'title', METADATA_RENDER_USING_SIMPLE_CACHE);
61        $geotags = p_get_metadata($ID, 'geo', METADATA_RENDER_USING_SIMPLE_CACHE) ?? [];
62        $region = $geotags ['region'] ?? null;
63        $lat = $geotags ['lat'] ?? null;
64        $lon = $geotags ['lon'] ?? null;
65        $alt = $geotags ['alt'] ?? null;
66        $country = $geotags ['country'] ?? null;
67        $placename = $geotags ['placename'] ?? null;
68        $geohash = $geotags ['geohash'] ?? null;
69
70        if (!empty($region)) {
71            $event->data ['meta'] [] = ['name' => 'geo.region', 'content' => $region];
72        }
73        if (!empty($placename)) {
74            $event->data ['meta'] [] = ['name' => 'geo.placename', 'content' => $placename];
75        }
76        if (!(empty($lat) && empty($lon))) {
77            if (!empty($alt)) {
78                $event->data ['meta'] [] = ['name' => 'geo.position', 'content' => $lat . ';' . $lon . ';' . $alt];
79            } else {
80                $event->data ['meta'] [] = ['name' => 'geo.position', 'content' => $lat . ';' . $lon];
81            }
82        }
83        if (!empty($country)) {
84            $event->data ['meta'] [] = ['name' => 'geo.country', 'content' => $country];
85        }
86        if (!(empty($lat) && empty($lon))) {
87            $event->data ['meta'] [] = ['name' => "ICBM", 'content' => $lat . ', ' . $lon];
88            // icbm is generally useless without a DC.title,
89            // so we copy that from title unless it's empty...
90            if (!(empty($title))) {
91                /*
92                 * don't specify the DC namespace as this is incomplete; it should be done at the
93                 * template level as it also needs a 'profile' attribute on the head/container,
94                 * see: https://dublincore.org/documents/dc-html/#sect-3.1.1
95                 * $event->data ['link'] [] = array ('rel' => 'schema.DC',
96                 * 'href' => 'http://purl.org/dc/elements/1.1/');
97                 */
98                $event->data ['meta'] [] = ['name' => "DC.title", 'content' => $title];
99            }
100        }
101        if (!empty($geohash)) {
102            $event->data ['meta'] [] = ['name' => 'geo.geohash', 'content' => $geohash];
103        }
104    }
105
106    /**
107     * Inserts the toolbar button.
108     *
109     * @param Event $event
110     *          the DokuWiki event
111     */
112    final public function insertButton(Event $event): void
113    {
114        $event->data [] = [
115            'type' => 'format',
116            'title' => $this->getLang('toolbar_desc'),
117            'icon' => '../../plugins/geotag/images/geotag.png',
118            'open' => '{{geotag>lat:', 'sample' => '52.2345',
119            'close' => ', lon:7.521, alt: , placename: , country: , region: }}'
120        ];
121    }
122
123    /**
124     * Add geotag popularity data.
125     *
126     * @param Event $event
127     *          the DokuWiki event
128     */
129    final public function popularity(Event $event): void
130    {
131        $versionInfo = getVersionData();
132        $plugin_info = $this->getInfo();
133        $event->data['geotag']['version'] = $plugin_info['date'];
134        $event->data['geotag']['dwversion'] = $versionInfo['date'];
135        $event->data['geotag']['combinedversion'] = $versionInfo['date'] . '_' . $plugin_info['date'];
136    }
137}
138