Passed
Pull Request — master (#6)
by Mark
02:08
created

action.php (4 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();
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));
275
        $entries    = array();
276
        $posts      = array();
277
        $containers = array();
278
        search($entries, $conf['datadir'], 'search_index', array('ns' => $ID), $dir);
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 n 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
        $wikiuser = new SIOCDokuWikiUser(
332
            $ID,
333
            normalizeUri($exporter->siocURL('user', $ID)),
334
            $userid,
335
            $userinfo['name'],
336
            $userinfo['mail']
337
        );
338
        /* TODO: avatar (using Gravatar) */
339
        /* TODO: creator_of */
340
        // add user to exporter
341
        $exporter->addObject($wikiuser);
342
343
        //print_r(headers_list());die();
344
        return $exporter;
345
    }
346
347
    private function exportPostcontent($exporter) {
348
        global $ID, $INFO, $REV, $conf;
349
350
        $exporter->setParameters(
351
            'Article: ' . $INFO['meta']['title'] . ($REV ? ' (rev ' . $REV . ')' : ''),
352
            $this->getDokuUrl(),
353
            $this->getDokuUrl() . 'doku.php?',
354
            'utf-8',
355
            $this->agentlink
356
        );
357
358
        // create user object
359
        // $id, $uri, $name, $email, $homepage='', $foaf_uri='', $role=false, $nick='', $sioc_url='', $foaf_url=''
360
        $dwuserpage_id = cleanID($this->getConf('userns')) . ($conf['useslash'] ? '/' : ':') . $INFO['editor'];
361
        /*
362
        if ($INFO['editor'] && $this->getConf('userns'))
363
            $pageuser = new SIOCUser($INFO['editor'],
364
                                        normalizeUri(getAbsUrl(exportlink($dwuserpage_id, 'siocxml',
365
                                            array('type'=>'user'), false, '&'))), // user page
366
                                        $INFO['meta']['contributor'][$INFO['editor']],
367
                                        getDwUserInfo($dwuserpage_id,$this,'mail'),
368
                                        '', // no homepage is saved for dokuwiki user
369
                                        '#'.$INFO['editor'], // local uri
370
                                        false, // no roles right now
371
                                        '', // no nick name is saved for dokuwiki user
372
                                        normalizeUri($exporter->siocURL('user', $dwuserpage_id))
373
                                    );
374
        */
375
376
        // create wiki page object
377
        $wikipage = new SIOCDokuWikiArticle(
378
            $ID, // id
379
            normalizeUri(
380
                $exporter->siocURL(
381
                    'post', $ID . ($REV ? $exporter->_urlseparator . 'rev'
382
                              . $exporter->_urlequal . $REV : '')
383
                )
384
            ), // url
385
            $INFO['meta']['title'] . ($REV ? ' (rev ' . $REV . ')' : ''), // subject
386
            rawWiki($ID, $REV) // body (content)
387
        );
388
        /* encoded content   */
389
        $wikipage->addContentEncoded(p_cached_output(wikiFN($ID, $REV), 'xhtml'));
390
        /* created           */
391
        if(isset($INFO['meta']['date']['created'])) {
392
            $wikipage->addCreated(date('c', $INFO['meta']['date']['created']));
393
        }
394
        /* or modified       */
395
        if(isset($INFO['meta']['date']['modified'])) {
396
            $wikipage->addModified(date('c', $INFO['meta']['date']['modified']));
397
        }
398
        /* creator/modifier  */
399
        if($INFO['editor'] && $this->getConf('userns')) {
400
            $wikipage->addCreator(array('foaf:maker' => '#' . $INFO['editor'], 'sioc:modifier' => $dwuserpage_id));
401
        }
402
        /* is creator        */
403
        if(isset($INFO['meta']['date']['created'])) {
404
            $wikipage->isCreator();
405
        }
406
        /* intern wiki links */
407
        $wikipage->addLinks($INFO['meta']['relation']['references']);
408
409
        // contributors - only for last revision b/c of wrong meta data for older revisions
410
        if(!$REV && $this->getConf('userns') && isset($INFO['meta']['contributor'])) {
411
            $cont_temp = array();
412
            $cont_ns   = $this->getConf('userns') . ($conf['useslash'] ? '/' : ':');
413
            foreach($INFO['meta']['contributor'] as $cont_id => $cont_name) {
414
                $cont_temp[$cont_ns . $cont_id] = $cont_name;
415
            }
416
            $wikipage->addContributors($cont_temp);
417
        }
418
419
        // backlinks - only for last revision
420
        if(!$REV) {
421
            require_once(DOKU_INC . 'inc/fulltext.php');
422
            $backlinks = ft_backlinks($ID);
423
            if(count($backlinks) > 0) {
424
                $wikipage->addBacklinks($backlinks);
425
            }
426
        }
427
428
        // TODO: addLinksExtern
429
430
        /* previous and next revision */
431
        $changelog = new PageChangeLog($ID);
432
        $pagerevs  = $changelog->getRevisions(0, $conf['recent'] + 1);
433
        $prevrev   = false;
434
        $nextrev   = false;
435
        if(!$REV) {
436
            // latest revision, previous rev is on top in array
437
            $prevrev = 0;
438
        } else {
439
            // other revision
440
            $currentrev = array_search($REV, $pagerevs);
441
            if($currentrev !== false) {
442
                $prevrev = $currentrev + 1;
443
                $nextrev = $currentrev - 1;
444
            }
445
        }
446
        if($prevrev !== false && $prevrev > -1 && page_exists($ID, $pagerevs[$prevrev])) {
447
            /* previous revision*/
448
            $wikipage->addVersionPrevious($pagerevs[$prevrev]);
449
        }
450
        if($nextrev !== false && $nextrev > -1 && page_exists($ID, $pagerevs[$nextrev])) {
451
            /* next revision*/
452
            $wikipage->addVersionNext($pagerevs[$nextrev]);
453
        }
454
455
        /* latest revision   */
456
        if($REV) {
457
            $wikipage->addVersionLatest();
458
        }
459
        // TODO: topics
460
        /* has_container     */
461
        if($INFO['namespace']) {
462
            $wikipage->addContainer($INFO['namespace']);
463
        }
464
        /* has_space         */
465
        if($this->getConf('owners')) {
466
            $wikipage->addSite($this->getConf('owners'));
467
        }
468
        // TODO: dc:contributor / has_modifier
469
        // TODO: attachment (e.g. pictures in that dwns)
470
471
        // add wiki page to exporter
472
        $exporter->addObject($wikipage);
473
        //if ($INFO['editor'] && $this->getConf('userns')) $exporter->addObject($pageuser);
474
475
        return $exporter;
476
477
    }
478
479
    private function getDokuUrl($url = null) {
480
        return getAbsUrl($url);
481
    }
482
483
    public function isRdfXmlRequest() {
484
        // get accepted types
485
        $http_accept = trim($_SERVER['HTTP_ACCEPT']);
486
487
        // save accepted types in array
488
        $accepted = explode(',', $http_accept);
489
490
        /*
491
        $debuginfo = implode(' // ', array(date('c',$_SERVER['REQUEST_TIME']), $_SERVER['HTTP_REFERER'],
492
        $_SERVER['REMOTE_ADDR'], $_SERVER['REMOTE_HOST'], $_SERVER['HTTP_USER_AGENT'], $_SERVER['HTTP_ACCEPT']));
493
        global $conf; //print_r($conf); die();
494
        //die($debuginfo);
495
        $debuglog = @fopen($conf['tmpdir'].DIRECTORY_SEPARATOR.'requests.log', 'ab');
496
        @fwrite($debuglog, $debuginfo."\n");
497
        @fclose($debuglog);
498
        @chmod($conf['tmpdir'].DIRECTORY_SEPARATOR.'requests.log', 0777);
499
        */
500
501
        // soft check, route to RDF when client requests it (don't check quality of request)
502
503
        if($this->getConf('softck') && strpos($_SERVER['HTTP_ACCEPT'], 'application/rdf+xml') !== false) {
504
            return true;
505
        }
506
507
        if(count($accepted) > 0) {
508
            // hard check, only serve RDF if it is requested first or equal to first type
509
510
            // extract accepting ratio
511
            $test_accept = array();
512
            foreach($accepted as $format) {
513
                $formatspec = explode(';', $format);
514
                $k          = trim($formatspec[0]);
515
                if(count($formatspec) == 2) {
516
                    $test_accept[$k] = trim($formatspec[1]);
517
                } else {
518
                    $test_accept[$k] = 'q=1.0';
519
                }
520
            }
521
522
            // sort by ratio
523
            arsort($test_accept);
524
            $accepted_order = array_keys($test_accept);
525
526
            if($accepted_order[0] == 'application/rdf+xml' || $test_accept['application/rdf+xml'] == 'q=1.0') {
527
                return true;
528
            }
529
        }
530
531
        // print_r($accepted_order);print_r($test_accept);die();
532
533
        return false;
534
535
    }
536
537
    /**
538
     */
539
    public function createRdfLink($event = null, $param = null) {
540
        global $ID, $INFO, $conf;
541
542
        // Test for hidden pages
543
544
        if(isHiddenPage($ID)) {
545
            return false;
546
        }
547
548
        // Get type of SIOC content
549
550
        $sioc_type = $this->getContenttype();
551
552
        // Test for valid types
553
554
        if(!(($sioc_type == 'post' && $INFO['exists']) || $sioc_type == 'user' || $sioc_type == 'container')) {
555
            return false;
556
        }
557
558
        // Test for permission
559
560
        if(!$INFO['perm']) {
561
            // not enough rights to see the wiki page
562
            return false;
563
        }
564
565
        $userinfo = getDwUserInfo($ID, $this);
566
567
        // Create attributes for meta link
568
569
        $metalink['type'] = 'application/rdf+xml';
570
        $metalink['rel']  = 'meta';
571
572
        switch($sioc_type) {
573
            case 'container':
574
                $title     = htmlentities(
575
                    "Container '" . ($INFO['meta']['title'] ?? $ID) . "' (SIOC document as RDF/XML)"
576
                );
577
                $queryAttr = array('type' => 'container');
578
                break;
579
580
            case 'user':
581
                $title     = htmlentities("User account '" . $userinfo['name'] . "' (SIOC document as RDF/XML)");
582
                $queryAttr = array('type' => 'user');
583
                break;
584
585
            case 'post':
586
            default:
587
                $title     = htmlentities("Article '" . $INFO['meta']['title'] . "' (SIOC document as RDF/XML)");
588
                $queryAttr = array('type' => 'post');
589
                if(isset($_GET['rev']) && $_GET['rev'] === (int) $_GET['rev']) {
590
                    $queryAttr['rev'] = $_GET['rev'];
591
                }
592
                break;
593
        }
594
595
        $metalink['title'] = $title;
596
        $metalink['href']  = normalizeUri(getAbsUrl(exportlink($ID, 'siocxml', $queryAttr, false, '&')));
597
598
        if($event !== null) {
599
            $event->data['link'][] = $metalink;
600
601
            // set canocial link for type URIs to prevent indexing double content
602
            if($_GET['type']) {
603
                $event->data['link'][] = array('rel' => 'canonical', 'href' => getAbsUrl(wl($ID)));
604
            }
605
        }
606
607
        return $metalink;
608
    }
609
610
    public function pingService($data, $controller) {
611
        // TODO: test acl
612
        // TODO: write in message queue (?)
613
614
        if($data->data['preact'] == array('save' => 'Save') || $data->data['preact'] == 'save') {
615
            //die('http://pingthesemanticweb.com/rest/?url='.urlencode(getAbsUrl(wl($data->data['id']))));
616
            //$ping = fopen('http://pingthesemanticweb.com/rest/?url='.urlencode(getAbsUrl(wl($data->data['id']))),'r');
617
            // it must be a post, and it's the last revision
618
            $ping = @fopen(
619
                'http://pingthesemanticweb.com/rest/?url='
620
                . urlencode(
621
                    normalizeUri(
622
                        getAbsUrl(
623
                            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

623
                            /** @scrutinizer ignore-call */ 
624
                            exportlink(
Loading history...
624
                                $data->data['id'], 'siocxml', array('type' => 'post'), false, '&'
625
                            )
626
                        )
627
                    )
628
                ), 'r'
629
            );
630
            @fclose($ping);
0 ignored issues
show
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

630
            @fclose(/** @scrutinizer ignore-type */ $ping);
Loading history...
631
        }
632
    }
633
634
    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...
635
        if(!$date) {
636
            $date = $date_alt;
637
        }
638
        return date('c', $date);
639
    }
640
641
}
642
643
if(!function_exists('getAbsUrl')) {
644
    function getAbsUrl($url = null) {
645
        if($url == null) {
646
            $url = DOKU_BASE;
647
        }
648
        return str_replace(DOKU_BASE, DOKU_URL, $url);
649
    }
650
}
651
652
if(!function_exists('getDwUserEmail')) {
653
    function getDwUserEmail($user) {
654
        global $auth;
655
        if($info = $auth->getUserData($user)) {
656
            return $info['mail'];
657
        } else {
658
            return false;
659
        }
660
    }
661
}
662
663
if(!function_exists('getDwUserInfo')) {
664
    function getDwUserInfo($id, $pobj, $key = null) {
665
        global $auth, $conf;
666
667
        if(!$pobj->getConf('userns')) {
668
            return false;
669
        }
670
671
        // get user id
672
        $userid = str_replace(cleanID($pobj->getConf('userns')) . ($conf['useslash'] ? '/' : ':'), '', $id);
673
674
        if($info = $auth->getUserData($userid)) {
675
            if($key) {
676
                return $info['key'];
677
            } else {
678
                return $info;
679
            }
680
        } else {
681
            return false;
682
        }
683
    }
684
}
685
686
// sort query attributes by name
687
if(!function_exists('normalizeUri')) {
688
    function normalizeUri($uri) {
689
        // part URI
690
        $parts = explode('?', $uri);
691
692
        // part query
693
        if(isset($parts[1])) {
694
            $query = $parts[1];
695
696
            // test separator
697
            $sep = '&';
698
            if(strpos($query, '&amp;') !== false) {
699
                $sep = '&amp;';
700
            }
701
            $attr = explode($sep, $query);
702
703
            sort($attr);
704
705
            $parts[1] = implode($sep, $attr);
706
        }
707
708
        return implode('?', $parts);
709
    }
710
}
711
712