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