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

html.php ➔ html_softbreak_callback()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 1
dl 0
loc 18
rs 9.6666
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
 * Default List item
418
 *
419
 * @author Andreas Gohr <[email protected]>
420
 *
421
 * @param array $item
422
 * @return string html
423
 */
424
function html_li_default($item) { // FIXME: should be closure in html_buildlist()?
425
    return '<li class="level'.$item['level'].'">';
426
}
427
428
/**
429
 * Build an unordered list
430
 *
431
 * Build an unordered list from the given $data array
432
 * Each item in the array has to have a 'level' property
433
 * the item itself gets printed by the given $func user
434
 * function. The second and optional function is used to
435
 * print the <li> tag. Both user function need to accept
436
 * a single item.
437
 *
438
 * Both user functions can be given as array to point to
439
 * a member of an object.
440
 *
441
 * @author Andreas Gohr <[email protected]>
442
 *
443
 * @param array    $data  array with item arrays
444
 * @param string   $class class of ul wrapper
445
 * @param callable $func  callback to print an list item
446
 * @param callable $lifunc callback to the opening li tag
447
 * @param bool     $forcewrapper Trigger building a wrapper ul if the first level is
448
 *                               0 (we have a root object) or 1 (just the root content)
449
 * @return string html of an unordered list
450
 */
451
function html_buildlist($data,$class,$func,$lifunc='html_li_default',$forcewrapper=false){
452
    if (count($data) === 0) {
453
        return '';
454
    }
455
456
    $firstElement = reset($data);
457
    $start_level = $firstElement['level'];
458
    $level = $start_level;
459
    $ret   = '';
460
    $open  = 0;
461
462
    foreach ($data as $item){
463
464
        if( $item['level'] > $level ){
465
            //open new list
466
            for($i=0; $i<($item['level'] - $level); $i++){
467
                if ($i) $ret .= "<li class=\"clear\">";
468
                $ret .= "\n<ul class=\"$class\">\n";
469
                $open++;
470
            }
471
            $level = $item['level'];
472
473
        }elseif( $item['level'] < $level ){
474
            //close last item
475
            $ret .= "</li>\n";
476
            while( $level > $item['level'] && $open > 0 ){
477
                //close higher lists
478
                $ret .= "</ul>\n</li>\n";
479
                $level--;
480
                $open--;
481
            }
482
        } elseif ($ret !== '') {
483
            //close previous item
484
            $ret .= "</li>\n";
485
        }
486
487
        //print item
488
        $ret .= call_user_func($lifunc,$item);
489
        $ret .= '<div class="li">';
490
491
        $ret .= call_user_func($func,$item);
492
        $ret .= '</div>';
493
    }
494
495
    //close remaining items and lists
496
    $ret .= "</li>\n";
497
    while($open-- > 0) {
498
        $ret .= "</ul></li>\n";
499
    }
500
501
    if ($forcewrapper || $start_level < 2) {
502
        // Trigger building a wrapper ul if the first level is
503
        // 0 (we have a root object) or 1 (just the root content)
504
        $ret = "\n<ul class=\"$class\">\n".$ret."</ul>\n";
505
    }
506
507
    return $ret;
508
}
509
510
/**
511
 * display backlinks
512
 *
513
 * @author Andreas Gohr <[email protected]>
514
 * @author Michael Klier <[email protected]>
515
 * @deprecated 2020-07-18
516
 */
517
function html_backlinks() {
518
    (new dokuwiki\Ui\Backlinks)->show();
519
}
520
521
/**
522
 * Show diff
523
 * between current page version and provided $text
524
 * or between the revisions provided via GET or POST
525
 *
526
 * @author Andreas Gohr <[email protected]>
527
 * @param  string $text  when non-empty: compare with this text with most current version
528
 * @param  bool   $intro display the intro text
529
 * @param  string $type  type of the diff (inline or sidebyside)
530
 * @deprecated 2020-07-18
531
 */
532
function html_diff($text = '', $intro = true, $type = null) {
533
    (new dokuwiki\Ui\Diff($text, $intro, $type))->show();
534
}
535
536
/**
537
 * show warning on conflict detection
538
 *
539
 * @author Andreas Gohr <[email protected]>
540
 *
541
 * @param string $text
542
 * @param string $summary
543
 * @deprecated 2020-07-18
544
 */
545
function html_conflict($text, $summary) {
546
    (new dokuwiki\Ui\Conflict($text, $summary))->show();
547
}
548
549
/**
550
 * Prints the global message array
551
 *
552
 * @author Andreas Gohr <[email protected]>
553
 */
554
function html_msgarea(){
555
    global $MSG, $MSG_shown;
556
    /** @var array $MSG */
557
    // store if the global $MSG has already been shown and thus HTML output has been started
558
    $MSG_shown = true;
559
560
    if(!isset($MSG)) return;
561
562
    $shown = array();
563
    foreach($MSG as $msg){
564
        $hash = md5($msg['msg']);
565
        if(isset($shown[$hash])) continue; // skip double messages
566
        if(info_msg_allowed($msg)){
567
            print '<div class="'.$msg['lvl'].'">';
568
            print $msg['msg'];
569
            print '</div>';
570
        }
571
        $shown[$hash] = 1;
572
    }
573
574
    unset($GLOBALS['MSG']);
575
}
576
577
/**
578
 * Prints the registration form
579
 *
580
 * @author Andreas Gohr <[email protected]>
581
 * @deprecated 2020-07-18
582
 */
583
function html_register() {
584
    (new dokuwiki\Ui\UserRegister)->show();
585
}
586
587
/**
588
 * Print the update profile form
589
 *
590
 * @author Christopher Smith <[email protected]>
591
 * @author Andreas Gohr <[email protected]>
592
 * @deprecated 2020-07-18
593
 */
594
function html_updateprofile() {
595
    (new dokuwiki\Ui\UserProfile)->show();
596
}
597
598
/**
599
 * Preprocess edit form data
600
 *
601
 * @author   Andreas Gohr <[email protected]>
602
 *
603
 * @triggers HTML_EDITFORM_OUTPUT
604
 * @deprecated 2020-07-18
605
 */
606
function html_edit() {
607
    (new dokuwiki\Ui\Editor)->show();
608
}
609
610
/**
611
 * prints some debug info
612
 *
613
 * @author Andreas Gohr <[email protected]>
614
 */
615
function html_debug(){
616
    global $conf;
617
    global $lang;
618
    /** @var AuthPlugin $auth */
619
    global $auth;
620
    global $INFO;
621
622
    //remove sensitive data
623
    $cnf = $conf;
624
    debug_guard($cnf);
625
    $nfo = $INFO;
626
    debug_guard($nfo);
627
    $ses = $_SESSION;
628
    debug_guard($ses);
629
630
    print '<html><body>';
631
632
    print '<p>When reporting bugs please send all the following ';
633
    print 'output as a mail to [email protected] ';
634
    print 'The best way to do this is to save this page in your browser</p>';
635
636
    print '<b>$INFO:</b><pre>';
637
    print_r($nfo);
638
    print '</pre>';
639
640
    print '<b>$_SERVER:</b><pre>';
641
    print_r($_SERVER);
642
    print '</pre>';
643
644
    print '<b>$conf:</b><pre>';
645
    print_r($cnf);
646
    print '</pre>';
647
648
    print '<b>DOKU_BASE:</b><pre>';
649
    print DOKU_BASE;
650
    print '</pre>';
651
652
    print '<b>abs DOKU_BASE:</b><pre>';
653
    print DOKU_URL;
654
    print '</pre>';
655
656
    print '<b>rel DOKU_BASE:</b><pre>';
657
    print dirname($_SERVER['PHP_SELF']).'/';
658
    print '</pre>';
659
660
    print '<b>PHP Version:</b><pre>';
661
    print phpversion();
662
    print '</pre>';
663
664
    print '<b>locale:</b><pre>';
665
    print setlocale(LC_ALL,0);
666
    print '</pre>';
667
668
    print '<b>encoding:</b><pre>';
669
    print $lang['encoding'];
670
    print '</pre>';
671
672
    if($auth){
673
        print '<b>Auth backend capabilities:</b><pre>';
674
        foreach ($auth->getCapabilities() as $cando){
675
            print '   '.str_pad($cando,16) . ' => ' . (int)$auth->canDo($cando) . NL;
676
        }
677
        print '</pre>';
678
    }
679
680
    print '<b>$_SESSION:</b><pre>';
681
    print_r($ses);
682
    print '</pre>';
683
684
    print '<b>Environment:</b><pre>';
685
    print_r($_ENV);
686
    print '</pre>';
687
688
    print '<b>PHP settings:</b><pre>';
689
    $inis = ini_get_all();
690
    print_r($inis);
691
    print '</pre>';
692
693
    if (function_exists('apache_get_version')) {
694
        $apache = array();
695
        $apache['version'] = apache_get_version();
696
697
        if (function_exists('apache_get_modules')) {
698
            $apache['modules'] = apache_get_modules();
699
        }
700
        print '<b>Apache</b><pre>';
701
        print_r($apache);
702
        print '</pre>';
703
    }
704
705
    print '</body></html>';
706
}
707
708
/**
709
 * Form to request a new password for an existing account
710
 *
711
 * @author Benoit Chesneau <[email protected]>
712
 * @author Andreas Gohr <[email protected]>
713
 * @deprecated 2020-07-18
714
 */
715
function html_resendpwd() {
716
    (new dokuwiki\Ui\UserResendPwd)->show();
717
}
718
719
/**
720
 * Return the TOC rendered to XHTML
721
 *
722
 * @author Andreas Gohr <[email protected]>
723
 *
724
 * @param array $toc
725
 * @return string html
726
 */
727
function html_TOC($toc){
728
    if(!count($toc)) return '';
729
    global $lang;
730
    $out  = '<!-- TOC START -->'.DOKU_LF;
731
    $out .= '<div id="dw__toc" class="dw__toc">'.DOKU_LF;
732
    $out .= '<h3 class="toggle">';
733
    $out .= $lang['toc'];
734
    $out .= '</h3>'.DOKU_LF;
735
    $out .= '<div>'.DOKU_LF;
736
    $out .= html_buildlist($toc,'toc','html_list_toc','html_li_default',true);
737
    $out .= '</div>'.DOKU_LF.'</div>'.DOKU_LF;
738
    $out .= '<!-- TOC END -->'.DOKU_LF;
739
    return $out;
740
}
741
742
/**
743
 * Callback for html_buildlist
744
 *
745
 * @param array $item
746
 * @return string html
747
 */
748
function html_list_toc($item){
749
    if(isset($item['hid'])){
750
        $link = '#'.$item['hid'];
751
    }else{
752
        $link = $item['link'];
753
    }
754
755
    return '<a href="'.$link.'">'.hsc($item['title']).'</a>';
756
}
757
758
/**
759
 * Helper function to build TOC items
760
 *
761
 * Returns an array ready to be added to a TOC array
762
 *
763
 * @param string $link  - where to link (if $hash set to '#' it's a local anchor)
764
 * @param string $text  - what to display in the TOC
765
 * @param int    $level - nesting level
766
 * @param string $hash  - is prepended to the given $link, set blank if you want full links
767
 * @return array the toc item
768
 */
769
function html_mktocitem($link, $text, $level, $hash='#'){
770
    return  array( 'link'  => $hash.$link,
771
            'title' => $text,
772
            'type'  => 'ul',
773
            'level' => $level);
774
}
775
776
/**
777
 * Output a Doku_Form object.
778
 * Triggers an event with the form name: HTML_{$name}FORM_OUTPUT
779
 *
780
 * @author Tom N Harris <[email protected]>
781
 *
782
 * @param string     $name The name of the form
783
 * @param Doku_Form  $form The form
784
 */
785
function html_form($name, $form) {
786
    // Safety check in case the caller forgets.
787
    $form->endFieldset();
788
    Event::createAndTrigger('HTML_'.strtoupper($name).'FORM_OUTPUT', $form, 'html_form_output', false);
789
}
790
791
/**
792
 * Form print function.
793
 * Just calls printForm() on the form object.
794
 *
795
 * @param Doku_Form $form The form
796
 */
797
function html_form_output($form) {
798
    $form->printForm();
799
}
800
801
/**
802
 * Embed a flash object in HTML
803
 *
804
 * This will create the needed HTML to embed a flash movie in a cross browser
805
 * compatble way using valid XHTML
806
 *
807
 * The parameters $params, $flashvars and $atts need to be associative arrays.
808
 * No escaping needs to be done for them. The alternative content *has* to be
809
 * escaped because it is used as is. If no alternative content is given
810
 * $lang['noflash'] is used.
811
 *
812
 * @author Andreas Gohr <[email protected]>
813
 * @link   http://latrine.dgx.cz/how-to-correctly-insert-a-flash-into-xhtml
814
 *
815
 * @param string $swf      - the SWF movie to embed
816
 * @param int $width       - width of the flash movie in pixels
817
 * @param int $height      - height of the flash movie in pixels
818
 * @param array $params    - additional parameters (<param>)
819
 * @param array $flashvars - parameters to be passed in the flashvar parameter
820
 * @param array $atts      - additional attributes for the <object> tag
821
 * @param string $alt      - alternative content (is NOT automatically escaped!)
822
 * @return string         - the XHTML markup
823
 */
824
function html_flashobject($swf,$width,$height,$params=null,$flashvars=null,$atts=null,$alt=''){
825
    global $lang;
826
827
    $out = '';
828
829
    // prepare the object attributes
830
    if(is_null($atts)) $atts = array();
831
    $atts['width']  = (int) $width;
832
    $atts['height'] = (int) $height;
833
    if(!$atts['width'])  $atts['width']  = 425;
834
    if(!$atts['height']) $atts['height'] = 350;
835
836
    // add object attributes for standard compliant browsers
837
    $std = $atts;
838
    $std['type'] = 'application/x-shockwave-flash';
839
    $std['data'] = $swf;
840
841
    // add object attributes for IE
842
    $ie  = $atts;
843
    $ie['classid'] = 'clsid:D27CDB6E-AE6D-11cf-96B8-444553540000';
844
845
    // open object (with conditional comments)
846
    $out .= '<!--[if !IE]> -->'.NL;
847
    $out .= '<object '.buildAttributes($std).'>'.NL;
848
    $out .= '<!-- <![endif]-->'.NL;
849
    $out .= '<!--[if IE]>'.NL;
850
    $out .= '<object '.buildAttributes($ie).'>'.NL;
851
    $out .= '    <param name="movie" value="'.hsc($swf).'" />'.NL;
852
    $out .= '<!--><!-- -->'.NL;
853
854
    // print params
855
    if(is_array($params)) foreach($params as $key => $val){
856
        $out .= '  <param name="'.hsc($key).'" value="'.hsc($val).'" />'.NL;
857
    }
858
859
    // add flashvars
860
    if(is_array($flashvars)){
861
        $out .= '  <param name="FlashVars" value="'.buildURLparams($flashvars).'" />'.NL;
862
    }
863
864
    // alternative content
865
    if($alt){
866
        $out .= $alt.NL;
867
    }else{
868
        $out .= $lang['noflash'].NL;
869
    }
870
871
    // finish
872
    $out .= '</object>'.NL;
873
    $out .= '<!-- <![endif]-->'.NL;
874
875
    return $out;
876
}
877
878
/**
879
 * Prints HTML code for the given tab structure
880
 *
881
 * @param array  $tabs        tab structure
882
 * @param string $current_tab the current tab id
883
 */
884
function html_tabs($tabs, $current_tab = null) {
885
    echo '<ul class="tabs">'.NL;
886
887
    foreach($tabs as $id => $tab) {
888
        html_tab($tab['href'], $tab['caption'], $id === $current_tab);
889
    }
890
891
    echo '</ul>'.NL;
892
}
893
894
/**
895
 * Prints a single tab
896
 *
897
 * @author Kate Arzamastseva <[email protected]>
898
 * @author Adrian Lang <[email protected]>
899
 *
900
 * @param string $href - tab href
901
 * @param string $caption - tab caption
902
 * @param boolean $selected - is tab selected
903
 */
904
905
function html_tab($href, $caption, $selected=false) {
906
    $tab = '<li>';
907
    if ($selected) {
908
        $tab .= '<strong>';
909
    } else {
910
        $tab .= '<a href="' . hsc($href) . '">';
911
    }
912
    $tab .= hsc($caption)
913
         .  '</' . ($selected ? 'strong' : 'a') . '>'
914
         .  '</li>'.NL;
915
    echo $tab;
916
}
917
918
/**
919
 * Display size change
920
 *
921
 * @param int $sizechange - size of change in Bytes
922
 * @param Doku_Form $form - (optional) form to add elements to
923
 * @return void|string
924
 */
925
function html_sizechange($sizechange, $form = null) {
926
    if (isset($sizechange)) {
927
        $class = 'sizechange';
928
        $value = filesize_h(abs($sizechange));
929
        if ($sizechange > 0) {
930
            $class .= ' positive';
931
            $value = '+' . $value;
932
        } elseif ($sizechange < 0) {
933
            $class .= ' negative';
934
            $value = '-' . $value;
935
        } else {
936
            $value = '±' . $value;
937
        }
938
        if (!isset($form)) {
939
            return '<span class="'.$class.'">'.$value.'</span>';
940
        } else { // Doku_Form
941
            $form->addElement(form_makeOpenTag('span', array('class' => $class)));
942
            $form->addElement($value);
943
            $form->addElement(form_makeCloseTag('span'));
944
        }
945
    }
946
}
947