Failed Conditions
Pull Request — master (#3198)
by
unknown
02:50
created

html.php ➔ html_revisions()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 2
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * HTML output functions
4
 *
5
 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
6
 * @author     Andreas Gohr <[email protected]>
7
 */
8
9
use dokuwiki\ChangeLog\MediaChangeLog;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, MediaChangeLog.

Let’s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let’s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
10
use dokuwiki\ChangeLog\PageChangeLog;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, PageChangeLog.

Let’s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let’s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
11
use dokuwiki\Extension\AuthPlugin;
12
use dokuwiki\Extension\Event;
13
14
if (!defined('SEC_EDIT_PATTERN')) {
15
    define('SEC_EDIT_PATTERN', '#<!-- EDIT({.*?}) -->#');
16
}
17
18
19
/**
20
 * Convenience function to quickly build a wikilink
21
 *
22
 * @author Andreas Gohr <[email protected]>
23
 * @param string  $id      id of the target page
24
 * @param string  $name    the name of the link, i.e. the text that is displayed
25
 * @param string|array  $search  search string(s) that shall be highlighted in the target page
26
 * @return string the HTML code of the link
27
 */
28
function html_wikilink($id,$name=null,$search=''){
29
    /** @var Doku_Renderer_xhtml $xhtml_renderer */
30
    static $xhtml_renderer = null;
31
    if(is_null($xhtml_renderer)){
32
        $xhtml_renderer = p_get_renderer('xhtml');
33
    }
34
35
    return $xhtml_renderer->internallink($id,$name,$search,true,'navigation');
36
}
37
38
/**
39
 * The loginform
40
 *
41
 * @author   Andreas Gohr <[email protected]>
42
 *
43
 * @param bool $svg Whether to show svg icons in the register and resendpwd links or not
44
 * @deprecated 2020-07-18
45
 */
46
function html_login($svg = false) {
47
    (new dokuwiki\Ui\Login($svg))->show();
48
}
49
50
51
/**
52
 * Denied page content
53
 *
54
 * @return string html
55
 */
56
function html_denied() {
57
    print p_locale_xhtml('denied');
58
59
    if(empty($_SERVER['REMOTE_USER']) && actionOK('login')){
60
        html_login();
0 ignored issues
show
Deprecated Code introduced by
The function html_login() has been deprecated with message: 2020-07-18

This function has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed from the class and what other function to use instead.

Loading history...
61
    }
62
}
63
64
/**
65
 * inserts section edit buttons if wanted or removes the markers
66
 *
67
 * @author Andreas Gohr <[email protected]>
68
 *
69
 * @param string $text
70
 * @param bool   $show show section edit buttons?
71
 * @return string
72
 */
73
function html_secedit($text,$show=true){
74
    global $INFO;
75
76
    if((isset($INFO) && !$INFO['writable']) || !$show || (isset($INFO) && $INFO['rev'])){
77
        return preg_replace(SEC_EDIT_PATTERN,'',$text);
78
    }
79
80
    return preg_replace_callback(SEC_EDIT_PATTERN,
81
                'html_secedit_button', $text);
82
}
83
84
/**
85
 * prepares section edit button data for event triggering
86
 * used as a callback in html_secedit
87
 *
88
 * @author Andreas Gohr <[email protected]>
89
 *
90
 * @param array $matches matches with regexp
91
 * @return string
92
 * @triggers HTML_SECEDIT_BUTTON
93
 */
94
function html_secedit_button($matches){
95
    $json = htmlspecialchars_decode($matches[1], ENT_QUOTES);
96
    $data = json_decode($json, true);
97
    if ($data == NULL) {
98
        return;
99
    }
100
    $data ['target'] = strtolower($data['target']);
101
    $data ['hid'] = strtolower($data['hid']);
102
103
    return Event::createAndTrigger('HTML_SECEDIT_BUTTON', $data,
104
                         'html_secedit_get_button');
105
}
106
107
/**
108
 * prints a section editing button
109
 * used as default action form HTML_SECEDIT_BUTTON
110
 *
111
 * @author Adrian Lang <[email protected]>
112
 *
113
 * @param array $data name, section id and target
114
 * @return string html
115
 */
116
function html_secedit_get_button($data) {
117
    global $ID;
118
    global $INFO;
119
120
    if (!isset($data['name']) || $data['name'] === '') return '';
121
122
    $name = $data['name'];
123
    unset($data['name']);
124
125
    $secid = $data['secid'];
126
    unset($data['secid']);
127
128
    return "<div class='secedit editbutton_" . $data['target'] .
129
                       " editbutton_" . $secid . "'>" .
130
           html_btn('secedit', $ID, '',
131
                    array_merge(array('do'  => 'edit',
132
                                      'rev' => $INFO['lastmod'],
133
                                      'summary' => '['.$name.'] '), $data),
134
                    'post', $name) . '</div>';
135
}
136
137
/**
138
 * Just the back to top button (in its own form)
139
 *
140
 * @author Andreas Gohr <[email protected]>
141
 *
142
 * @return string html
143
 */
144
function html_topbtn(){
145
    global $lang;
146
147
    $ret = '<a class="nolink" href="#dokuwiki__top">' .
148
        '<button class="button" onclick="window.scrollTo(0, 0)" title="' . $lang['btn_top'] . '">' .
149
        $lang['btn_top'] .
150
        '</button></a>';
151
152
    return $ret;
153
}
154
155
/**
156
 * Displays a button (using its own form)
157
 * If tooltip exists, the access key tooltip is replaced.
158
 *
159
 * @author Andreas Gohr <[email protected]>
160
 *
161
 * @param string         $name
162
 * @param string         $id
163
 * @param string         $akey   access key
164
 * @param string[] $params key-value pairs added as hidden inputs
165
 * @param string         $method
166
 * @param string         $tooltip
167
 * @param bool|string    $label  label text, false: lookup btn_$name in localization
168
 * @param string         $svg (optional) svg code, inserted into the button
169
 * @return string
170
 */
171
function html_btn($name, $id, $akey, $params, $method='get', $tooltip='', $label=false, $svg=null){
172
    global $conf;
173
    global $lang;
174
175
    if (!$label)
176
        $label = $lang['btn_'.$name];
177
178
    $ret = '';
179
180
    //filter id (without urlencoding)
181
    $id = idfilter($id,false);
182
183
    //make nice URLs even for buttons
184
    if($conf['userewrite'] == 2){
185
        $script = DOKU_BASE.DOKU_SCRIPT.'/'.$id;
186
    }elseif($conf['userewrite']){
187
        $script = DOKU_BASE.$id;
188
    }else{
189
        $script = DOKU_BASE.DOKU_SCRIPT;
190
        $params['id'] = $id;
191
    }
192
193
    $ret .= '<form class="button btn_'.$name.'" method="'.$method.'" action="'.$script.'"><div class="no">';
194
195
    if(is_array($params)){
196
        foreach($params as $key => $val) {
197
            $ret .= '<input type="hidden" name="'.$key.'" ';
198
            $ret .= 'value="'.hsc($val).'" />';
199
        }
200
    }
201
202
    if ($tooltip!='') {
203
        $tip = hsc($tooltip);
204
    }else{
205
        $tip = hsc($label);
206
    }
207
208
    $ret .= '<button type="submit" ';
209
    if($akey){
210
        $tip .= ' ['.strtoupper($akey).']';
211
        $ret .= 'accesskey="'.$akey.'" ';
212
    }
213
    $ret .= 'title="'.$tip.'">';
214
    if ($svg) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $svg of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
215
        $ret .= '<span>' . hsc($label) . '</span>';
216
        $ret .= inlineSVG($svg);
217
    } else {
218
        $ret .= hsc($label);
219
    }
220
    $ret .= '</button>';
221
    $ret .= '</div></form>';
222
223
    return $ret;
224
}
225
/**
226
 * show a revision warning
227
 *
228
 * @author Szymon Olewniczak <[email protected]>
229
 */
230
function html_showrev() {
231
    print p_locale_xhtml('showrev');
232
}
233
234
/**
235
 * Show a wiki page
236
 *
237
 * @author Andreas Gohr <[email protected]>
238
 *
239
 * @param null|string $txt wiki text or null for showing $ID
240
 * @deprecated 2020-07-18
241
 */
242
function html_show($txt=null) {
243
    (new dokuwiki\Ui\PageView($txt))->show();
244
}
245
246
/**
247
 * ask the user about how to handle an exisiting draft
248
 *
249
 * @author Andreas Gohr <[email protected]>
250
 * @deprecated 2020-07-18
251
 */
252
function html_draft() {
253
    (new dokuwiki\Ui\Draft)->show();
254
}
255
256
/**
257
 * Highlights searchqueries in HTML code
258
 *
259
 * @author Andreas Gohr <[email protected]>
260
 * @author Harry Fuecks <[email protected]>
261
 *
262
 * @param string $html
263
 * @param array|string $phrases
264
 * @return string html
265
 */
266
function html_hilight($html, $phrases) {
267
    $phrases = (array) $phrases;
268
    $phrases = array_map('preg_quote_cb', $phrases);
269
    $phrases = array_map('ft_snippet_re_preprocess', $phrases);
270
    $phrases = array_filter($phrases);
271
    $regex = join('|',$phrases);
272
273
    if ($regex === '') return $html;
274
    if (!\dokuwiki\Utf8\Clean::isUtf8($regex)) return $html;
275
276
    $html = @preg_replace_callback("/((<[^>]*)|$regex)/ui", function ($match) {
277
        $hlight = unslash($match[0]);
278
        if (!isset($match[2])) {
279
            $hlight = '<span class="search_hit">'.$hlight.'</span>';
280
        }
281
        return $hlight;
282
    }, $html);
283
    return $html;
284
}
285
286
/**
287
 * Display error on locked pages
288
 *
289
 * @author Andreas Gohr <[email protected]>
290
 */
291
function html_locked(){
292
    global $ID;
293
    global $conf;
294
    global $lang;
295
    global $INFO;
296
297
    $locktime = filemtime(wikiLockFN($ID));
298
    $expire = dformat($locktime + $conf['locktime']);
299
    $min    = round(($conf['locktime'] - (time() - $locktime) )/60);
300
301
    print p_locale_xhtml('locked');
302
    print '<ul>';
303
    print '<li><div class="li"><strong>'.$lang['lockedby'].'</strong> '.editorinfo($INFO['locked']).'</div></li>';
304
    print '<li><div class="li"><strong>'.$lang['lockexpire'].'</strong> '.$expire.' ('.$min.' min)</div></li>';
305
    print '</ul>';
306
}
307
308
/**
309
 * list old revisions
310
 *
311
 * @author Andreas Gohr <[email protected]>
312
 * @author Ben Coburn <[email protected]>
313
 * @author Kate Arzamastseva <[email protected]>
314
 *
315
 * @param int $first skip the first n changelog lines
316
 * @param bool|string $media_id id of media, or false for current page
317
 * @deprecated 2020-07-18
318
 */
319
function html_revisions($first=0, $media_id = false) {
320
    (new dokuwiki\Ui\Revisions($first, $media_id))->show();
321
}
322
323
/**
324
 * display recent changes
325
 *
326
 * @author Andreas Gohr <[email protected]>
327
 * @author Matthias Grimm <[email protected]>
328
 * @author Ben Coburn <[email protected]>
329
 * @author Kate Arzamastseva <[email protected]>
330
 *
331
 * @param int $first
332
 * @param string $show_changes
333
 * @deprecated 2020-07-18
334
 */
335
function html_recent($first = 0, $show_changes = 'both') {
336
    (new dokuwiki\Ui\Recent($first, $show_changes))->show();
337
}
338
339
/**
340
 * Display page index
341
 *
342
 * @author Andreas Gohr <[email protected]>
343
 *
344
 * @param string $ns
345
 * @deprecated 2020-07-18
346
 */
347
function html_index($ns) {
348
    (new dokuwiki\Ui\Index($ns))->show();
349
}
350
351
/**
352
 * Index item formatter
353
 *
354
 * User function for html_buildlist()
355
 *
356
 * @author Andreas Gohr <[email protected]>
357
 *
358
 * @param array $item
359
 * @return string
360
 */
361
function html_list_index($item) { // FIXME: also called from inc/Ajax.php
362
    global $ID, $conf;
363
364
    // prevent searchbots needlessly following links
365
    $nofollow = ($ID != $conf['start'] || $conf['sitemap']) ? 'rel="nofollow"' : '';
366
367
    $ret = '';
368
    $base = ':'.$item['id'];
369
    $base = substr($base,strrpos($base,':')+1);
370
    if($item['type']=='d'){
371
        // FS#2766, no need for search bots to follow namespace links in the index
372
        $link = wl($ID, 'idx=' . rawurlencode($item['id']));
373
        $ret .= '<a href="' . $link . '" title="' . $item['id'] . '" class="idx_dir" ' . $nofollow . '><strong>';
374
        $ret .= $base;
375
        $ret .= '</strong></a>';
376
    }else{
377
        // default is noNSorNS($id), but we want noNS($id) when useheading is off FS#2605
378
        $ret .= html_wikilink(':'.$item['id'], useHeading('navigation') ? null : noNS($item['id']));
379
    }
380
    return $ret;
381
}
382
383
/**
384
 * Index List item
385
 *
386
 * This user function is used in html_buildlist to build the
387
 * <li> tags for namespaces when displaying the page index
388
 * it gives different classes to opened or closed "folders"
389
 *
390
 * @author Andreas Gohr <[email protected]>
391
 *
392
 * @param array $item
393
 * @return string html
394
 */
395
function html_li_index($item) { // FIXME: also called from inc/Ajax.php
396
    global $INFO;
397
    global $ACT;
398
399
    $class = '';
400
    $id = '';
401
402
    if($item['type'] == "f"){
403
        // scroll to the current item
404
        if(isset($INFO) && $item['id'] == $INFO['id'] && $ACT == 'index') {
405
            $id = ' id="scroll__here"';
406
            $class = ' bounce';
407
        }
408
        return '<li class="level'.$item['level'].$class.'" '.$id.'>';
409
    }elseif($item['open']){
410
        return '<li class="open">';
411
    }else{
412
        return '<li class="closed">';
413
    }
414
}
415
416
/**
417
 * Build an unordered list
418
 *
419
 * Build an unordered list from the given $data array
420
 * Each item in the array has to have a 'level' property
421
 * the item itself gets printed by the given $func user
422
 * function. The second and optional function is used to
423
 * print the <li> tag. Both user function need to accept
424
 * a single item.
425
 *
426
 * Both user functions can be given as array to point to
427
 * a member of an object.
428
 *
429
 * @author Andreas Gohr <[email protected]>
430
 *
431
 * @param array    $data  array with item arrays
432
 * @param string   $class class of ul wrapper
433
 * @param callable $func  callback to print an list item
434
 * @param callable $lifunc (optional) callback to the opening li tag
435
 * @param bool     $forcewrapper (optional) Trigger building a wrapper ul if the first level is
436
 *                               0 (we have a root object) or 1 (just the root content)
437
 * @return string html of an unordered list
438
 */
439
function html_buildlist($data, $class, $func, $lifunc = null, $forcewrapper = false) {
440
    if (count($data) === 0) {
441
        return '';
442
    }
443
444
    $firstElement = reset($data);
445
    $start_level = $firstElement['level'];
446
    $level = $start_level;
447
    $ret   = '';
448
    $open  = 0;
449
450
    // set callback function to build the <li> tag, formerly defined as html_li_default()
451
    if (!is_callable($lifunc)) {
452
       $lifunc = function($item) { return '<li class="level'.$item['level'].'">';};
453
    }
454
455
    foreach ($data as $item){
456
457
        if( $item['level'] > $level ){
458
            //open new list
459
            for($i=0; $i<($item['level'] - $level); $i++){
460
                if ($i) $ret .= "<li class=\"clear\">";
461
                $ret .= "\n<ul class=\"$class\">\n";
462
                $open++;
463
            }
464
            $level = $item['level'];
465
466
        }elseif( $item['level'] < $level ){
467
            //close last item
468
            $ret .= "</li>\n";
469
            while( $level > $item['level'] && $open > 0 ){
470
                //close higher lists
471
                $ret .= "</ul>\n</li>\n";
472
                $level--;
473
                $open--;
474
            }
475
        } elseif ($ret !== '') {
476
            //close previous item
477
            $ret .= "</li>\n";
478
        }
479
480
        //print item
481
        $ret .= call_user_func($lifunc,$item);
482
        $ret .= '<div class="li">';
483
484
        $ret .= call_user_func($func,$item);
485
        $ret .= '</div>';
486
    }
487
488
    //close remaining items and lists
489
    $ret .= "</li>\n";
490
    while($open-- > 0) {
491
        $ret .= "</ul></li>\n";
492
    }
493
494
    if ($forcewrapper || $start_level < 2) {
495
        // Trigger building a wrapper ul if the first level is
496
        // 0 (we have a root object) or 1 (just the root content)
497
        $ret = "\n<ul class=\"$class\">\n".$ret."</ul>\n";
498
    }
499
500
    return $ret;
501
}
502
503
/**
504
 * display backlinks
505
 *
506
 * @author Andreas Gohr <[email protected]>
507
 * @author Michael Klier <[email protected]>
508
 * @deprecated 2020-07-18
509
 */
510
function html_backlinks() {
511
    (new dokuwiki\Ui\Backlinks)->show();
512
}
513
514
/**
515
 * Show diff
516
 * between current page version and provided $text
517
 * or between the revisions provided via GET or POST
518
 *
519
 * @author Andreas Gohr <[email protected]>
520
 * @param  string $text  when non-empty: compare with this text with most current version
521
 * @param  bool   $intro display the intro text
522
 * @param  string $type  type of the diff (inline or sidebyside)
523
 * @deprecated 2020-07-18
524
 */
525
function html_diff($text = '', $intro = true, $type = null) {
526
    (new dokuwiki\Ui\Diff($text, $intro, $type))->show();
527
}
528
529
/**
530
 * show warning on conflict detection
531
 *
532
 * @author Andreas Gohr <[email protected]>
533
 *
534
 * @param string $text
535
 * @param string $summary
536
 * @deprecated 2020-07-18
537
 */
538
function html_conflict($text, $summary) {
539
    (new dokuwiki\Ui\Conflict($text, $summary))->show();
540
}
541
542
/**
543
 * Prints the global message array
544
 *
545
 * @author Andreas Gohr <[email protected]>
546
 */
547
function html_msgarea(){
548
    global $MSG, $MSG_shown;
549
    /** @var array $MSG */
550
    // store if the global $MSG has already been shown and thus HTML output has been started
551
    $MSG_shown = true;
552
553
    if(!isset($MSG)) return;
554
555
    $shown = array();
556
    foreach($MSG as $msg){
557
        $hash = md5($msg['msg']);
558
        if(isset($shown[$hash])) continue; // skip double messages
559
        if(info_msg_allowed($msg)){
560
            print '<div class="'.$msg['lvl'].'">';
561
            print $msg['msg'];
562
            print '</div>';
563
        }
564
        $shown[$hash] = 1;
565
    }
566
567
    unset($GLOBALS['MSG']);
568
}
569
570
/**
571
 * Prints the registration form
572
 *
573
 * @author Andreas Gohr <[email protected]>
574
 * @deprecated 2020-07-18
575
 */
576
function html_register() {
577
    (new dokuwiki\Ui\UserRegister)->show();
578
}
579
580
/**
581
 * Print the update profile form
582
 *
583
 * @author Christopher Smith <[email protected]>
584
 * @author Andreas Gohr <[email protected]>
585
 * @deprecated 2020-07-18
586
 */
587
function html_updateprofile() {
588
    (new dokuwiki\Ui\UserProfile)->show();
589
}
590
591
/**
592
 * Preprocess edit form data
593
 *
594
 * @author   Andreas Gohr <[email protected]>
595
 *
596
 * @triggers HTML_EDITFORM_OUTPUT
597
 * @deprecated 2020-07-18
598
 */
599
function html_edit() {
600
    (new dokuwiki\Ui\Editor)->show();
601
}
602
603
/**
604
 * prints some debug info
605
 *
606
 * @author Andreas Gohr <[email protected]>
607
 */
608
function html_debug(){
609
    global $conf;
610
    global $lang;
611
    /** @var AuthPlugin $auth */
612
    global $auth;
613
    global $INFO;
614
615
    //remove sensitive data
616
    $cnf = $conf;
617
    debug_guard($cnf);
618
    $nfo = $INFO;
619
    debug_guard($nfo);
620
    $ses = $_SESSION;
621
    debug_guard($ses);
622
623
    print '<html><body>';
624
625
    print '<p>When reporting bugs please send all the following ';
626
    print 'output as a mail to [email protected] ';
627
    print 'The best way to do this is to save this page in your browser</p>';
628
629
    print '<b>$INFO:</b><pre>';
630
    print_r($nfo);
631
    print '</pre>';
632
633
    print '<b>$_SERVER:</b><pre>';
634
    print_r($_SERVER);
635
    print '</pre>';
636
637
    print '<b>$conf:</b><pre>';
638
    print_r($cnf);
639
    print '</pre>';
640
641
    print '<b>DOKU_BASE:</b><pre>';
642
    print DOKU_BASE;
643
    print '</pre>';
644
645
    print '<b>abs DOKU_BASE:</b><pre>';
646
    print DOKU_URL;
647
    print '</pre>';
648
649
    print '<b>rel DOKU_BASE:</b><pre>';
650
    print dirname($_SERVER['PHP_SELF']).'/';
651
    print '</pre>';
652
653
    print '<b>PHP Version:</b><pre>';
654
    print phpversion();
655
    print '</pre>';
656
657
    print '<b>locale:</b><pre>';
658
    print setlocale(LC_ALL,0);
659
    print '</pre>';
660
661
    print '<b>encoding:</b><pre>';
662
    print $lang['encoding'];
663
    print '</pre>';
664
665
    if($auth){
666
        print '<b>Auth backend capabilities:</b><pre>';
667
        foreach ($auth->getCapabilities() as $cando){
668
            print '   '.str_pad($cando,16) . ' => ' . (int)$auth->canDo($cando) . NL;
669
        }
670
        print '</pre>';
671
    }
672
673
    print '<b>$_SESSION:</b><pre>';
674
    print_r($ses);
675
    print '</pre>';
676
677
    print '<b>Environment:</b><pre>';
678
    print_r($_ENV);
679
    print '</pre>';
680
681
    print '<b>PHP settings:</b><pre>';
682
    $inis = ini_get_all();
683
    print_r($inis);
684
    print '</pre>';
685
686
    if (function_exists('apache_get_version')) {
687
        $apache = array();
688
        $apache['version'] = apache_get_version();
689
690
        if (function_exists('apache_get_modules')) {
691
            $apache['modules'] = apache_get_modules();
692
        }
693
        print '<b>Apache</b><pre>';
694
        print_r($apache);
695
        print '</pre>';
696
    }
697
698
    print '</body></html>';
699
}
700
701
/**
702
 * Form to request a new password for an existing account
703
 *
704
 * @author Benoit Chesneau <[email protected]>
705
 * @author Andreas Gohr <[email protected]>
706
 * @deprecated 2020-07-18
707
 */
708
function html_resendpwd() {
709
    (new dokuwiki\Ui\UserResendPwd)->show();
710
}
711
712
/**
713
 * Return the TOC rendered to XHTML
714
 *
715
 * @author Andreas Gohr <[email protected]>
716
 *
717
 * @param array $toc
718
 * @return string html
719
 */
720
function html_TOC($toc) {
721
    if (!count($toc)) return '';
722
    global $lang;
723
    $out  = '<!-- TOC START -->'.DOKU_LF;
724
    $out .= '<div id="dw__toc" class="dw__toc">'.DOKU_LF;
725
    $out .= '<h3 class="toggle">';
726
    $out .= $lang['toc'];
727
    $out .= '</h3>'.DOKU_LF;
728
    $out .= '<div>'.DOKU_LF;
729
    $out .= html_buildlist($toc, 'toc', 'html_list_toc', null, true);
730
    $out .= '</div>'.DOKU_LF.'</div>'.DOKU_LF;
731
    $out .= '<!-- TOC END -->'.DOKU_LF;
732
    return $out;
733
}
734
735
/**
736
 * Callback for html_buildlist
737
 *
738
 * @param array $item
739
 * @return string html
740
 */
741
function html_list_toc($item) {
742
    if (isset($item['hid'])){
743
        $link = '#'.$item['hid'];
744
    } else {
745
        $link = $item['link'];
746
    }
747
748
    return '<a href="'.$link.'">'.hsc($item['title']).'</a>';
749
}
750
751
/**
752
 * Helper function to build TOC items
753
 *
754
 * Returns an array ready to be added to a TOC array
755
 *
756
 * @param string $link  - where to link (if $hash set to '#' it's a local anchor)
757
 * @param string $text  - what to display in the TOC
758
 * @param int    $level - nesting level
759
 * @param string $hash  - is prepended to the given $link, set blank if you want full links
760
 * @return array the toc item
761
 */
762
function html_mktocitem($link, $text, $level, $hash='#') {
763
    return  array(
764
            'link'  => $hash.$link,
765
            'title' => $text,
766
            'type'  => 'ul',
767
            'level' => $level
768
    );
769
}
770
771
/**
772
 * Output a Doku_Form object.
773
 * Triggers an event with the form name: HTML_{$name}FORM_OUTPUT
774
 *
775
 * @author Tom N Harris <[email protected]>
776
 *
777
 * @param string     $name The name of the form
778
 * @param Doku_Form  $form The form
779
 */
780
function html_form($name, $form) {
781
    // Safety check in case the caller forgets.
782
    $form->endFieldset();
783
    Event::createAndTrigger('HTML_'.strtoupper($name).'FORM_OUTPUT', $form, 'html_form_output', false);
784
}
785
786
/**
787
 * Form print function.
788
 * Just calls printForm() on the form object.
789
 *
790
 * @param Doku_Form $form The form
791
 */
792
function html_form_output($form) {
793
    $form->printForm();
794
}
795
796
/**
797
 * Embed a flash object in HTML
798
 *
799
 * This will create the needed HTML to embed a flash movie in a cross browser
800
 * compatble way using valid XHTML
801
 *
802
 * The parameters $params, $flashvars and $atts need to be associative arrays.
803
 * No escaping needs to be done for them. The alternative content *has* to be
804
 * escaped because it is used as is. If no alternative content is given
805
 * $lang['noflash'] is used.
806
 *
807
 * @author Andreas Gohr <[email protected]>
808
 * @link   http://latrine.dgx.cz/how-to-correctly-insert-a-flash-into-xhtml
809
 *
810
 * @param string $swf      - the SWF movie to embed
811
 * @param int $width       - width of the flash movie in pixels
812
 * @param int $height      - height of the flash movie in pixels
813
 * @param array $params    - additional parameters (<param>)
814
 * @param array $flashvars - parameters to be passed in the flashvar parameter
815
 * @param array $atts      - additional attributes for the <object> tag
816
 * @param string $alt      - alternative content (is NOT automatically escaped!)
817
 * @return string         - the XHTML markup
818
 */
819
function html_flashobject($swf,$width,$height,$params=null,$flashvars=null,$atts=null,$alt=''){
820
    global $lang;
821
822
    $out = '';
823
824
    // prepare the object attributes
825
    if(is_null($atts)) $atts = array();
826
    $atts['width']  = (int) $width;
827
    $atts['height'] = (int) $height;
828
    if(!$atts['width'])  $atts['width']  = 425;
829
    if(!$atts['height']) $atts['height'] = 350;
830
831
    // add object attributes for standard compliant browsers
832
    $std = $atts;
833
    $std['type'] = 'application/x-shockwave-flash';
834
    $std['data'] = $swf;
835
836
    // add object attributes for IE
837
    $ie  = $atts;
838
    $ie['classid'] = 'clsid:D27CDB6E-AE6D-11cf-96B8-444553540000';
839
840
    // open object (with conditional comments)
841
    $out .= '<!--[if !IE]> -->'.NL;
842
    $out .= '<object '.buildAttributes($std).'>'.NL;
843
    $out .= '<!-- <![endif]-->'.NL;
844
    $out .= '<!--[if IE]>'.NL;
845
    $out .= '<object '.buildAttributes($ie).'>'.NL;
846
    $out .= '    <param name="movie" value="'.hsc($swf).'" />'.NL;
847
    $out .= '<!--><!-- -->'.NL;
848
849
    // print params
850
    if(is_array($params)) foreach($params as $key => $val){
851
        $out .= '  <param name="'.hsc($key).'" value="'.hsc($val).'" />'.NL;
852
    }
853
854
    // add flashvars
855
    if(is_array($flashvars)){
856
        $out .= '  <param name="FlashVars" value="'.buildURLparams($flashvars).'" />'.NL;
857
    }
858
859
    // alternative content
860
    if($alt){
861
        $out .= $alt.NL;
862
    }else{
863
        $out .= $lang['noflash'].NL;
864
    }
865
866
    // finish
867
    $out .= '</object>'.NL;
868
    $out .= '<!-- <![endif]-->'.NL;
869
870
    return $out;
871
}
872
873
/**
874
 * Prints HTML code for the given tab structure
875
 *
876
 * @param array  $tabs        tab structure
877
 * @param string $current_tab the current tab id
878
 */
879
function html_tabs($tabs, $current_tab = null) {
880
    echo '<ul class="tabs">'.NL;
881
882
    foreach($tabs as $id => $tab) {
883
        html_tab($tab['href'], $tab['caption'], $id === $current_tab);
884
    }
885
886
    echo '</ul>'.NL;
887
}
888
889
/**
890
 * Prints a single tab
891
 *
892
 * @author Kate Arzamastseva <[email protected]>
893
 * @author Adrian Lang <[email protected]>
894
 *
895
 * @param string $href - tab href
896
 * @param string $caption - tab caption
897
 * @param boolean $selected - is tab selected
898
 */
899
900
function html_tab($href, $caption, $selected=false) {
901
    $tab = '<li>';
902
    if ($selected) {
903
        $tab .= '<strong>';
904
    } else {
905
        $tab .= '<a href="' . hsc($href) . '">';
906
    }
907
    $tab .= hsc($caption)
908
         .  '</' . ($selected ? 'strong' : 'a') . '>'
909
         .  '</li>'.NL;
910
    echo $tab;
911
}
912
913
/**
914
 * Display size change
915
 *
916
 * @param int $sizechange - size of change in Bytes
917
 * @param Doku_Form $form - (optional) form to add elements to
918
 * @return void|string
919
 */
920
function html_sizechange($sizechange, $form = null) {
921
    if (isset($sizechange)) {
922
        $class = 'sizechange';
923
        $value = filesize_h(abs($sizechange));
924
        if ($sizechange > 0) {
925
            $class .= ' positive';
926
            $value = '+' . $value;
927
        } elseif ($sizechange < 0) {
928
            $class .= ' negative';
929
            $value = '-' . $value;
930
        } else {
931
            $value = '±' . $value;
932
        }
933
        if (!isset($form)) {
934
            return '<span class="'.$class.'">'.$value.'</span>';
935
        } else { // Doku_Form
936
            $form->addElement(form_makeOpenTag('span', array('class' => $class)));
937
            $form->addElement($value);
938
            $form->addElement(form_makeCloseTag('span'));
939
        }
940
    }
941
}
942