Passed
Pull Request — master (#6)
by Mark
02:54 queued 54s
created

action.php (19 issues)

1
<?php
2
/**
3
 * DokuSIOC - SIOC plugin for DokuWiki
4
 *
5
 * version 0.1.2
6
 *
7
 * DokuSIOC integrates the SIOC ontology within DokuWiki and provides an
8
 * alternate RDF/XML views of the wiki documents.
9
 *
10
 * For DokuWiki we can't use the Triplify script because DokuWiki has not a RDBS
11
 * backend. But the wiki API provides enough methods to get the data out, so
12
 * DokuSIOC as a plugin uses the export hook to provide accessible data as
13
 * RDF/XML, using the SIOC ontology as vocabulary.
14
 *
15
 * METADATA
16
 *
17
 * @author    Michael Haschke @ eye48.com
18
 * @copyright 2009 Michael Haschke
19
 * @license   http://www.gnu.org/licenses/old-licenses/gpl-2.0.html GNU General Public License 2.0 (GPLv2)
20
 * @version   0.1.2
21
 *
22
 * WEBSITES
23
 *
24
 * @link      http://eye48.com/go/dokusioc Plugin Website and Overview
25
 * @link      http://github.com/haschek/DokuWiki-Plugin-DokuSIOC/issues Issue tracker
26
 *
27
 * LICENCE
28
 *
29
 * This program is free software: you can redistribute it and/or modify it under
30
 * the terms of the GNU General Public License as published by the Free Software
31
 * Foundation, version 2 of the License.
32
 *
33
 * This program is distributed in the hope that it will be useful, but WITHOUT
34
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
35
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
36
 *
37
 * @link      http://www.gnu.org/licenses/old-licenses/gpl-2.0.html GNU General Public License 2.0 (GPLv2)
38
 *
39
 * CHANGELOG
40
 *
41
 * 0.1.2
42
 * - fix: meta link to post type is standard use now (issue 9)
43
 * - mod: titles for SIOC documents (issue 10)
44
 * - mod: use sioc:UserAccount instead of deprecated sioc:User (issue 2)
45
 * 0.1.1 (bugfix release)
46
 * - fix header output for content negotiation
47
 * - fix URIs for profile and SIOC ressource
48
 * - better dc:title for revisions
49
 * - add complete URI to rdf:about for foaf:Document (Profile) to make it explicit
50
 * - add rel="canonical" for URIs with type parameter, to prevent double content
51
 * 0.1
52
 * - exchange licence b/c CC-BY-SA was incompatible with GPL
53
 * - restructuring code base
54
 * - fix: wrong meta link for revisions
55
 * - add: possibility to send noindex by x-robots-tag via HTTP header
56
 * - add: soft check for requested application type
57
 * - mod: use search method to get container content on next sub level
58
 * - mod: better dc:title for foaf:document,
59
 * - mod: better distinction between user/container/post resources
60
 * - mod: normalize URIs
61
 * - fix: URIs for SIOC documents
62
 * - mod: use dcterms:created and sioc:has_creator only for first revision of wiki page b/c of inadequate meta data
63
 * - add: backlinks from wiki via dcterms:isReferencedBy
64
 * - add: contributors by sioc:has_modifier (only for last revision b/c of wrong meta data for older revisions)
65
 * - rem: foaf:person link in sioct:WikiArticle b/c it routes to same data like sioc:has_creater/modifier
66
 * - rem: Talis SIOC widget for comments b/c incompatibility with DokuWiki JS
67
 * poc
68
 * - proof of concept release under CC-BY-SA
69
 **/
70
71
class action_plugin_dokusioc extends DokuWiki_Action_Plugin {
72
73
    private $agentlink = 'http://eye48.com/go/dokusioc?v=0.1.2';
74
75
    /* -- Methods to manage plugin ------------------------------------------ */
76
77
    /**
78
     * Register its handlers with the DokuWiki's event controller
79
     */
80
    public function register(Doku_Event_Handler $controller) {
81
        //print_r(headers_list()); die();
82
83
        // test the requested action
84
        $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, 'checkAction', $controller);
85
        // pingthesemanticweb.com
86
        if($this->getConf('pingsw')) {
87
            $controller->register_hook('ACTION_SHOW_REDIRECT', 'BEFORE', $this, 'pingService', $controller);
88
        }
89
    }
90
91
    /* -- Event handlers ---------------------------------------------------- */
92
93
    public function checkAction($action, $controller) {
94
        global $INFO;
95
        //print_r($INFO); die();
96
        //print_r(headers_list()); die();
97
98
        if($action->data == 'export_siocxml') {
99
            // give back rdf
100
            $this->exportSioc();
101
        } elseif(($action->data == 'show' || $action->data == 'index') && $INFO['perm']
102
            && !defined('DOKU_MEDIADETAIL')
103
            && ($INFO['exists'] || getDwUserInfo($INFO['id'], $this)) && !isHiddenPage($INFO['id'])) {
104
            if($this->isRdfXmlRequest()) {
105
                // forward to rdfxml document if requested
106
                // print_r(headers_list()); die();
107
                $location = $this->createRdfLink();
108
                if(function_exists('header_remove')) {
109
                    header_remove();
110
                }
111
                header('Location: ' . $location['href'], true, 303);
112
                exit();
113
            } else {
114
                // add meta link to html head
115
                $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'createRdfLink');
116
            }
117
        }
118
        /*
119
        else
120
        {
121
            print_r(array($action->data, $INFO['perm'], defined('DOKU_MEDIADETAIL'), $INFO['exists'],
122
                    getDwUserInfo($INFO['id'],$this), isHiddenPage($INFO['id'])));
123
            die();
124
        }
125
        */
126
    }
127
128
    public function exportSioc() {
129
        global $ID, $INFO, $conf, $REV, $auth;
130
131
        // Test for hidden pages
132
133
        if(isHiddenPage($ID)) {
134
            $this->exit("HTTP/1.0 404 Not Found");
135
        }
136
137
        // Get type of SIOC content
138
139
        $sioc_type = $this->getContenttype();
140
141
        // Test for valid types
142
143
        if(!(($sioc_type == 'post' && $INFO['exists']) || $sioc_type == 'user' || $sioc_type == 'container')) {
144
            $this->exit("HTTP/1.0 404 Not Found");
145
        }
146
147
        // Test for permission
148
149
        if(!$INFO['perm']) {
150
            // not enough rights to see the wiki page
151
            $this->exit("HTTP/1.0 401 Unauthorized");
152
        }
153
154
        // Forward to URI with explicit type attribut
155
        if(!isset($_GET['type'])) {
156
            header('Location:' . $_SERVER['REQUEST_URI'] . '&type=' . $sioc_type, true, 302);
157
        }
158
159
        // Include SIOC libs
160
161
        require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'lib' . DIRECTORY_SEPARATOR . 'sioc_inc.php');
162
        require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'lib' . DIRECTORY_SEPARATOR . 'sioc_dokuwiki.php');
163
164
        // Create exporter
165
166
        $rdf              = new SIOCExporter();
167
        $rdf->profile_url = normalizeUri(
168
            getAbsUrl(
169
                exportlink(
0 ignored issues
show
The function exportlink was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

169
                /** @scrutinizer ignore-call */ 
170
                exportlink(
Loading history...
170
                    $ID, 'siocxml',
171
                    array('type' => $sioc_type), false, '&'
172
                )
173
            )
174
        );
175
        $rdf->setURLParameters('type', 'id', 'page', false);
176
177
        // Create SIOC-RDF content
178
179
        switch($sioc_type) {
180
            case 'container':
181
                $rdf = $this->exportContainercontent($rdf);
182
                break;
183
184
            case 'user':
185
                $rdf = $this->exportUsercontent($rdf);
186
                break;
187
188
            case 'post':
189
            default:
190
                $rdf = $this->exportPostcontent($rdf);
191
                break;
192
        }
193
194
        // export
195
        if($this->getConf('noindx')) {
196
            header("X-Robots-Tag: noindex", true);
197
        }
198
        $rdf->export();
199
200
        //print_r(headers_list()); die();
201
        die();
0 ignored issues
show
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
202
    }
203
204
    private function exit($headermsg) {
205
        header($headermsg);
206
        die();
207
    }
208
209
    /* -- public class methods ---------------------------------------------- */
210
211
    private function getContenttype() {
212
        global $ID, $conf;
213
214
        // check for type if unknown
215
        if(!($_GET['type'] ?? "")) {
216
            $userinfo = getDwUserInfo($ID, $this);
217
218
            if($userinfo) {
219
                $type = 'user';
220
            } elseif(isset($_GET['do']) && $_GET['do'] == 'index') {
221
                $type = 'container';
222
            } else {
223
                $type = 'post';
224
            }
225
226
        } else {
227
            $type = $_GET['type'];
228
        }
229
230
        return $type;
231
232
    }
233
234
    private function exportContainercontent($exporter) {
235
        global $ID, $INFO, $conf;
236
237
        if($ID == $conf['start']) {
238
            $title = $conf['title'];
239
        } elseif(isset($INFO['meta']['title'])) {
240
            $title = $INFO['meta']['title'];
241
        } else {
242
            $title = $ID;
243
        }
244
245
        $exporter->setParameters(
246
            'Container: ' . $title,
247
            getAbsUrl(),
248
            getAbsUrl() . 'doku.php?',
249
            'utf-8',
250
            $this->agentlink
251
        );
252
253
        // create container object
254
        $wikicontainer = new SIOCDokuWikiContainer(
255
            $ID,
256
            normalizeUri($exporter->siocURL('container', $ID))
257
        );
258
259
        /* container is type=wiki */
260
        if($ID == $conf['start']) {
261
            $wikicontainer->isWiki();
262
        }
263
        /* sioc:name              */
264
        if($INFO['exists']) {
265
            $wikicontainer->addTitle($INFO['meta']['title']);
266
        }
267
        /* has_parent             */
268
        if($INFO['namespace']) {
269
            $wikicontainer->addParent($INFO['namespace']);
270
        }
271
272
        // search next level entries (posts, sub containers) in container
273
        require_once(DOKU_INC . 'inc/search.php');
274
        $dir        = utf8_encodeFN(str_replace(':', '/', $ID));
0 ignored issues
show
The function utf8_encodeFN was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

274
        $dir        = /** @scrutinizer ignore-call */ utf8_encodeFN(str_replace(':', '/', $ID));
Loading history...
275
        $entries    = array();
276
        $posts      = array();
277
        $containers = array();
278
        search($entries, $conf['datadir'], 'search_index', array('ns' => $ID), $dir);
0 ignored issues
show
The function search was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

278
        /** @scrutinizer ignore-call */ 
279
        search($entries, $conf['datadir'], 'search_index', array('ns' => $ID), $dir);
Loading history...
279
        foreach($entries as $entry) {
280
            if($entry['type'] === 'f') {
281
                // wikisite
282
                $posts[] = $entry;
283
            } elseif($entry['type'] === 'd') {
284
                // sub container
285
                $containers[] = $entry;
286
            }
287
        }
288
289
        // without sub content it can't be a container (so it does not exist as a container)
290
        if(count($posts) + count($containers) == 0) {
291
            $this->exit("HTTP/1.0 404 Not Found");
292
        }
293
294
        if(count($posts) > 0) {
295
            $wikicontainer->addArticles($posts);
296
        }
297
        if(count($containers) > 0) {
298
            $wikicontainer->addContainers($containers);
299
        }
300
301
        //print_r($containers);die();
302
303
        // add container to exporter
304
        $exporter->addObject($wikicontainer);
305
306
        return $exporter;
307
    }
308
309
    /* -- private helpers --------------------------------------------------- */
310
311
    private function exportUsercontent($exporter) {
312
        global $ID;
313
314
        // get user info
315
        $userinfo = getDwUserInfo($ID, $this);
316
317
        // no userinfo means there is no user space or user does not exists
318
        if($userinfo === false) {
319
            $this->exit("HTTP/1.0 404 Not Found");
320
        }
321
322
        $exporter->setParameters(
323
            'Account: ' . $userinfo['name'],
324
            getAbsUrl(),
325
            getAbsUrl() . 'doku.php?',
326
            'utf-8',
327
            $this->agentlink
328
        );
329
        // create user object
330
        //print_r($userinfo); die();
331
        // $id, $url, $userid, $name, $email
332
        $wikiuser = new SIOCDokuWikiUser(
333
            $ID,
334
            normalizeUri($exporter->siocURL('user', $ID)),
335
            $userinfo['user'],
336
            $userinfo['name'],
337
            $userinfo['mail']
338
        );
339
        /* TODO: avatar (using Gravatar) */
340
        /* TODO: creator_of */
341
        // add user to exporter
342
        $exporter->addObject($wikiuser);
343
344
        //print_r(headers_list());die();
345
        return $exporter;
346
    }
347
348
    private function exportPostcontent($exporter) {
349
        global $ID, $INFO, $REV, $conf;
350
351
        $exporter->setParameters(
352
            'Article: ' . $INFO['meta']['title'] . ($REV ? ' (rev ' . $REV . ')' : ''),
353
            $this->getDokuUrl(),
354
            $this->getDokuUrl() . 'doku.php?',
355
            'utf-8',
356
            $this->agentlink
357
        );
358
359
        // create user object
360
        // $id, $uri, $name, $email, $homepage='', $foaf_uri='', $role=false, $nick='', $sioc_url='', $foaf_url=''
361
        $dwuserpage_id = cleanID($this->getConf('userns')) . ($conf['useslash'] ? '/' : ':') . $INFO['editor'];
0 ignored issues
show
The function cleanID was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

361
        $dwuserpage_id = /** @scrutinizer ignore-call */ cleanID($this->getConf('userns')) . ($conf['useslash'] ? '/' : ':') . $INFO['editor'];
Loading history...
362
        /*
363
        if ($INFO['editor'] && $this->getConf('userns'))
364
            $pageuser = new SIOCUser($INFO['editor'],
365
                                        normalizeUri(getAbsUrl(exportlink($dwuserpage_id, 'siocxml',
366
                                            array('type'=>'user'), false, '&'))), // user page
367
                                        $INFO['meta']['contributor'][$INFO['editor']],
368
                                        getDwUserInfo($dwuserpage_id,$this,'mail'),
369
                                        '', // no homepage is saved for dokuwiki user
370
                                        '#'.$INFO['editor'], // local uri
371
                                        false, // no roles right now
372
                                        '', // no nick name is saved for dokuwiki user
373
                                        normalizeUri($exporter->siocURL('user', $dwuserpage_id))
374
                                    );
375
        */
376
377
        // create wiki page object
378
        $wikipage = new SIOCDokuWikiArticle(
379
            $ID, // id
380
            normalizeUri(
381
                $exporter->siocURL(
382
                    'post', $ID . ($REV ? $exporter->_urlseparator . 'rev'
383
                              . $exporter->_urlequal . $REV : '')
384
                )
385
            ), // url
386
            $INFO['meta']['title'] . ($REV ? ' (rev ' . $REV . ')' : ''), // subject
387
            rawWiki($ID, $REV) // body (content)
0 ignored issues
show
The function rawWiki was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

387
            /** @scrutinizer ignore-call */ 
388
            rawWiki($ID, $REV) // body (content)
Loading history...
388
        );
389
        /* encoded content   */
390
        $wikipage->addContentEncoded(p_cached_output(wikiFN($ID, $REV), 'xhtml'));
0 ignored issues
show
The function p_cached_output was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

390
        $wikipage->addContentEncoded(/** @scrutinizer ignore-call */ p_cached_output(wikiFN($ID, $REV), 'xhtml'));
Loading history...
The function wikiFN was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

390
        $wikipage->addContentEncoded(p_cached_output(/** @scrutinizer ignore-call */ wikiFN($ID, $REV), 'xhtml'));
Loading history...
391
        /* created           */
392
        if(isset($INFO['meta']['date']['created'])) {
393
            $wikipage->addCreated(date('c', $INFO['meta']['date']['created']));
394
        }
395
        /* or modified       */
396
        if(isset($INFO['meta']['date']['modified'])) {
397
            $wikipage->addModified(date('c', $INFO['meta']['date']['modified']));
398
        }
399
        /* creator/modifier  */
400
        if($INFO['editor'] && $this->getConf('userns')) {
401
            $wikipage->addCreator(array('foaf:maker' => '#' . $INFO['editor'], 'sioc:modifier' => $dwuserpage_id));
402
        }
403
        /* is creator        */
404
        if(isset($INFO['meta']['date']['created'])) {
405
            $wikipage->isCreator();
406
        }
407
        /* intern wiki links */
408
        $wikipage->addLinks($INFO['meta']['relation']['references']);
409
410
        // contributors - only for last revision b/c of wrong meta data for older revisions
411
        if(!$REV && $this->getConf('userns') && isset($INFO['meta']['contributor'])) {
412
            $cont_temp = array();
413
            $cont_ns   = $this->getConf('userns') . ($conf['useslash'] ? '/' : ':');
414
            foreach($INFO['meta']['contributor'] as $cont_id => $cont_name) {
415
                $cont_temp[$cont_ns . $cont_id] = $cont_name;
416
            }
417
            $wikipage->addContributors($cont_temp);
418
        }
419
420
        // backlinks - only for last revision
421
        if(!$REV) {
422
            require_once(DOKU_INC . 'inc/fulltext.php');
423
            $backlinks = ft_backlinks($ID);
424
            if(count($backlinks) > 0) {
425
                $wikipage->addBacklinks($backlinks);
426
            }
427
        }
428
429
        // TODO: addLinksExtern
430
431
        /* previous and next revision */
432
        $changelog = new PageChangeLog($ID);
0 ignored issues
show
The type PageChangeLog was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
433
        $pagerevs  = $changelog->getRevisions(0, $conf['recent'] + 1);
434
        $prevrev   = false;
435
        $nextrev   = false;
436
        if(!$REV) {
437
            // latest revision, previous rev is on top in array
438
            $prevrev = 0;
439
        } else {
440
            // other revision
441
            $currentrev = array_search($REV, $pagerevs);
442
            if($currentrev !== false) {
443
                $prevrev = $currentrev + 1;
444
                $nextrev = $currentrev - 1;
445
            }
446
        }
447
        if($prevrev !== false && $prevrev > -1 && page_exists($ID, $pagerevs[$prevrev])) {
0 ignored issues
show
The function page_exists was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

447
        if($prevrev !== false && $prevrev > -1 && /** @scrutinizer ignore-call */ page_exists($ID, $pagerevs[$prevrev])) {
Loading history...
448
            /* previous revision*/
449
            $wikipage->addVersionPrevious($pagerevs[$prevrev]);
450
        }
451
        if($nextrev !== false && $nextrev > -1 && page_exists($ID, $pagerevs[$nextrev])) {
452
            /* next revision*/
453
            $wikipage->addVersionNext($pagerevs[$nextrev]);
454
        }
455
456
        /* latest revision   */
457
        if($REV) {
458
            $wikipage->addVersionLatest();
459
        }
460
        // TODO: topics
461
        /* has_container     */
462
        if($INFO['namespace']) {
463
            $wikipage->addContainer($INFO['namespace']);
464
        }
465
        /* has_space         */
466
        if($this->getConf('owners')) {
467
            $wikipage->addSite($this->getConf('owners'));
468
        }
469
        // TODO: dc:contributor / has_modifier
470
        // TODO: attachment (e.g. pictures in that dwns)
471
472
        // add wiki page to exporter
473
        $exporter->addObject($wikipage);
474
        //if ($INFO['editor'] && $this->getConf('userns')) $exporter->addObject($pageuser);
475
476
        return $exporter;
477
478
    }
479
480
    private function getDokuUrl($url = null) {
481
        return getAbsUrl($url);
482
    }
483
484
    public function isRdfXmlRequest() {
485
        // get accepted types
486
        $http_accept = trim($_SERVER['HTTP_ACCEPT']);
487
488
        // save accepted types in array
489
        $accepted = explode(',', $http_accept);
490
491
        /*
492
        $debuginfo = implode(' // ', array(date('c',$_SERVER['REQUEST_TIME']), $_SERVER['HTTP_REFERER'],
493
        $_SERVER['REMOTE_ADDR'], $_SERVER['REMOTE_HOST'], $_SERVER['HTTP_USER_AGENT'], $_SERVER['HTTP_ACCEPT']));
494
        global $conf; //print_r($conf); die();
495
        //die($debuginfo);
496
        $debuglog = @fopen($conf['tmpdir'].DIRECTORY_SEPARATOR.'requests.log', 'ab');
497
        @fwrite($debuglog, $debuginfo."\n");
498
        @fclose($debuglog);
499
        @chmod($conf['tmpdir'].DIRECTORY_SEPARATOR.'requests.log', 0777);
500
        */
501
502
        // soft check, route to RDF when client requests it (don't check quality of request)
503
504
        if($this->getConf('softck') && strpos($_SERVER['HTTP_ACCEPT'], 'application/rdf+xml') !== false) {
505
            return true;
506
        }
507
508
        if(count($accepted) > 0) {
509
            // hard check, only serve RDF if it is requested first or equal to first type
510
511
            // extract accepting ratio
512
            $test_accept = array();
513
            foreach($accepted as $format) {
514
                $formatspec = explode(';', $format);
515
                $k          = trim($formatspec[0]);
516
                if(count($formatspec) == 2) {
517
                    $test_accept[$k] = trim($formatspec[1]);
518
                } else {
519
                    $test_accept[$k] = 'q=1.0';
520
                }
521
            }
522
523
            // sort by ratio
524
            arsort($test_accept);
525
            $accepted_order = array_keys($test_accept);
526
527
            if($accepted_order[0] == 'application/rdf+xml' ||
528
                (array_key_exists('application/rdf+xml', $test_accept)
529
                    && $test_accept['application/rdf+xml'] == 'q=1.0')
530
            ) {
531
                return true;
532
            }
533
        }
534
535
        // print_r($accepted_order);print_r($test_accept);die();
536
537
        return false;
538
539
    }
540
541
    /**
542
     */
543
    public function createRdfLink($event = null, $param = null) {
544
        global $ID, $INFO, $conf;
545
546
        // Test for hidden pages
547
548
        if(isHiddenPage($ID)) {
549
            return false;
550
        }
551
552
        // Get type of SIOC content
553
554
        $sioc_type = $this->getContenttype();
555
556
        // Test for valid types
557
558
        if(!(($sioc_type == 'post' && $INFO['exists']) || $sioc_type == 'user' || $sioc_type == 'container')) {
559
            return false;
560
        }
561
562
        // Test for permission
563
564
        if(!$INFO['perm']) {
565
            // not enough rights to see the wiki page
566
            return false;
567
        }
568
569
        $userinfo = getDwUserInfo($ID, $this);
570
571
        // Create attributes for meta link
572
573
        $metalink['type'] = 'application/rdf+xml';
0 ignored issues
show
Comprehensibility Best Practice introduced by
$metalink was never initialized. Although not strictly required by PHP, it is generally a good practice to add $metalink = array(); before regardless.
Loading history...
574
        $metalink['rel']  = 'meta';
575
576
        switch($sioc_type) {
577
            case 'container':
578
                $title     = htmlentities(
579
                    "Container '" . ($INFO['meta']['title'] ?? $ID) . "' (SIOC document as RDF/XML)"
580
                );
581
                $queryAttr = array('type' => 'container');
582
                break;
583
584
            case 'user':
585
                $title     = htmlentities("User account '" . $userinfo['name'] . "' (SIOC document as RDF/XML)");
586
                $queryAttr = array('type' => 'user');
587
                break;
588
589
            case 'post':
590
            default:
591
                $title     = htmlentities("Article '" . $INFO['meta']['title'] . "' (SIOC document as RDF/XML)");
592
                $queryAttr = array('type' => 'post');
593
                if(isset($_GET['rev']) && $_GET['rev'] === (int) $_GET['rev']) {
594
                    $queryAttr['rev'] = $_GET['rev'];
595
                }
596
                break;
597
        }
598
599
        $metalink['title'] = $title;
600
        $metalink['href']  = normalizeUri(getAbsUrl(exportlink($ID, 'siocxml', $queryAttr, false, '&')));
0 ignored issues
show
The function exportlink was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

600
        $metalink['href']  = normalizeUri(getAbsUrl(/** @scrutinizer ignore-call */ exportlink($ID, 'siocxml', $queryAttr, false, '&')));
Loading history...
601
602
        if($event !== null) {
603
            $event->data['link'][] = $metalink;
604
605
            // set canocial link for type URIs to prevent indexing double content
606
            if($_GET['type'] ?? "") {
607
                $event->data['link'][] = array('rel' => 'canonical', 'href' => getAbsUrl(wl($ID)));
0 ignored issues
show
The function wl was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

607
                $event->data['link'][] = array('rel' => 'canonical', 'href' => getAbsUrl(/** @scrutinizer ignore-call */ wl($ID)));
Loading history...
608
            }
609
        }
610
611
        return $metalink;
612
    }
613
614
    public function pingService($data, $controller) {
615
        // TODO: test acl
616
        // TODO: write in message queue (?)
617
618
        if($data->data['preact'] == array('save' => 'Save') || $data->data['preact'] == 'save') {
619
            //die('http://pingthesemanticweb.com/rest/?url='.urlencode(getAbsUrl(wl($data->data['id']))));
620
            //$ping = fopen('http://pingthesemanticweb.com/rest/?url='.urlencode(getAbsUrl(wl($data->data['id']))),'r');
621
            // it must be a post, and it's the last revision
622
            $ping = @fopen(
623
                'http://pingthesemanticweb.com/rest/?url='
624
                . urlencode(
625
                    normalizeUri(
626
                        getAbsUrl(
627
                            exportlink(
0 ignored issues
show
The function exportlink was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

627
                            /** @scrutinizer ignore-call */ 
628
                            exportlink(
Loading history...
628
                                $data->data['id'], 'siocxml', array('type' => 'post'), false, '&'
629
                            )
630
                        )
631
                    )
632
                ), 'r'
633
            );
634
            @fclose($ping);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for fclose(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

634
            /** @scrutinizer ignore-unhandled */ @fclose($ping);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
It seems like $ping can also be of type false; however, parameter $stream of fclose() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

634
            @fclose(/** @scrutinizer ignore-type */ $ping);
Loading history...
635
        }
636
    }
637
638
    private function getDate($date, $date_alt = null) {
0 ignored issues
show
The method getDate() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
639
        if(!$date) {
640
            $date = $date_alt;
641
        }
642
        return date('c', $date);
643
    }
644
645
}
646
647
if(!function_exists('getAbsUrl')) {
648
    function getAbsUrl($url = null) {
649
        if($url == null) {
650
            $url = DOKU_BASE;
651
        }
652
        return str_replace(DOKU_BASE, DOKU_URL, $url);
0 ignored issues
show
The constant DOKU_URL was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
653
    }
654
}
655
656
if(!function_exists('getDwUserEmail')) {
657
    function getDwUserEmail($user) {
658
        global $auth;
659
        if($info = $auth->getUserData($user)) {
660
            return $info['mail'];
661
        } else {
662
            return false;
663
        }
664
    }
665
}
666
667
if(!function_exists('getDwUserInfo')) {
668
    function getDwUserInfo($id, $pobj, $key = null) {
669
        global $auth, $conf;
670
671
        if(!$pobj->getConf('userns')) {
672
            return false;
673
        }
674
675
        // get user id
676
        $userid = str_replace(cleanID($pobj->getConf('userns')) . ($conf['useslash'] ? '/' : ':'), '', $id);
0 ignored issues
show
The function cleanID was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

676
        $userid = str_replace(/** @scrutinizer ignore-call */ cleanID($pobj->getConf('userns')) . ($conf['useslash'] ? '/' : ':'), '', $id);
Loading history...
677
678
        if($info = $auth->getUserData($userid)) {
679
            if($key) {
680
                return $info['key'];
681
            } else {
682
                return $info;
683
            }
684
        } else {
685
            return false;
686
        }
687
    }
688
}
689
690
// sort query attributes by name
691
if(!function_exists('normalizeUri')) {
692
    function normalizeUri($uri) {
693
        // part URI
694
        $parts = explode('?', $uri);
695
696
        // part query
697
        if(isset($parts[1])) {
698
            $query = $parts[1];
699
700
            // test separator
701
            $sep = '&';
702
            if(strpos($query, '&amp;') !== false) {
703
                $sep = '&amp;';
704
            }
705
            $attr = explode($sep, $query);
706
707
            sort($attr);
708
709
            $parts[1] = implode($sep, $attr);
710
        }
711
712
        return implode('?', $parts);
713
    }
714
}
715
716