Issues (847)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

inc/parser/renderer.php (19 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * Renderer output base class
4
 *
5
 * @author Harry Fuecks <[email protected]>
6
 * @author Andreas Gohr <[email protected]>
7
 */
8
9
use dokuwiki\Extension\Plugin;
10
use dokuwiki\Extension\SyntaxPlugin;
11
12
/**
13
 * Allowed chars in $language for code highlighting
14
 * @see GeSHi::set_language()
15
 */
16
define('PREG_PATTERN_VALID_LANGUAGE', '#[^a-zA-Z0-9\-_]#');
17
18
/**
19
 * An empty renderer, produces no output
20
 *
21
 * Inherits from dokuwiki\Plugin\DokuWiki_Plugin for giving additional functions to render plugins
22
 *
23
 * The renderer transforms the syntax instructions created by the parser and handler into the
24
 * desired output format. For each instruction a corresponding method defined in this class will
25
 * be called. That method needs to produce the desired output for the instruction and add it to the
26
 * $doc field. When all instructions are processed, the $doc field contents will be cached by
27
 * DokuWiki and sent to the user.
28
 */
29
abstract class Doku_Renderer extends Plugin {
30
    /** @var array Settings, control the behavior of the renderer */
31
    public $info = array(
32
        'cache' => true, // may the rendered result cached?
33
        'toc'   => true, // render the TOC?
34
    );
35
36
    /** @var array contains the smiley configuration, set in p_render() */
37
    public $smileys = array();
38
    /** @var array contains the entity configuration, set in p_render() */
39
    public $entities = array();
40
    /** @var array contains the acronym configuration, set in p_render() */
41
    public $acronyms = array();
42
    /** @var array contains the interwiki configuration, set in p_render() */
43
    public $interwiki = array();
44
45
    /** @var array the list of headers used to create unique link ids */
46
    protected $headers = array();
47
48
    /**
49
     * @var string the rendered document, this will be cached after the renderer ran through
50
     */
51
    public $doc = '';
52
53
    /**
54
     * clean out any per-use values
55
     *
56
     * This is called before each use of the renderer object and should be used to
57
     * completely reset the state of the renderer to be reused for a new document
58
     */
59
    public function reset(){
60
        $this->headers = array();
61
        $this->doc           = '';
62
        $this->info['cache'] = true;
63
        $this->info['toc']   = true;
64
    }
65
66
    /**
67
     * Allow the plugin to prevent DokuWiki from reusing an instance
68
     *
69
     * Since most renderer plugins fail to implement Doku_Renderer::reset() we default
70
     * to reinstantiating the renderer here
71
     *
72
     * @return bool   false if the plugin has to be instantiated
73
     */
74
    public function isSingleton() {
75
        return false;
76
    }
77
78
    /**
79
     * Returns the format produced by this renderer.
80
     *
81
     * Has to be overidden by sub classes
82
     *
83
     * @return string
84
     */
85
    abstract public function getFormat();
86
87
    /**
88
     * Disable caching of this renderer's output
89
     */
90
    public function nocache() {
91
        $this->info['cache'] = false;
92
    }
93
94
    /**
95
     * Disable TOC generation for this renderer's output
96
     *
97
     * This might not be used for certain sub renderer
98
     */
99
    public function notoc() {
100
        $this->info['toc'] = false;
101
    }
102
103
    /**
104
     * Handle plugin rendering
105
     *
106
     * Most likely this needs NOT to be overwritten by sub classes
107
     *
108
     * @param string $name  Plugin name
109
     * @param mixed  $data  custom data set by handler
110
     * @param string $state matched state if any
111
     * @param string $match raw matched syntax
112
     */
113
    public function plugin($name, $data, $state = '', $match = '') {
0 ignored issues
show
The parameter $state is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $match is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
114
        /** @var SyntaxPlugin $plugin */
115
        $plugin = plugin_load('syntax', $name);
116
        if($plugin != null) {
117
            $plugin->render($this->getFormat(), $this, $data);
118
        }
119
    }
120
121
    /**
122
     * handle nested render instructions
123
     * this method (and nest_close method) should not be overloaded in actual renderer output classes
124
     *
125
     * @param array $instructions
126
     */
127
    public function nest($instructions) {
128
        foreach($instructions as $instruction) {
129
            // execute the callback against ourself
130
            if(method_exists($this, $instruction[0])) {
131
                call_user_func_array(array($this, $instruction[0]), $instruction[1] ? $instruction[1] : array());
132
            }
133
        }
134
    }
135
136
    /**
137
     * dummy closing instruction issued by Doku_Handler_Nest
138
     *
139
     * normally the syntax mode should override this instruction when instantiating Doku_Handler_Nest -
140
     * however plugins will not be able to - as their instructions require data.
141
     */
142
    public function nest_close() {
143
    }
144
145
    #region Syntax modes - sub classes will need to implement them to fill $doc
146
147
    /**
148
     * Initialize the document
149
     */
150
    public function document_start() {
151
    }
152
153
    /**
154
     * Finalize the document
155
     */
156
    public function document_end() {
157
    }
158
159
    /**
160
     * Render the Table of Contents
161
     *
162
     * @return string
163
     */
164
    public function render_TOC() {
165
        return '';
166
    }
167
168
    /**
169
     * Add an item to the TOC
170
     *
171
     * @param string $id       the hash link
172
     * @param string $text     the text to display
173
     * @param int    $level    the nesting level
174
     */
175
    public function toc_additem($id, $text, $level) {
176
    }
177
178
    /**
179
     * Render a heading
180
     *
181
     * @param string $text  the text to display
182
     * @param int    $level header level
183
     * @param int    $pos   byte position in the original source
184
     */
185
    public function header($text, $level, $pos) {
186
    }
187
188
    /**
189
     * Open a new section
190
     *
191
     * @param int $level section level (as determined by the previous header)
192
     */
193
    public function section_open($level) {
194
    }
195
196
    /**
197
     * Close the current section
198
     */
199
    public function section_close() {
200
    }
201
202
    /**
203
     * Render plain text data
204
     *
205
     * @param string $text
206
     */
207
    public function cdata($text) {
208
    }
209
210
    /**
211
     * Open a paragraph
212
     */
213
    public function p_open() {
214
    }
215
216
    /**
217
     * Close a paragraph
218
     */
219
    public function p_close() {
220
    }
221
222
    /**
223
     * Create a line break
224
     */
225
    public function linebreak() {
226
    }
227
228
    /**
229
     * Create a horizontal line
230
     */
231
    public function hr() {
232
    }
233
234
    /**
235
     * Start strong (bold) formatting
236
     */
237
    public function strong_open() {
238
    }
239
240
    /**
241
     * Stop strong (bold) formatting
242
     */
243
    public function strong_close() {
244
    }
245
246
    /**
247
     * Start emphasis (italics) formatting
248
     */
249
    public function emphasis_open() {
250
    }
251
252
    /**
253
     * Stop emphasis (italics) formatting
254
     */
255
    public function emphasis_close() {
256
    }
257
258
    /**
259
     * Start underline formatting
260
     */
261
    public function underline_open() {
262
    }
263
264
    /**
265
     * Stop underline formatting
266
     */
267
    public function underline_close() {
268
    }
269
270
    /**
271
     * Start monospace formatting
272
     */
273
    public function monospace_open() {
274
    }
275
276
    /**
277
     * Stop monospace formatting
278
     */
279
    public function monospace_close() {
280
    }
281
282
    /**
283
     * Start a subscript
284
     */
285
    public function subscript_open() {
286
    }
287
288
    /**
289
     * Stop a subscript
290
     */
291
    public function subscript_close() {
292
    }
293
294
    /**
295
     * Start a superscript
296
     */
297
    public function superscript_open() {
298
    }
299
300
    /**
301
     * Stop a superscript
302
     */
303
    public function superscript_close() {
304
    }
305
306
    /**
307
     * Start deleted (strike-through) formatting
308
     */
309
    public function deleted_open() {
310
    }
311
312
    /**
313
     * Stop deleted (strike-through) formatting
314
     */
315
    public function deleted_close() {
316
    }
317
318
    /**
319
     * Start a footnote
320
     */
321
    public function footnote_open() {
322
    }
323
324
    /**
325
     * Stop a footnote
326
     */
327
    public function footnote_close() {
328
    }
329
330
    /**
331
     * Open an unordered list
332
     */
333
    public function listu_open() {
334
    }
335
336
    /**
337
     * Close an unordered list
338
     */
339
    public function listu_close() {
340
    }
341
342
    /**
343
     * Open an ordered list
344
     */
345
    public function listo_open() {
346
    }
347
348
    /**
349
     * Close an ordered list
350
     */
351
    public function listo_close() {
352
    }
353
354
    /**
355
     * Open a list item
356
     *
357
     * @param int $level the nesting level
358
     * @param bool $node true when a node; false when a leaf
359
     */
360
    public function listitem_open($level,$node=false) {
361
    }
362
363
    /**
364
     * Close a list item
365
     */
366
    public function listitem_close() {
367
    }
368
369
    /**
370
     * Start the content of a list item
371
     */
372
    public function listcontent_open() {
373
    }
374
375
    /**
376
     * Stop the content of a list item
377
     */
378
    public function listcontent_close() {
379
    }
380
381
    /**
382
     * Output unformatted $text
383
     *
384
     * Defaults to $this->cdata()
385
     *
386
     * @param string $text
387
     */
388
    public function unformatted($text) {
389
        $this->cdata($text);
390
    }
391
392
    /**
393
     * Output inline PHP code
394
     *
395
     * If $conf['phpok'] is true this should evaluate the given code and append the result
396
     * to $doc
397
     *
398
     * @param string $text The PHP code
399
     */
400
    public function php($text) {
401
    }
402
403
    /**
404
     * Output block level PHP code
405
     *
406
     * If $conf['phpok'] is true this should evaluate the given code and append the result
407
     * to $doc
408
     *
409
     * @param string $text The PHP code
410
     */
411
    public function phpblock($text) {
412
    }
413
414
    /**
415
     * Output raw inline HTML
416
     *
417
     * If $conf['htmlok'] is true this should add the code as is to $doc
418
     *
419
     * @param string $text The HTML
420
     */
421
    public function html($text) {
422
    }
423
424
    /**
425
     * Output raw block-level HTML
426
     *
427
     * If $conf['htmlok'] is true this should add the code as is to $doc
428
     *
429
     * @param string $text The HTML
430
     */
431
    public function htmlblock($text) {
432
    }
433
434
    /**
435
     * Output preformatted text
436
     *
437
     * @param string $text
438
     */
439
    public function preformatted($text) {
440
    }
441
442
    /**
443
     * Start a block quote
444
     */
445
    public function quote_open() {
446
    }
447
448
    /**
449
     * Stop a block quote
450
     */
451
    public function quote_close() {
452
    }
453
454
    /**
455
     * Display text as file content, optionally syntax highlighted
456
     *
457
     * @param string $text text to show
458
     * @param string $lang programming language to use for syntax highlighting
459
     * @param string $file file path label
460
     */
461
    public function file($text, $lang = null, $file = null) {
462
    }
463
464
    /**
465
     * Display text as code content, optionally syntax highlighted
466
     *
467
     * @param string $text text to show
468
     * @param string $lang programming language to use for syntax highlighting
469
     * @param string $file file path label
470
     */
471
    public function code($text, $lang = null, $file = null) {
472
    }
473
474
    /**
475
     * Format an acronym
476
     *
477
     * Uses $this->acronyms
478
     *
479
     * @param string $acronym
480
     */
481
    public function acronym($acronym) {
482
    }
483
484
    /**
485
     * Format a smiley
486
     *
487
     * Uses $this->smiley
488
     *
489
     * @param string $smiley
490
     */
491
    public function smiley($smiley) {
492
    }
493
494
    /**
495
     * Format an entity
496
     *
497
     * Entities are basically small text replacements
498
     *
499
     * Uses $this->entities
500
     *
501
     * @param string $entity
502
     */
503
    public function entity($entity) {
504
    }
505
506
    /**
507
     * Typographically format a multiply sign
508
     *
509
     * Example: ($x=640, $y=480) should result in "640×480"
510
     *
511
     * @param string|int $x first value
512
     * @param string|int $y second value
513
     */
514
    public function multiplyentity($x, $y) {
515
    }
516
517
    /**
518
     * Render an opening single quote char (language specific)
519
     */
520
    public function singlequoteopening() {
521
    }
522
523
    /**
524
     * Render a closing single quote char (language specific)
525
     */
526
    public function singlequoteclosing() {
527
    }
528
529
    /**
530
     * Render an apostrophe char (language specific)
531
     */
532
    public function apostrophe() {
533
    }
534
535
    /**
536
     * Render an opening double quote char (language specific)
537
     */
538
    public function doublequoteopening() {
539
    }
540
541
    /**
542
     * Render an closinging double quote char (language specific)
543
     */
544
    public function doublequoteclosing() {
545
    }
546
547
    /**
548
     * Render a CamelCase link
549
     *
550
     * @param string $link The link name
551
     * @see http://en.wikipedia.org/wiki/CamelCase
552
     */
553
    public function camelcaselink($link) {
554
    }
555
556
    /**
557
     * Render a page local link
558
     *
559
     * @param string $hash hash link identifier
560
     * @param string $name name for the link
561
     */
562
    public function locallink($hash, $name = null) {
563
    }
564
565
    /**
566
     * Render a wiki internal link
567
     *
568
     * @param string       $link  page ID to link to. eg. 'wiki:syntax'
569
     * @param string|array $title name for the link, array for media file
570
     */
571
    public function internallink($link, $title = null) {
572
    }
573
574
    /**
575
     * Render an external link
576
     *
577
     * @param string       $link  full URL with scheme
578
     * @param string|array $title name for the link, array for media file
579
     */
580
    public function externallink($link, $title = null) {
581
    }
582
583
    /**
584
     * Render the output of an RSS feed
585
     *
586
     * @param string $url    URL of the feed
587
     * @param array  $params Finetuning of the output
588
     */
589
    public function rss($url, $params) {
590
    }
591
592
    /**
593
     * Render an interwiki link
594
     *
595
     * You may want to use $this->_resolveInterWiki() here
596
     *
597
     * @param string       $link     original link - probably not much use
598
     * @param string|array $title    name for the link, array for media file
599
     * @param string       $wikiName indentifier (shortcut) for the remote wiki
600
     * @param string       $wikiUri  the fragment parsed from the original link
601
     */
602
    public function interwikilink($link, $title, $wikiName, $wikiUri) {
0 ignored issues
show
The parameter $link is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
603
    }
604
605
    /**
606
     * Link to file on users OS
607
     *
608
     * @param string       $link  the link
609
     * @param string|array $title name for the link, array for media file
610
     */
611
    public function filelink($link, $title = null) {
0 ignored issues
show
The parameter $link is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $title is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
612
    }
613
614
    /**
615
     * Link to windows share
616
     *
617
     * @param string       $link  the link
618
     * @param string|array $title name for the link, array for media file
619
     */
620
    public function windowssharelink($link, $title = null) {
621
    }
622
623
    /**
624
     * Render a linked E-Mail Address
625
     *
626
     * Should honor $conf['mailguard'] setting
627
     *
628
     * @param string $address Email-Address
629
     * @param string|array $name name for the link, array for media file
630
     */
631
    public function emaillink($address, $name = null) {
632
    }
633
634
    /**
635
     * Render an internal media file
636
     *
637
     * @param string $src     media ID
638
     * @param string $title   descriptive text
639
     * @param string $align   left|center|right
640
     * @param int    $width   width of media in pixel
641
     * @param int    $height  height of media in pixel
642
     * @param string $cache   cache|recache|nocache
643
     * @param string $linking linkonly|detail|nolink
644
     */
645
    public function internalmedia($src, $title = null, $align = null, $width = null,
646
                           $height = null, $cache = null, $linking = null) {
647
    }
648
649
    /**
650
     * Render an external media file
651
     *
652
     * @param string $src     full media URL
653
     * @param string $title   descriptive text
654
     * @param string $align   left|center|right
655
     * @param int    $width   width of media in pixel
656
     * @param int    $height  height of media in pixel
657
     * @param string $cache   cache|recache|nocache
658
     * @param string $linking linkonly|detail|nolink
659
     */
660
    public function externalmedia($src, $title = null, $align = null, $width = null,
661
                           $height = null, $cache = null, $linking = null) {
662
    }
663
664
    /**
665
     * Render a link to an internal media file
666
     *
667
     * @param string $src     media ID
668
     * @param string $title   descriptive text
669
     * @param string $align   left|center|right
670
     * @param int    $width   width of media in pixel
671
     * @param int    $height  height of media in pixel
672
     * @param string $cache   cache|recache|nocache
673
     */
674
    public function internalmedialink($src, $title = null, $align = null,
0 ignored issues
show
The parameter $src is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $title is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $align is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
675
                               $width = null, $height = null, $cache = null) {
0 ignored issues
show
The parameter $width is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $height is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $cache is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
676
    }
677
678
    /**
679
     * Render a link to an external media file
680
     *
681
     * @param string $src     media ID
682
     * @param string $title   descriptive text
683
     * @param string $align   left|center|right
684
     * @param int    $width   width of media in pixel
685
     * @param int    $height  height of media in pixel
686
     * @param string $cache   cache|recache|nocache
687
     */
688
    public function externalmedialink($src, $title = null, $align = null,
0 ignored issues
show
The parameter $src is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $title is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $align is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
689
                               $width = null, $height = null, $cache = null) {
0 ignored issues
show
The parameter $width is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $height is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $cache is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
690
    }
691
692
    /**
693
     * Start a table
694
     *
695
     * @param int $maxcols maximum number of columns
696
     * @param int $numrows NOT IMPLEMENTED
697
     * @param int $pos     byte position in the original source
698
     */
699
    public function table_open($maxcols = null, $numrows = null, $pos = null) {
0 ignored issues
show
The parameter $maxcols is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $numrows is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
700
    }
701
702
    /**
703
     * Close a table
704
     *
705
     * @param int $pos byte position in the original source
706
     */
707
    public function table_close($pos = null) {
708
    }
709
710
    /**
711
     * Open a table header
712
     */
713
    public function tablethead_open() {
714
    }
715
716
    /**
717
     * Close a table header
718
     */
719
    public function tablethead_close() {
720
    }
721
722
    /**
723
     * Open a table body
724
     */
725
    public function tabletbody_open() {
726
    }
727
728
    /**
729
     * Close a table body
730
     */
731
    public function tabletbody_close() {
732
    }
733
734
    /**
735
     * Open a table footer
736
     */
737
    public function tabletfoot_open() {
738
    }
739
740
    /**
741
     * Close a table footer
742
     */
743
    public function tabletfoot_close() {
744
    }
745
746
    /**
747
     * Open a table row
748
     */
749
    public function tablerow_open() {
750
    }
751
752
    /**
753
     * Close a table row
754
     */
755
    public function tablerow_close() {
756
    }
757
758
    /**
759
     * Open a table header cell
760
     *
761
     * @param int    $colspan
762
     * @param string $align left|center|right
763
     * @param int    $rowspan
764
     */
765
    public function tableheader_open($colspan = 1, $align = null, $rowspan = 1) {
766
    }
767
768
    /**
769
     * Close a table header cell
770
     */
771
    public function tableheader_close() {
772
    }
773
774
    /**
775
     * Open a table cell
776
     *
777
     * @param int    $colspan
778
     * @param string $align left|center|right
779
     * @param int    $rowspan
780
     */
781
    public function tablecell_open($colspan = 1, $align = null, $rowspan = 1) {
782
    }
783
784
    /**
785
     * Close a table cell
786
     */
787
    public function tablecell_close() {
788
    }
789
790
    #endregion
791
792
    #region util functions, you probably won't need to reimplement them
793
794
    /**
795
     * Creates a linkid from a headline
796
     *
797
     * @author Andreas Gohr <[email protected]>
798
     * @param string  $title   The headline title
799
     * @param boolean $create  Create a new unique ID?
800
     * @return string
801
     */
802
    public function _headerToLink($title, $create = false) {
803
        if($create) {
804
            return sectionID($title, $this->headers);
805
        } else {
806
            $check = false;
807
            return sectionID($title, $check);
808
        }
809
    }
810
811
    /**
812
     * Removes any Namespace from the given name but keeps
813
     * casing and special chars
814
     *
815
     * @author Andreas Gohr <[email protected]>
816
     *
817
     * @param string $name
818
     * @return string
819
     */
820
    public function _simpleTitle($name) {
821
        global $conf;
822
823
        //if there is a hash we use the ancor name only
824
        @list($name, $hash) = explode('#', $name, 2);
825
        if($hash) return $hash;
826
827
        if($conf['useslash']) {
828
            $name = strtr($name, ';/', ';:');
829
        } else {
830
            $name = strtr($name, ';', ':');
831
        }
832
833
        return noNSorNS($name);
834
    }
835
836
    /**
837
     * Resolve an interwikilink
838
     *
839
     * @param string    $shortcut  identifier for the interwiki link
840
     * @param string    $reference fragment that refers the content
841
     * @param null|bool $exists    reference which returns if an internal page exists
842
     * @return string interwikilink
843
     */
844
    public function _resolveInterWiki(&$shortcut, $reference, &$exists = null) {
845
        //get interwiki URL
846
        if(isset($this->interwiki[$shortcut])) {
847
            $url = $this->interwiki[$shortcut];
848
        }elseif(isset($this->interwiki['default'])) {
849
            $shortcut = 'default';
850
            $url = $this->interwiki[$shortcut];
851
        }else{
852
            // not parsable interwiki outputs '' to make sure string manipluation works
853
            $shortcut = '';
854
            $url      = '';
855
        }
856
857
        //split into hash and url part
858
        $hash = strrchr($reference, '#');
859
        if($hash) {
860
            $reference = substr($reference, 0, -strlen($hash));
861
            $hash = substr($hash, 1);
862
        }
863
864
        //replace placeholder
865
        if(preg_match('#\{(URL|NAME|SCHEME|HOST|PORT|PATH|QUERY)\}#', $url)) {
866
            //use placeholders
867
            $url    = str_replace('{URL}', rawurlencode($reference), $url);
868
            //wiki names will be cleaned next, otherwise urlencode unsafe chars
869
            $url    = str_replace('{NAME}', ($url[0] === ':') ? $reference :
870
                                  preg_replace_callback('/[[\\\\\]^`{|}#%]/', function($match) {
871
                                    return rawurlencode($match[0]);
872
                                  }, $reference), $url);
873
            $parsed = parse_url($reference);
874
            if (empty($parsed['scheme'])) $parsed['scheme'] = '';
875
            if (empty($parsed['host'])) $parsed['host'] = '';
876
            if (empty($parsed['port'])) $parsed['port'] = 80;
877
            if (empty($parsed['path'])) $parsed['path'] = '';
878
            if (empty($parsed['query'])) $parsed['query'] = '';
879
            $url = strtr($url,[
880
                '{SCHEME}' => $parsed['scheme'],
881
                '{HOST}' => $parsed['host'],
882
                '{PORT}' => $parsed['port'],
883
                '{PATH}' => $parsed['path'],
884
                '{QUERY}' => $parsed['query'] ,
885
            ]);
886
        } else if($url != '') {
887
            // make sure when no url is defined, we keep it null
888
            // default
889
            $url = $url.rawurlencode($reference);
890
        }
891
        //handle as wiki links
892
        if($url && $url[0] === ':') {
893
            $urlparam = null;
894
            $id = $url;
895
            if (strpos($url, '?') !== false) {
896
                list($id, $urlparam) = explode('?', $url, 2);
897
            }
898
            $url    = wl(cleanID($id), $urlparam);
899
            $exists = page_exists($id);
900
        }
901
        if($hash) $url .= '#'.rawurlencode($hash);
902
903
        return $url;
904
    }
905
906
    #endregion
907
}
908
909
910
//Setup VIM: ex: et ts=4 :
911