Passed
Pull Request — master (#2)
by Mark
02:12 queued 31s
created

action.php (2 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
if(!defined('DOKU_INC')) die();
72
if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
73
require_once(DOKU_PLUGIN.'action.php');
74
 
75
class action_plugin_dokusioc extends DokuWiki_Action_Plugin {
76
77
    var $agentlink = 'http://eye48.com/go/dokusioc?v=0.1.2';
78
79
80
    /* -- Methods to manage plugin ------------------------------------------ */
81
82
    /**
83
    * Register its handlers with the DokuWiki's event controller
84
    */
85
    function register(Doku_Event_Handler $controller)
1 ignored issue
show
The type Doku_Event_Handler 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...
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
86
    {
87
        //print_r(headers_list()); die();
88
        
89
        // test the requested action
90
        $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE',  $this, 'checkAction', $controller);
91
        // pingthesemanticweb.com
92
        if ($this->getConf('pingsw')) $controller->register_hook('ACTION_SHOW_REDIRECT', 'BEFORE',  $this, 'pingService', $controller);
93
    }
94
 
95
    /* -- Event handlers ---------------------------------------------------- */
96
97
    function checkAction($action, $controller)
98
    {
99
        global $INFO;
100
        //print_r($INFO); die();
101
        //print_r(headers_list()); die();
102
103
        if ($action->data == 'export_siocxml')
104
        {
105
            // give back rdf
106
            $this->exportSioc();
107
        }
108
        elseif (($action->data == 'show' || $action->data == 'index') && $INFO['perm'] && !defined('DOKU_MEDIADETAIL') && ($INFO['exists'] || getDwUserInfo($INFO['id'],$this)) && !isHiddenPage($INFO['id']))
109
        {
110
            if ($this->isRdfXmlRequest())
111
            {
112
                // forward to rdfxml document if requested
113
                // print_r(headers_list()); die();
114
                $location = $this->createRdfLink();
115
                if (function_exists('header_remove')) header_remove();
116
                header('Location: '.$location['href'], true, 303); exit();
117
            }
118
            else
119
            {
120
                // add meta link to html head
121
                $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE',  $this, 'createRdfLink');
122
            }
123
        }
124
        /*
125
        else
126
        {
127
            print_r(array($action->data, $INFO['perm'], defined('DOKU_MEDIADETAIL'), $INFO['exists'], getDwUserInfo($INFO['id'],$this), isHiddenPage($INFO['id'])));
128
            die();
129
        }
130
        */
131
    }
132
    
133
    function pingService($data, $controller)
134
    {
135
        // TODO: test acl
136
        // TODO: write in message queue (?)
137
        
138
        if ($data->data['preact'] == array('save'=>'Save') || $data->data['preact'] == 'save')
139
        {
140
            //die('http://pingthesemanticweb.com/rest/?url='.urlencode(getAbsUrl(wl($data->data['id']))));
141
            //$ping = fopen('http://pingthesemanticweb.com/rest/?url='.urlencode(getAbsUrl(wl($data->data['id']))),'r');
142
            // it must be a post, and it's the last revision
143
            $ping = @fopen('http://pingthesemanticweb.com/rest/?url='.urlencode(normalizeUri(getAbsUrl(exportlink($data->data['id'], 'siocxml', array('type'=>'post'), false, '&')))),'r');
144
            @fclose($ping);
145
        }
146
    }
147
    
148
    /**
149
    */
150
    function createRdfLink($event = null, $param = null)
151
    {
152
        global $ID, $INFO, $conf;
153
        
154
        // Test for hidden pages
155
        
156
        if (isHiddenPage($ID))
157
            return false;
158
        
159
        // Get type of SIOC content
160
        
161
        $sioc_type = $this->_getContenttype();
162
        
163
        // Test for valid types
164
        
165
        if (!(($sioc_type == 'post' && $INFO['exists']) || $sioc_type == 'user' || $sioc_type == 'container'))
166
            return false;
167
        
168
        // Test for permission
169
        
170
        if (!$INFO['perm']) // not enough rights to see the wiki page
171
            return false;
172
173
        $userinfo = getDwUserInfo($ID, $this);
174
        
175
        // Create attributes for meta link
176
        
177
        $metalink['type'] = 'application/rdf+xml';
178
        $metalink['rel'] = 'meta';
179
        
180
        switch ($sioc_type)
181
        {
182
            case 'container':
183
                $title = htmlentities("Container '".(isset($INFO['meta']['title'])?$INFO['meta']['title']:$ID)."' (SIOC document as RDF/XML)");
184
                $queryAttr = array('type'=>'container');
185
                break;
186
                
187
            case 'user':
188
                $title = htmlentities("User account '".$userinfo['name']."' (SIOC document as RDF/XML)");
189
                $queryAttr =  array('type'=>'user');
190
                break;
191
192
            case 'post':
193
            default:
194
                $title = htmlentities("Article '".$INFO['meta']['title']."' (SIOC document as RDF/XML)");
195
                $queryAttr =  array('type'=>'post');
196
                if (isset($_GET['rev']) && $_GET['rev'] == intval($_GET['rev']))
197
                    $queryAttr['rev'] = $_GET['rev'];
198
                break;
199
        }
200
    
201
        $metalink['title'] = $title;
202
        $metalink['href'] = normalizeUri(getAbsUrl(exportlink($ID, 'siocxml', $queryAttr, false, '&')));
203
204
        if ($event !== null)
205
        {
206
            $event->data['link'][] = $metalink;
207
            
208
            // set canocial link for type URIs to prevent indexing double content
209
            if ($_GET['type'])
210
                $event->data['link'][] = array('rel'=>'canonical', 'href'=>getAbsUrl(wl($ID)));
211
        }
212
        
213
        return $metalink;
214
    }
215
    
216
    /* -- public class methods ---------------------------------------------- */
217
218
    function exportSioc()
219
    {
220
        global $ID, $INFO, $conf, $REV, $auth;
221
        
222
        // Test for hidden pages
223
        
224
        if (isHiddenPage($ID))
225
            $this->_exit("HTTP/1.0 404 Not Found");
226
        
227
        // Get type of SIOC content
228
        
229
        $sioc_type = $this->_getContenttype();
230
        
231
        // Test for valid types
232
        
233
        if (!(($sioc_type == 'post' && $INFO['exists']) || $sioc_type == 'user' || $sioc_type == 'container'))
234
            $this->_exit("HTTP/1.0 404 Not Found");
235
        
236
        // Test for permission
237
        
238
        if (!$INFO['perm']) // not enough rights to see the wiki page
239
            $this->_exit("HTTP/1.0 401 Unauthorized");
240
241
        // Forward to URI with explicit type attribut
242
        if (!isset($_GET['type'])) header('Location:'.$_SERVER['REQUEST_URI'].'&type='.$sioc_type, true, 302);
243
244
        // Include SIOC libs
245
        
246
        require_once(dirname(__FILE__).DIRECTORY_SEPARATOR.'lib'.DIRECTORY_SEPARATOR.'sioc_inc.php');
247
        require_once(dirname(__FILE__).DIRECTORY_SEPARATOR.'lib'.DIRECTORY_SEPARATOR.'sioc_dokuwiki.php');
248
        
249
        // Create exporter
250
        
251
        $rdf = new SIOCExporter();
252
        $rdf->_profile_url = normalizeUri(getAbsUrl(exportlink($ID, 'siocxml', array('type'=>$sioc_type), false, '&')));
253
        $rdf->setURLParameters('type', 'id', 'page', false);
254
        
255
        // Create SIOC-RDF content
256
        
257
        switch ($sioc_type)
258
        {
259
            case 'container':
260
                $rdf = $this->_exportContainercontent($rdf);
261
                break;
262
                
263
            case 'user':
264
                $rdf = $this->_exportUsercontent($rdf);
265
                break;
266
267
            case 'post':
268
            default:
269
                $rdf = $this->_exportPostcontent($rdf);
270
                break;
271
        }
272
    
273
        // export
274
        if ($this->getConf('noindx')) 
275
            header("X-Robots-Tag: noindex", true);
276
        $rdf->export();
277
        
278
        //print_r(headers_list()); die();
279
        die();
280
    }
281
    
282
    function isRdfXmlRequest()
283
    {   
284
        // get accepted types
285
        $http_accept = trim($_SERVER['HTTP_ACCEPT']);
286
        
287
        // save accepted types in array
288
        $accepted = explode(',', $http_accept);
289
        
290
        /*
291
        $debuginfo = implode(' // ', array(date('c',$_SERVER['REQUEST_TIME']), $_SERVER['HTTP_REFERER'], $_SERVER['REMOTE_ADDR'], $_SERVER['REMOTE_HOST'], $_SERVER['HTTP_USER_AGENT'], $_SERVER['HTTP_ACCEPT']));
292
        global $conf; //print_r($conf); die();
293
        //die($debuginfo);
294
        $debuglog = @fopen($conf['tmpdir'].DIRECTORY_SEPARATOR.'requests.log', 'ab');
295
        @fwrite($debuglog, $debuginfo."\n");
296
        @fclose($debuglog);
297
        @chmod($conf['tmpdir'].DIRECTORY_SEPARATOR.'requests.log', 0777);
298
        */
299
        
300
        // soft check, route to RDF when client requests it (don't check quality of request)
301
        
302
        if ($this->getConf('softck') && strpos($_SERVER['HTTP_ACCEPT'], 'application/rdf+xml') !== false)
303
        {
304
            return true;
305
        }
306
        
307
        if (count($accepted)>0)
308
        {
309
            // hard check, only serve RDF if it is requested first or equal to first type
310
    
311
            // extract accepting ratio
312
            $test_accept = array();
313
            foreach($accepted as $format)
314
            {
315
                $formatspec = explode(';',$format);
316
                $k = trim($formatspec[0]);
317
                if (count($formatspec)==2)
318
                {
319
                    $test_accept[$k] = trim($formatspec[1]);
320
                }
321
                else
322
                {
323
                    $test_accept[$k] = 'q=1.0';
324
                }
325
            }
326
            
327
            // sort by ratio
328
            arsort($test_accept); $accepted_order = array_keys($test_accept);
329
            
330
            if ($accepted_order[0] == 'application/rdf+xml' || $test_accept['application/rdf+xml'] == 'q=1.0')
331
            {
332
                return true;
333
            }
334
        }
335
336
        // print_r($accepted_order);print_r($test_accept);die();
337
338
        return false;
339
340
    }
341
342
    /* -- private helpers --------------------------------------------------- */
343
    
344
    function _getContenttype()
345
    {
346
        global $ID, $conf;
347
348
        // check for type if unknown
349
        if (!$_GET['type'])
350
        {
351
            $userinfo = getDwUserInfo($ID, $this);
352
            
353
            if ($userinfo)
354
            {
355
                $type = 'user';
356
            }
357
            elseif (isset($_GET['do']) && $_GET['do'] == 'index')
358
            {
359
                $type = 'container';
360
            }
361
            else
362
            {
363
                $type = 'post';
364
            }
365
            
366
        }
367
        else
368
        {
369
            $type = $_GET['type'];
370
        }
371
        
372
        return $type;
373
    
374
    }
375
    
376
    function _exportPostcontent($exporter)
377
    {
378
        global $ID, $INFO, $REV, $conf;
379
380
        $exporter->setParameters('Article: '.$INFO['meta']['title'].($REV?' (rev '.$REV.')':''),
381
                            $this->_getDokuUrl(),
382
                            $this->_getDokuUrl().'doku.php?',
383
                            'utf-8',
384
                            $this->agentlink
385
                            );
386
387
        // create user object
388
        // $id, $uri, $name, $email, $homepage='', $foaf_uri='', $role=false, $nick='', $sioc_url='', $foaf_url=''
389
        $dwuserpage_id = cleanID($this->getConf('userns')).($conf['useslash']?'/':':').$INFO['editor'];
390
        /*
391
        if ($INFO['editor'] && $this->getConf('userns'))
392
            $pageuser = new SIOCUser($INFO['editor'],
393
                                        normalizeUri(getAbsUrl(exportlink($dwuserpage_id, 'siocxml', array('type'=>'user'), false, '&'))), // user page
394
                                        $INFO['meta']['contributor'][$INFO['editor']],
395
                                        getDwUserInfo($dwuserpage_id,$this,'mail'),
396
                                        '', // no homepage is saved for dokuwiki user
397
                                        '#'.$INFO['editor'], // local uri
398
                                        false, // no roles right now
399
                                        '', // no nick name is saved for dokuwiki user
400
                                        normalizeUri($exporter->siocURL('user', $dwuserpage_id))
401
                                    );
402
        */
403
        
404
        // create wiki page object
405
        $wikipage = new SIOCDokuWikiArticle($ID, // id
406
                                            normalizeUri($exporter->siocURL('post', $ID.($REV?$exporter->_urlseparator.'rev'.$exporter->_urlequal.$REV:''))), // url
407
                                            $INFO['meta']['title'].($REV?' (rev '.$REV.')':''), // subject
408
                                            rawWiki($ID,$REV) // body (content)
409
                                            );
410
        /* encoded content   */ $wikipage->addContentEncoded(p_cached_output(wikiFN($ID,$REV),'xhtml'));
411
        /* created           */ if (isset($INFO['meta']['date']['created'])) $wikipage->addCreated(date('c', $INFO['meta']['date']['created']));
412
        /* or modified       */ if (isset($INFO['meta']['date']['modified'])) $wikipage->addModified(date('c', $INFO['meta']['date']['modified']));
413
        /* creator/modifier  */ if ($INFO['editor'] && $this->getConf('userns')) $wikipage->addCreator(array('foaf:maker'=>'#'.$INFO['editor'],'sioc:modifier'=>$dwuserpage_id));
414
        /* is creator        */ if (isset($INFO['meta']['date']['created'])) $wikipage->isCreator();
415
        /* intern wiki links */ $wikipage->addLinks($INFO['meta']['relation']['references']);
416
        
417
        // contributors - only for last revision b/c of wrong meta data for older revisions
418
        if (!$REV && $this->getConf('userns') && isset($INFO['meta']['contributor']))
419
        {
420
            $cont_temp = array();
421
            $cont_ns = $this->getConf('userns').($conf['useslash']?'/':':');
422
            foreach($INFO['meta']['contributor'] as $cont_id => $cont_name)
423
                $cont_temp[$cont_ns.$cont_id] = $cont_name;
424
            $wikipage->addContributors($cont_temp);
425
        }
426
        
427
        // backlinks - only for last revision
428
        if (!$REV)
429
        {
430
            require_once(DOKU_INC.'inc/fulltext.php');
431
            $backlinks = ft_backlinks($ID);
432
            if (count($backlinks) > 0) $wikipage->addBacklinks($backlinks);
433
        }
434
        
435
        // TODO: addLinksExtern
436
437
        /* previous and next revision */
438
        $changelog = new PageChangeLog($ID);
439
        $pagerevs = $changelog->getRevisions(0,$conf['recent']+1);
440
        $prevrev = false; $nextrev = false;
441
        if (!$REV)
442
        {
443
            // latest revision, previous rev is on top in array
444
            $prevrev = 0;
445
        }
446
        else
447
        {
448
            // other revision
449
            $currentrev = array_search($REV, $pagerevs);
450
            if ($currentrev !== false)
451
            {
452
                $prevrev = $currentrev + 1;
453
                $nextrev = $currentrev - 1;
454
            }
455
        }
456
        if ($prevrev !== false && $prevrev > -1 && page_exists($ID,$pagerevs[$prevrev]))
457
        /* previous revision*/ $wikipage->addVersionPrevious($pagerevs[$prevrev]);
458
        if ($nextrev !== false && $nextrev > -1 && page_exists($ID,$pagerevs[$nextrev]))
459
        /* next revision*/ $wikipage->addVersionNext($pagerevs[$nextrev]);
460
461
        /* latest revision   */ if ($REV) $wikipage->addVersionLatest();
462
        // TODO: topics
463
        /* has_container     */ if ($INFO['namespace']) $wikipage->addContainer($INFO['namespace']); 
464
        /* has_space         */ if ($this->getConf('owners')) $wikipage->addSite($this->getConf('owners')); 
465
        // TODO: dc:contributor / has_modifier
466
        // TODO: attachment (e.g. pictures in that dwns)
467
        
468
        // add wiki page to exporter
469
        $exporter->addObject($wikipage);
470
        //if ($INFO['editor'] && $this->getConf('userns')) $exporter->addObject($pageuser);
471
        
472
        return $exporter;
473
        
474
    }
475
    
476
    function _exportContainercontent($exporter)
477
    {
478
        global $ID, $INFO, $conf;
479
        
480
        if ($ID == $conf['start'])
481
        {
482
            $title = $conf['title'];
483
        }
484
        elseif (isset($INFO['meta']['title']))
485
        {
486
            $title = $INFO['meta']['title'];
487
        }
488
        else
489
        {
490
            $title = $ID;
491
        }
492
        
493
    
494
        $exporter->setParameters('Container: '.$title,
495
                            getAbsUrl(),
496
                            getAbsUrl().'doku.php?',
497
                            'utf-8',
498
                            $this->agentlink
499
                            );
500
501
        // create container object
502
        $wikicontainer = new SIOCDokuWikiContainer($ID,
503
                                                   normalizeUri($exporter->siocURL('container', $ID))
504
                                                  );
505
506
        /* container is type=wiki */ if ($ID == $conf['start']) $wikicontainer->isWiki();
507
        /* sioc:name              */ if ($INFO['exists']) $wikicontainer->addTitle($INFO['meta']['title']);
508
        /* has_parent             */ if ($INFO['namespace']) $wikicontainer->addParent($INFO['namespace']); 
509
510
        // search next level entries (posts, sub containers) in container
511
        require_once(DOKU_INC.'inc/search.php');
512
        $dir  = utf8_encodeFN(str_replace(':','/',$ID));
513
        $entries = array();
514
        $posts = array();
515
        $containers = array();
516
        search($entries,$conf['datadir'],'search_index',array('ns' => $ID),$dir);
517
        foreach ($entries as $entry)
518
        {
519
            if ($entry['type'] === 'f')
520
            {
521
                // wikisite
522
                $posts[] = $entry;
523
            }
524
            elseif($entry['type'] === 'd')
525
            {
526
                // sub container
527
                $containers[] = $entry;
528
            }
529
        }
530
        
531
        // without sub content it can't be a container (so it does not exist as a container)
532
        if (count($posts) + count($containers) == 0)
533
            $this->_exit("HTTP/1.0 404 Not Found");
534
        
535
        if (count($posts)>0) $wikicontainer->addArticles($posts);
536
        if (count($containers)>0) $wikicontainer->addContainers($containers);
537
538
        //print_r($containers);die();
539
        
540
        // add container to exporter
541
        $exporter->addObject($wikicontainer);
542
        
543
        return $exporter;
544
    }
545
    
546
    function _exportUsercontent($exporter)
547
    {
548
        global $ID;
549
                
550
        // get user info
551
        $userinfo = getDwUserInfo($ID,$this);
552
        
553
        // no userinfo means there is n user space or user does not exists
554
        if ($userinfo === false)
555
            $this->_exit("HTTP/1.0 404 Not Found");
556
        
557
        $exporter->setParameters('Account: '.$userinfo['name'],
558
                            getAbsUrl(),
559
                            getAbsUrl().'doku.php?',
560
                            'utf-8',
561
                            $this->agentlink
562
                            );
563
        // create user object
564
        //print_r($userinfo); die();
565
        $wikiuser = new SIOCDokuWikiUser($ID,
566
                                         normalizeUri($exporter->siocURL('user', $ID)),
567
                                         $userid,
568
                                         $userinfo['name'],
569
                                         $userinfo['mail']);
570
        /* TODO: avatar (using Gravatar) */
571
        /* TODO: creator_of */
572
        // add user to exporter
573
        $exporter->addObject($wikiuser);
574
        
575
        //print_r(headers_list());die();
576
        return $exporter;
577
    }
578
    
579
    function _exit($headermsg)
580
    {
581
        header($headermsg);
582
        die();
583
    }
584
585
    function _getDokuUrl($url=null)
586
    {
587
        return getAbsUrl($url);
588
    }
589
    
590
    function _getDate($date, $date_alt=null)
591
    {
592
        if (!$date) $date = $date_alt;
593
        return date('c',$date);
594
    }
595
    
596
}
597
598
if (!function_exists('getAbsUrl'))
599
{
600
    function getAbsUrl($url=null)
601
    {
602
        if ($url == null) $url = DOKU_BASE;
603
        return str_replace(DOKU_BASE, DOKU_URL, $url);
604
    }
605
}
606
607
if (!function_exists('getDwUserEmail'))
608
{
609
    function getDwUserEmail($user)
610
    {
611
        global $auth;
612
        if ($info = $auth->getUserData($user))
613
        {
614
            return $info['mail'];
615
        }
616
        else
617
        {
618
            return false;
619
        }
620
    }
621
}
622
623
if (!function_exists('getDwUserInfo'))
624
{
625
    function getDwUserInfo($id, $pobj, $key = null)
626
    {
627
        global $auth, $conf;
628
        
629
        if (!$pobj->getConf('userns')) return false;
630
        
631
        // get user id
632
        $userid = str_replace(cleanID($pobj->getConf('userns')).($conf['useslash']?'/':':'),'',$id);
633
        
634
        if ($info = $auth->getUserData($userid))
635
        {
636
            if ($key)
637
            {
638
                return $info['key'];
639
            }
640
            else
641
            {
642
                return $info;
643
            }
644
        }
645
        else
646
        {
647
            return false;
648
        }
649
    }
650
}
651
652
// sort query attributes by name
653
if (!function_exists('normalizeUri'))
654
{
655
    function normalizeUri($uri)
656
    {
657
        // part URI
658
        $parts = explode('?', $uri);
659
        
660
        // part query
661
        if (isset($parts[1]))
662
        {
663
            $query = $parts[1];
664
            
665
            // test separator
666
            $sep = '&';
667
            if (strpos($query, '&amp;') !== false) $sep = '&amp;';
668
            $attr = explode($sep, $query);
669
            
670
            sort($attr);
671
            
672
            $parts[1] = implode($sep, $attr);
673
        }
674
        
675
        return implode('?', $parts);
676
    }
677
}
678
679