1<?php
2/**
3 * Semantic Action Plugin
4 *
5 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
6 * @author     Giuseppe Di Terlizzi <giuseppe.diterlizzi@gmail.com>
7 * @copyright  (C) 2015-2023, Giuseppe Di Terlizzi
8 */
9
10
11/**
12 * Class Semantic Action Plugin
13 *
14 * Add semantic data to DokuWiki
15 */
16class action_plugin_semantic extends DokuWiki_Action_Plugin
17{
18
19    private $helper = null;
20
21    public function __construct()
22    {
23        $this->helper = $this->loadHelper('semantic');
24    }
25
26    /**
27     * Register events
28     *
29     * @param Doku_Event_Handler $controller handler
30     */
31    public function register(Doku_Event_Handler $controller)
32    {
33
34        if ($this->getConf('useJSONLD')) {
35            $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'website');
36            $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'json_ld');
37        }
38
39        if ($this->getConf('useMetaDescription')) {
40            $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'meta_description');
41        }
42
43        if ($this->getConf('useMetaAuthor')) {
44            $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'meta_author');
45        }
46
47        if ($this->getConf('useDublinCore')) {
48            $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'meta_dublin_core');
49        }
50
51        if ($this->getConf('useOpenGraph')) {
52            $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'meta_open_graph');
53        }
54
55        if ($this->getConf('exposeWebService')) {
56            $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'ajax');
57        }
58
59        $controller->register_hook('DOKUWIKI_STARTED', 'AFTER', $this, 'jsinfo');
60    }
61
62    /**
63     * Export JSON-JD in $JSONINFO array
64     */
65    public function jsinfo(Doku_Event &$event, $param)
66    {
67
68        global $JSINFO;
69
70        $JSINFO['plugin']['semantic'] = array(
71            'exposeWebService' => $this->getConf('exposeWebService'),
72        );
73
74    }
75
76    /**
77     * Export in JSON-LD format
78     *
79     * @param Doku_Event $event handler
80     * @param array      $param
81     *
82     * @return string
83     */
84    public function ajax(Doku_Event &$event, $param)
85    {
86
87        if ($event->data !== 'plugin_semantic') {
88            return false;
89        }
90
91        //no other ajax call handlers needed
92        $event->stopPropagation();
93        $event->preventDefault();
94
95        global $INPUT;
96
97        $export = $INPUT->str('export');
98        $id     = $INPUT->str('id');
99
100        if (!$id) {
101            return false;
102        }
103
104        $this->helper->getMetadata($id);
105        $json_ld = $this->helper->getJsonLD();
106
107        header('Content-Type: application/ld+json');
108        print json_encode($json_ld);
109        return true;
110
111    }
112
113    /**
114     * Expose JSON-JD WebSite schema
115     *
116     * @param Doku_Event $event handler
117     * @param array      $params
118     *
119     * @return void
120     */
121    public function website(Doku_Event &$event, $params)
122    {
123        $event->data["script"][] = array(
124            "type"  => "application/ld+json",
125            "_data" => json_encode($this->helper->getWebSite(), JSON_PRETTY_PRINT),
126        );
127    }
128
129    /**
130     * JSON-LD Event handler
131     *
132     * @param Doku_Event $event handler
133     * @param array      $params
134     *
135     * @return void
136     */
137    public function json_ld(Doku_Event &$event, $params)
138    {
139
140        global $ID;
141
142        $this->helper->getMetadata($ID);
143        $json_ld = $this->helper->getJsonLD();
144
145        if (!count($json_ld)) {
146            return false;
147        }
148
149        $event->data["script"][] = array(
150            "type"  => "application/ld+json",
151            "_data" => json_encode($json_ld, JSON_PRETTY_PRINT),
152        );
153
154    }
155
156    /**
157     * Meta Description handler
158     *
159     * @param Doku_Event $event handler
160     * @param array      $params
161     *
162     * @return void
163     */
164    public function meta_description(Doku_Event &$event, $params)
165    {
166
167        global $ID;
168
169        $this->helper->getMetadata($ID);
170
171        if ($description = $this->helper->getDescription()) {
172
173            $description = str_replace("\n", ' ', $description);
174
175            $event->data['meta'][] = array(
176                'name'    => 'description',
177                'content' => $description,
178            );
179
180        }
181
182    }
183
184    /**
185     * Meta Description handler
186     *
187     * @param Doku_Event $event handler
188     * @param array      $params
189     *
190     * @return void
191     */
192    public function meta_author(Doku_Event &$event, $params)
193    {
194
195        global $ID;
196
197        $this->helper->getMetadata($ID);
198
199        if ($author = $this->helper->getAuthor()) {
200
201            $event->data['meta'][] = array(
202                'name'    => 'author',
203                'content' => $author,
204            );
205
206        }
207
208    }
209
210    /**
211     * OpenGraph handler
212     *
213     * @param Doku_Event $event handler
214     * @param array      $params
215     *
216     * @return void
217     */
218    public function meta_open_graph(Doku_Event &$event, $params)
219    {
220
221        global $ID;
222
223        $this->helper->getMetadata($ID);
224
225        foreach ($this->helper->getOpenGraph() as $property => $content) {
226
227            if (!$content) {
228                continue;
229            }
230
231            $event->data['meta'][] = array(
232                'property' => $property,
233                'content'  => $content,
234            );
235
236        }
237
238    }
239
240    /**
241     * Dublin Core handler
242     *
243     * @param Doku_Event $event handler
244     * @param array      $params
245     *
246     * @return void
247     */
248    public function meta_dublin_core(Doku_Event &$event, $params)
249    {
250
251        global $ID;
252
253        $this->helper->getMetadata($ID);
254
255        foreach ($this->helper->getDublinCore() as $name => $content) {
256
257            if (!$content) {
258                continue;
259            }
260
261            $event->data['meta'][] = array(
262                'name'    => $name,
263                'content' => $content,
264            );
265
266        }
267
268    }
269
270}
271