1<?php
2
3require_once dirname(__FILE__).'/accesscheck.php';
4
5// interface functions
6
7class UIPanel
8{
9    private $header = '';
10    private $nav = '';
11    private $content = '';
12    private $id = '';
13
14    public function __construct($header, $content, $nav = '')
15    {
16        $this->header = $header;
17        $this->nav = $nav;
18        $this->content = $content;
19    }
20
21    public function setID($id)
22    {
23        $this->id = $id;
24    }
25
26    public function display()
27    {
28        $html = '<div class="panel"';
29        if (!empty($this->id)) {
30            $html .= ' id="'.$this->id.'"';
31        }
32        $html .= '>';
33        $html .= '<div class="header"><h2>'.$this->header.'</h2>';
34        $nav = '';
35        if ($this->nav) {
36            $html .= $this->nav;
37        }
38        $html .= '</div><!-- ENDOF .header -->';
39        $html .= '
40<div class="content">
41
42    ' .$this->content.'
43  </div><!-- ENDOF .content -->';
44        $html .= '
45<div class="footer">
46      ' .$this->nav.'
47  </div><!-- ENDOF .footer -->
48</div><!-- ENDOF .panel -->
49    ';
50
51        return $html;
52    }
53}
54
55class WebblerListing
56{
57    public $title;
58    public $elementHeading;
59    public $help;
60    public $elements = array();
61    public $columns = array();
62    public $sortby = array();
63    public $sort = 0;
64    public $sortcolumn = '';
65    public $buttons = array();
66    public $submitbuttons = array();
67    public $initialstate = 'block';
68    public $duplicatebuttons = array();
69    public $buttonduplicate = 0;
70    private $useShader = true;
71    private $usePanel = false;
72    private $panelNav = '';
73    private $insideNav = '';
74    private $suppressHeader = false;
75    private $suppressGreenline = false;
76    private $buttonsOutsideTable = false;
77
78    public function __construct($title, $help = '')
79    {
80        $this->title = strip_tags($title);
81        $this->help = strip_tags($help);
82        //# in phpList don't use the shader
83        if (!defined('IN_WEBBLER') && !defined('WEBBLER')) {
84            $this->noShader();
85            $this->usePanel();
86            $this->suppressGreenline();
87            $this->buttonsOutsideTable = true;
88        }
89    }
90
91    public function setElementHeading($heading)
92    {
93        $this->elementHeading = $heading;
94    }
95
96    public function noShader()
97    {
98        $this->useShader = false;
99    }
100
101    public function noHeader()
102    {
103        $this->suppressHeader = true;
104    }
105
106    public function suppressGreenline()
107    {
108        $this->suppressGreenline = true;
109    }
110
111    public function usePanel($nav = '')
112    {
113        $this->insideNav = $nav;
114        $this->usePanel = true;
115    }
116
117    public function addElement($name, $url = '', $colsize = '')
118    {
119        if (!isset($this->elements[$name])) {
120            $this->elements[$name] = array(
121                'name'    => $name,
122                'url'     => $url,
123                'colsize' => $colsize,
124                'columns' => array(),
125                'rows'    => array(),
126                'class'   => '',
127            );
128        }
129    }
130
131    public function setClass($name, $class)
132    {
133        $this->elements[$name]['class'] = $class;
134    }
135
136    public function deleteElement($name)
137    {
138        unset($this->elements[$name]);
139    }
140
141    public function addSort()
142    {
143        $this->sort = 1;
144    }
145
146    public function sortBy($colname, $direction = 'desc')
147    {
148        $this->sortcolumn = $colname;
149    }
150
151    public function addColumn($name, $column_name, $value, $url = '', $align = '')
152    {
153        if (!isset($name)) {
154            return;
155        }
156        $this->columns[$column_name] = $column_name;
157        $this->sortby[$column_name] = $column_name;
158        // @@@ should make this a callable function
159        $this->elements[$name]['columns']["$column_name"] = array(
160            'value' => $value,
161            'url'   => $url,
162            'align' => $align,
163        );
164    }
165
166    public function renameColumn($oldname, $newname)
167    {
168        $this->columns[$oldname] = $newname;
169    }
170
171    public function deleteColumn($colname)
172    {
173        unset($this->columns[$colname]);
174    }
175
176    public function removeGetParam($remove)
177    {
178        $res = '';
179        foreach ($_GET as $key => $val) {
180            if ($key != $remove) {
181                $res .= "$key=".urlencode($val).'&amp;';
182            }
183        }
184
185        return $res;
186    }
187
188    public function addRow($name, $row_name, $value, $url = '', $align = '', $class = '')
189    {
190        if (!isset($name)) {
191            return;
192        }
193        $this->elements[$name]['rows']["$row_name"] = array(
194            'name'  => $row_name,
195            'value' => $value,
196            'url'   => $url,
197            'align' => $align,
198            'class' => $class,
199        );
200    }
201
202    public function addInput($name, $value)
203    {
204        $this->addElement($name);
205        $this->addColumn($name, 'value',
206            sprintf('<input type="text" name="%s" value="%s" size="40" class="listinginput" />',
207                mb_strtolower($name), $value));
208    }
209
210    public function addButton($name, $url)
211    {
212        $this->buttons[$name] = $url;
213    }
214
215    public function addSubmitButton($name, $label)
216    {
217        $this->submitbuttons[$name] = $label;
218    }
219
220    public function duplicateButton($name, $rows)
221    {
222        $this->duplicatebuttons[$name] = array(
223            'button'   => $name,
224            'rows'     => $rows,
225            'rowcount' => 1,
226        );
227        $this->buttonduplicate = 1;
228    }
229
230    public function listingStart($class = '')
231    {
232        return '<table cellpadding="0" cellspacing="0" border="0" width="100%" class="listing '.$class.'">';
233    }
234
235    public function listingHeader()
236    {
237        $tophelp = '';
238        if (!count($this->columns)) {
239            $tophelp = $this->help;
240        }
241
242        $heading = isset($this->elementHeading) ? $this->elementHeading : $this->title;
243        $html = '<tr valign="top">';
244        $html .= sprintf('<th><a name="%s"></a><div class="listinghdname">%s%s</div></th>',
245            str_replace(' ', '_', htmlspecialchars(mb_strtolower($heading))), $tophelp, $heading);
246        $c = 1;
247        foreach ($this->columns as $column => $columnname) {
248            if ($c == count($this->columns)) {
249                $html .= sprintf('<th><div class="listinghdelement">%s%s</div></th>', $columnname, $this->help);
250            } else {
251                if ($this->sortby[$columnname] && $this->sort) {
252                    $display = sprintf('<a href="./?%s&amp;sortby=%s" title="%s">%s</a>',
253                        $this->removeGetParam('sortby'), urlencode($columnname),
254                        sprintf($GLOBALS['I18N']->get('sort by %s'), $columnname), $columnname);
255                } else {
256                    $display = $columnname;
257                }
258                $html .= sprintf('<th><div class="listinghdelement">%s</div></th>', $display);
259            }
260            ++$c;
261        }
262        //  $html .= sprintf('<td align="right"><span class="listinghdelementright">%s</span></td>',$lastelement);
263        $html .= '</tr>';
264
265        return $html;
266    }
267
268    public function listingElement($element)
269    {
270        if (!empty($element['colsize'])) {
271            $width = 'width='.$element['colsize'];
272        } else {
273            $width = '';
274        }
275        if (isset($element['class'])) {
276            $html = '<tr class="'.$element['class'].'">';
277        } else {
278            $html = '<tr>';
279        }
280
281        if (!empty($element['url'])) {
282            $html .= sprintf('<td %s class="listingname"><span class="listingname"><a href="%s" class="listingname" title="%s">%s</a></span></td>',
283                $width, $element['url'], htmlspecialchars(strip_tags($element['name'])), $element['name']);
284        } else {
285            $html .= sprintf('<td %s class="listingname"><span class="listingname">%s</span></td>', $width,
286                $element['name']);
287        }
288        foreach ($this->columns as $column) {
289            if (isset($element['columns'][$column]) && $element['columns'][$column]['value']) {
290                $value = $element['columns'][$column]['value'];
291            } else {
292                $value = $column;
293            }
294            if (isset($element['columns'][$column]) && $element['columns'][$column]['align']) {
295                $align = $element['columns'][$column]['align'];
296            } else {
297                $align = '';
298            }
299            if (!empty($element['columns'][$column]['url'])) {
300                $html .= sprintf('<td class="listingelement%s"><span class="listingelement%s"><a href="%s" class="listingelement" title="%s">%s</a></span></td>',
301                    $align, $align, $element['columns'][$column]['url'], htmlspecialchars($value), $value);
302            } elseif (isset($element['columns'][$column])) {
303                $html .= sprintf('<td class="listingelement%s"><span class="listingelement%s">%s</span></td>', $align,
304                    $align, $element['columns'][$column]['value']);
305            } else {
306                $html .= sprintf('<td class="listingelement%s"><span class="listingelement%s">%s</span></td>', $align,
307                    $align, '');
308            }
309        }
310        $html .= '</tr>';
311        foreach ($element['rows'] as $row) {
312            $value = $row['value'];
313            $align = $row['align'];
314
315            if (!empty($row['url'])) {
316                $html .= sprintf('<tr class="rowelement %s"><td class="listingrowname">
317          <span class="listingrowname"><a href="%s" class="listinghdname" title="%s">%s</a></span>
318          </td><td class="listingelement%s" colspan="%d">
319          <span class="listingelement%s">%s</span>
320          </td></tr>', $row['class'], $row['url'], htmlspecialchars($row['name']), $row['name'], $align,
321                    count($this->columns), $align, $value);
322            } else {
323                $html .= sprintf('<tr class="rowelement %s"><td class="listingrowname">
324          <span class="listingrowname">%s</span>
325          </td><td class="listingelement%s" colspan="%d">
326          <span class="listingelement%s">%s</span>
327          </td></tr>', $row['class'], $row['name'], $align, count($this->columns), $align, $value);
328            }
329        }
330        if (!$this->suppressGreenline) {
331            $html .= sprintf('<!--greenline start-->
332        <tr>
333        <td colspan="%d" bgcolor="#CCCC99"><img height="1" alt="" src="images/transparent.png" width="1" border="0" /></td>
334        </tr>
335        <!--greenline end-->
336      ', count($this->columns) + 2);
337        }
338        $this->buttonduplicate = 1;
339        if ($this->buttonduplicate) {
340            $buttons = '';
341            foreach ($this->duplicatebuttons as $key => $val) {
342                ++$this->duplicatebuttons[$key]['rowcount'];
343                if ($val['rowcount'] >= $val['rows']) {
344                    if ($this->buttons[$val['button']]) {
345                        $buttons .= sprintf('<a class="button" href="%s">%s</a>', $this->buttons[$val['button']],
346                            strtoupper($val['button']));
347                    }
348                    $this->duplicatebuttons[$key]['rowcount'] = 1;
349                }
350            }
351            if ($buttons) {
352                $html .= sprintf('
353        <tr><td colspan="2">&nbsp;</td></tr>
354        <tr><td colspan="%d" align="right">%s</td></tr>
355        <tr><td colspan="2">&nbsp;</td></tr>
356        ', count($this->columns) + 2, $buttons);
357            }
358        }
359
360        return $html;
361    }
362
363    public function listingEnd()
364    {
365        $html = '';
366        $buttons = '';
367        if (count($this->buttons)) {
368            foreach ($this->buttons as $button => $url) {
369                $buttons .= sprintf('<a class="button" href="%s">%s</a>', $url, strtoupper($button));
370            }
371            if (!$this->buttonsOutsideTable) {
372                $html .= sprintf('
373      <tr><td colspan="2">&nbsp;</td></tr>
374      <tr><td colspan="%d" align="right">%s</td></tr>
375      <tr><td colspan="2">&nbsp;</td></tr>
376      ', count($this->columns) + 2, $buttons);
377            }
378        }
379        $submitbuttons = '';
380        if (count($this->submitbuttons)) {
381            foreach ($this->submitbuttons as $name => $label) {
382                $submitbuttons .= sprintf('<button type="submit" name="%s">%s</button>', $name, strtoupper($label));
383            }
384            if (!$this->buttonsOutsideTable) {
385                $html .= sprintf('
386      <tr><td colspan="2">&nbsp;</td></tr>
387      <tr><td colspan="%d" align="right">%s</td></tr>
388      <tr><td colspan="2">&nbsp;</td></tr>
389      ', count($this->columns) + 2, $submitbuttons);
390            }
391        }
392        $html .= '</table>';
393        if ($this->buttonsOutsideTable) {
394            $html .= $buttons.$submitbuttons;
395        }
396
397        return $html;
398    }
399
400    public function index()
401    {
402        return '<a name="top">Index:</a><br />';
403    }
404
405    public function cmp($a, $b)
406    {
407        if (isset($_GET['sortby'])) {
408            $sortcol = urldecode($_GET['sortby']);
409        } elseif (!empty($this->sortcolumn)) {
410            $sortcol = $this->sortcolumn;
411        }
412        if (!is_array($a) || !is_array($b)) {
413            return 0;
414        }
415        $val1 = strip_tags($a['columns'][$sortcol]['value']);
416        $val2 = strip_tags($b['columns'][$sortcol]['value']);
417        if ($val1 == $val2) {
418            return 0;
419        }
420
421        return $val1 < $val2 ? -1 : 1;
422    }
423
424    public function collapse()
425    {
426        $this->initialstate = 'none';
427    }
428
429    public function display($add_index = 0, $class = '')
430    {
431        $html = '';
432        if (!count($this->elements)) {
433            return '';
434        }
435//   if ($add_index)
436//     $html = $this->index();
437
438        $html .= $this->listingStart($class);
439        if (!empty($this->insideNav)) {
440            $html .= sprintf('<tr><td colspan="%d">%s</td></tr>', count($this->columns) + 1, $this->insideNav);
441        }
442        if (!$this->suppressHeader) {
443            $html .= $this->listingHeader();
444        }
445
446//    global $float_menu;
447//    $float_menu .= "<a style=\"display: block;\" href=\"#".htmlspecialchars($this->title)."\">$this->title</a>";
448        if ($this->sort) {
449            usort($this->elements, array($this, 'cmp'));
450        }
451        if ($this->sortcolumn) {
452            usort($this->elements, array($this, 'cmp'));
453        }
454
455        foreach ($this->elements as $element) {
456            $html .= $this->listingElement($element);
457        }
458        $html .= $this->listingEnd();
459
460        if ($this->usePanel) {
461            $p = new UIPanel($this->title, $html, $this->panelNav);
462
463            return $p->display();
464        }
465
466        if (!$this->useShader) {
467            return $html;
468        }
469
470        $shader = new WebblerShader($this->title);
471        $shader->addContent($html);
472        $shader->display = $this->initialstate;
473        $html = $shader->shaderStart();
474        $html .= $shader->header();
475        $html .= $shader->dividerRow();
476        $html .= $shader->contentDiv();
477        $html .= $shader->footer();
478
479        return $html;
480    }
481
482    public function plainText($text)
483    {
484        $text = strip_tags($text);
485        $text = str_ireplace('&nbsp;', ' ', $text);
486
487        return $text;
488    }
489
490    /**
491     * Change output format to tab delimited (TSV)
492     */
493    public function tabDelimited()
494    {
495        $heading = isset($this->elementHeading) ? $this->elementHeading : $this->title;
496        echo $heading."\t";
497        foreach ($this->columns as $column => $columnname) {
498            echo $this->plainText($column)."\t";
499        }
500        echo "\n";
501        foreach ($this->elements as $element) {
502            echo $this->plainText($element['name'])."\t";
503            foreach ($this->columns as $column) {
504                if (isset($element['columns'][$column]) && $element['columns'][$column]['value']) {
505                    echo $this->plainText($element['columns'][$column]['value']);
506                }
507                echo "\t";
508            }
509            echo "\n";
510        }
511        exit;
512    }
513}
514
515class WebblerListing2 extends WebblerListing
516{
517    public function listingStart($class = '')
518    {
519        return '<div class="listing '.$class.'">';
520    }
521
522    public function listingHeader()
523    {
524        return '
525<div class="header">
526	<a href="#">Test list d2e53c3bd01</a>
527<input type="text" name="listorder[3]" value="1" size="5">
528</div><!--ENDOF .header -->      ';
529        $tophelp = '';
530        if (!count($this->columns)) {
531            $tophelp = $this->help;
532        }
533        $html = '<tr valign="top">';
534        $html .= sprintf('<th><a name="%s"></a><div class="listinghdname">%s%s</div></th>',
535            str_replace(' ', '_', htmlspecialchars(mb_strtolower($this->title))), $tophelp, $this->title);
536        $c = 1;
537        foreach ($this->columns as $column => $columnname) {
538            if ($c == count($this->columns)) {
539                $html .= sprintf('<th><div class="listinghdelement">%s%s</div></th>', $columnname, $this->help);
540            } else {
541                if ($this->sortby[$columnname] && $this->sort) {
542                    $display = sprintf('<a href="./?%s&amp;sortby=%s" title="sortby">%s</a>',
543                        $this->removeGetParam('sortby'), urlencode($columnname), $columnname);
544                } else {
545                    $display = $columnname;
546                }
547                $html .= sprintf('<th><div class="listinghdelement">%s</div></th>', $display);
548            }
549            ++$c;
550        }
551        //  $html .= sprintf('<td align="right"><span class="listinghdelementright">%s</span></td>',$lastelement);
552        $html .= '</tr>';
553
554        return $html;
555    }
556
557    public function listingElement($element)
558    {
559        /*
560    return '<div class="column members">
561    <a href="#"><span class="label">Members</span> <span class="value">55425</span></a>
562    <a class="button" href="#" title="add">Add</a>
563</div><!--ENDOF .column --> ';
564*/
565
566        if (!empty($element['colsize'])) {
567            $width = 'width='.$element['colsize'];
568        } else {
569            $width = '';
570        }
571        if (isset($element['class'])) {
572            $html = '<tr class="'.$element['class'].'">';
573        } else {
574            $html = '<tr>';
575        }
576
577        $html = '<div class="column '.$element['class'].'">';
578
579        foreach ($this->columns as $column) {
580            if (isset($element['columns'][$column]) && $element['columns'][$column]['value']) {
581                $value = $element['columns'][$column]['value'];
582            } else {
583                $value = $column;
584            }
585            if (!empty($element['columns'][$column]['url'])) {
586                $url = $element['columns'][$column]['url'];
587            } else {
588                $url = '#';
589            }
590            $html .= sprintf('
591          <a href="%s" title="%s">
592            <span class="label">%s</span>
593            <span class="value">%s</span>
594          </a>', $url, htmlspecialchars(strip_tags($value)), $column, $value);
595        }
596
597        return $html;
598        foreach ($element['rows'] as $row) {
599            if ($row['value']) {
600                $value = $row['value'];
601            } else {
602                $value = '';
603            }
604            if (isset($row['align'])) {
605                $align = $row['align'];
606            } else {
607                $align = 'left';
608            }
609            if (!empty($row['url'])) {
610                $html .= sprintf('<tr><td class="listingrowname">
611          <span class="listingrowname"><a href="%s" class="listinghdname" title="%s">%s</a></span>
612          </td><td class="listingelement%s" colspan="%d">
613          <span class="listingelement%s">%s</span>
614          </td></tr>', $row['url'], htmlspecialchars(strip_tags($row['name'])), $row['name'], $align,
615                    count($this->columns), $align, $value);
616            } else {
617                $html .= sprintf('<tr><td class="listingrowname">
618          <span class="listingrowname">%s</span>
619          </td><td class="listingelement%s" colspan="%d">
620          <span class="listingelement%s">%s</span>
621          </td></tr>', $row['name'], $align, count($this->columns), $align, $value);
622            }
623        }
624        $this->buttonduplicate = 1;
625        if ($this->buttonduplicate) {
626            $buttons = '';
627            foreach ($this->duplicatebuttons as $key => $val) {
628                ++$this->duplicatebuttons[$key]['rowcount'];
629                if ($val['rowcount'] >= $val['rows']) {
630                    if ($this->buttons[$val['button']]) {
631                        $buttons .= sprintf('<a class="button" href="%s">%s</a>', $this->buttons[$val['button']],
632                            strtoupper($val['button']));
633                    }
634                    $this->duplicatebuttons[$key]['rowcount'] = 1;
635                }
636            }
637            if ($buttons) {
638                $html .= sprintf('
639        <tr><td colspan="2">&nbsp;</td></tr>
640        <tr><td colspan="%d" align="right">%s</td></tr>
641        <tr><td colspan="2">&nbsp;</td></tr>
642        ', count($this->columns) + 2, $buttons);
643            }
644        }
645
646        return $html;
647    }
648
649    public function listingEnd()
650    {
651        return '</div><!--ENDOF .listing -->  ';
652        $html = '';
653        $buttons = '';
654        if (count($this->buttons)) {
655            foreach ($this->buttons as $button => $url) {
656                $buttons .= sprintf('<a class="button" href="%s">%s</a>', $url, strtoupper($button));
657            }
658            $html .= sprintf('
659    <tr><td colspan="2">&nbsp;</td></tr>
660    <tr><td colspan="%d" align="right">%s</td></tr>
661    <tr><td colspan="2">&nbsp;</td></tr>
662    ', count($this->columns) + 2, $buttons);
663        }
664        $buttons = '';
665        if (count($this->submitbuttons)) {
666            foreach ($this->submitbuttons as $name => $label) {
667                $buttons .= sprintf('<button type="submit" name="%s">%s</button>', $name, strtoupper($label));
668            }
669            $html .= sprintf('
670    <tr><td colspan="2">&nbsp;</td></tr>
671    <tr><td colspan="%d" align="right">%s</td></tr>
672    <tr><td colspan="2">&nbsp;</td></tr>
673    ', count($this->columns) + 2, $buttons);
674        }
675        $html .= '</table>';
676
677        return $html;
678    }
679}
680
681/*
682<div class="column bounces">
683    <a href="#"><span class="label">Bounces</span>
684    <span class="value">10910</span></a>
685</div><!--ENDOF .column -->
686<div class="column settings">
687    <div class="listingfield">
688    <label for="checkbox" class="inline">Public</label>
689    <input type="checkbox" name="active[3]" value="1" checked="checked">
690    </div>
691    <div class="listingfield">
692    <span class="label inline">Owner</span> <span class="title">Admin<span class="title">
693    </div>
694</div><!--ENDOF .settings -->
695<div class="content">
696<p>This is a text description of this list decribing it in as much detail as required by the administartor that creates the list</p>
697</div><!--ENDOF .content -->
698
699*/
700
701class DomTab
702{
703    public $tabs = array();
704    public $domtabcluster = '';
705
706    public function __construct($name = '')
707    {
708        $this->domtabcluster = $name;
709    }
710
711    public function addTab($title, $content)
712    {
713        $this->tabs[strip_tags($title)] = $content;
714    }
715
716    public function header()
717    {
718        return '
719	<script type="text/javascript">
720		document.write(\'<style type="text/css">\');
721		document.write(\'div.domtab div{display:visible;}<\');
722		document.write(\'/s\'+\'tyle>\');
723    </script>
724  ';
725    }
726
727    public function display()
728    {
729        $html = '
730      <div class="domtab">
731        <ul class="domtabs">
732        ';
733        foreach ($this->tabs as $title => $content) {
734            $html .= sprintf('<li><a href="#%s" title="%s">%s</a></li>',
735                $this->domtabcluster.urlencode(mb_strtolower($title)), htmlspecialchars($title), $title);
736        }
737        $html .= '</ul>';
738
739        foreach ($this->tabs as $title => $content) {
740            $html .= '<div style="display: none;">';
741            $html .= sprintf('<h4><a name="%s" id="%s"><span class="hide">%s</span></a></h4>',
742                $this->domtabcluster.mb_strtolower($title), $this->domtabcluster.urlencode(strtolower($title)),
743                $title);
744            $html .= $content;
745            $html .= '</div>';
746        }
747        $html .= '</div>';
748
749        return $this->header().$html;
750    }
751}
752
753class WebblerTabs
754{
755    private $tabs = array();
756    private $tablabels = array();
757    private $current = '';
758    private $currentTitle = '';
759    private $previous = '';
760    private $next = '';
761    private $linkcode = '';
762    private $liststyle = 'ul';
763    private $addTabNo = false;
764    private $class = '';
765    private $addprevnext = false;
766    private $id = 'webblertabs';
767
768    public function addTab($label, $url = '', $name = '')
769    {
770        if (empty($name)) {
771            $name = $label;
772        }
773        $this->tabs[$name] = $url;
774        $this->tablabels[$name] = $label;
775    }
776
777    public function insertTabBefore($first, $second)
778    {
779        if (isset($this->tabs[$first]) && isset($this->tabs[$second])) {
780            $reordered = array();
781            foreach ($this->tabs as $tabName => $tabContent) {
782                if ($tabName == $second) {
783                    // skip
784                } elseif ($tabName == $first) {
785                    $reordered[$second] = $this->tabs[$second];
786                    $reordered[$first] = $tabContent;
787                } else {
788                    $reordered[$tabName] = $tabContent;
789                }
790            }
791            $this->tabs = $reordered;
792        }
793    }
794
795    public function addPrevNext()
796    {
797        $this->addprevnext = true;
798    }
799
800    public function addTabNo()
801    {
802        $this->addTabNo = true;
803    }
804
805    public function listStyle($style)
806    {
807        $this->liststyle = $style;
808    }
809
810    public function setId($id)
811    {
812        $this->id = $id;
813    }
814
815    public function tabTitle()
816    {
817        return $this->currentTitle;
818    }
819
820    public function setListClass($class)
821    {
822        $this->class = $class;
823    }
824
825    public function setCurrent($name)
826    {
827        $this->current = mb_strtolower(strip_tags($name));
828        $this->currentTitle = htmlspecialchars(strip_tags($name));
829    }
830
831    public function previousLink()
832    {
833        if (!empty($this->previous)) {
834            return sprintf('<a href="%s" %s title="%s">', $this->tabs[$this->previous], $this->linkcode,
835                $GLOBALS['I18N']->get('Previous'));
836        }
837
838        return '';
839    }
840
841    public function previous()
842    {
843        if (!empty($this->previous)) {
844            return $this->tabs[$this->previous];
845        }
846
847        return '';
848    }
849
850    public function next()
851    {
852        if (!empty($this->next)) {
853            return $this->tabs[$this->next];
854        }
855
856        return '';
857    }
858
859    public function addLinkCode($code)
860    {
861        $this->linkcode = $code;
862    }
863
864    public function prevNextNav()
865    {
866        $html = '<div class="step-nav">';
867
868        $previousTab = $this->previous();
869        $nextTab = $this->next();
870        if (!empty($previousTab)) {
871            $html .= '<a class="back savechanges" href="'.$previousTab.'">'.$GLOBALS['I18N']->get('Back').'</a>';
872        } else {
873            //  $html .= '<a class="back">'.$GLOBALS['I18N']->get('Back').'</a>';
874        }
875        if (!empty($nextTab)) {
876            $html .= '<a class="next savechanges" href="'.$nextTab.'">'.$GLOBALS['I18N']->get('Next').'</a>';
877        } else {
878            //  $html .= '<a class="next">'.$GLOBALS['I18N']->get('Next').'</a>';
879        }
880        $html .= '</div>';
881
882        return $html;
883    }
884
885    public function display()
886    {
887        $html = '';
888        if (empty($GLOBALS['design']) && empty($GLOBALS['ui'])) {
889            $html = '<style type=text/css media=screen>@import url( styles/tabs.css );</style>';
890        }
891        $html .= '<div id="'.$this->id.'">';
892        $html .= '<'.$this->liststyle;
893        if (!empty($this->class)) {
894            $html .= ' class="'.$this->class.'"';
895        }
896        $html .= '>';
897        reset($this->tabs);
898        $previous = $next = '';
899        $gotcurrent = false;
900        $count = 0;
901        foreach ($this->tabs as $tab => $url) {
902            ++$count;
903            if (mb_strtolower(strip_tags($tab)) == $this->current) {
904                $this->previous = $previous;
905                $gotcurrent = true;
906                $html .= '<li class="current" id="'.$count.'">';
907            } else {
908                if ($gotcurrent && empty($this->next)) {
909                    $this->next = $tab;
910                }
911                $html .= '<li>';
912            }
913            $html .= sprintf('<a href="%s" %s title="%s">', $url, $this->linkcode,
914                htmlspecialchars(strip_tags($this->tablabels[$tab])));
915            if ($this->addTabNo) {
916                $html .= sprintf('<span class="tabno">%d</span> ', $count);
917            }
918            $html .= sprintf('<span class="title">%s</span></a>', ucfirst($this->tablabels[$tab]));
919            $html .= '</li>';
920            $previous = $tab;
921        }
922        $html .= '</'.$this->liststyle.'>';
923
924        if ($this->addprevnext) {
925            $html .= $this->prevNextNav();
926        }
927        $html .= '</div>';
928
929//    $html .= '<span class="faderight">&nbsp;</span>';
930        //  $html .= '<br clear="all" />';
931        return $html;
932    }
933}
934
935class pageInfo
936{
937    private $noteid = '';
938    private $ajaxed = false;
939    private $page = '';
940    private $infocontent = '';
941    private $addhide = true;
942
943    public function __construct($id = '')
944    {
945        $this->ajaxed = isset($_GET['ajaxed']);
946        $this->noteid = $id;
947        $this->page = $GLOBALS['page'];
948    }
949
950    public function setContent($content)
951    {
952        $this->infocontent = $content;
953    }
954
955    public function suppressHide()
956    {
957        $this->addhide = false;
958    }
959
960    public function fetchInfoContent($include)
961    {
962        //# pages to not allow hiding the info for
963        if (in_array($include, array('login.php', 'logout.php'))) {
964            $this->addhide = false;
965        }
966        //# import has too much in the info and needs replacing
967        if (in_array($include, array('import.php'))) {
968            return '';
969        }
970        //# community should not show in the global help, but main page
971        if (in_array($include, array('community.php'))) {
972            return '';
973        }
974        $this->noteid = substr(md5(basename($include, '.php')), 0, 15);
975        $this->page = $this->noteid;
976        $buffer = ob_get_contents();
977        ob_end_clean();
978        ob_start();
979
980        // include some information
981        if (empty($_GET['pi'])) {
982            if (is_file('info/'.$_SESSION['adminlanguage']['info']."/$include")) {
983                @include 'info/'.$_SESSION['adminlanguage']['info']."/$include";
984            } elseif (is_file("info/en/$include")) {
985                @include "info/en/$include";
986            } else {
987                echo $buffer;
988
989                return ''; //'No file: '."info/en/$include";
990            }
991        } elseif (isset($_GET['pi']) && !empty($GLOBALS['plugins'][$_GET['pi']]) && is_object($GLOBALS['plugins'][$_GET['pi']])) {
992            if (is_file($GLOBALS['plugins'][$_GET['pi']]->coderoot.'/info/'.$_SESSION['adminlanguage']['info']."/$include")) {
993                @include $GLOBALS['plugins'][$_GET['pi']]->coderoot.'/info/'.$_SESSION['adminlanguage']['info']."/$include";
994            }
995        } elseif (is_file("info/en/$include")) {
996            @include "info/en/$include";
997            //  print "Not a file: "."info/".$adminlanguage["info"]."/$include";
998        } else {
999            echo $buffer;
1000
1001            return '';
1002        }
1003        $this->infocontent = ob_get_contents();
1004        ob_end_clean();
1005        ob_start();
1006        echo $buffer;
1007    }
1008
1009    public function show()
1010    {
1011        $html = '';
1012        if ($this->ajaxed || ($this->addhide && !empty($_SESSION['suppressinfo'][$this->noteid]))) {
1013            return '';
1014        }
1015        if (empty($this->infocontent)) {
1016            return '';
1017        }
1018        if (isset($_GET['action']) && $_GET['action'] == 'hidenote' && isset($_GET['note']) && $_GET['note'] == $this->noteid) {
1019            if (!isset($_SESSION['suppressinfo']) || !is_array($_SESSION['suppressinfo'])) {
1020                $_SESSION['suppressinfo'] = array();
1021            }
1022            if ($this->addhide) {
1023                $_SESSION['suppressinfo'][$this->noteid] = 'hide';
1024            }
1025        }
1026
1027        $html = '<div class="note '.$this->noteid.'">';
1028        if ($this->addhide) {
1029            $html .=
1030                '<a href="./?page='
1031                .$GLOBALS['page']
1032                .'&amp;action=hidenote&amp;note='
1033                .$this->noteid
1034                .'" class="hide ajaxable" title="'
1035                .$GLOBALS['I18N']->get('Close this box')
1036                .'">'
1037                .$GLOBALS['I18N']->get('Hide')
1038                .'</a>';
1039        }
1040        $html .= $this->infocontent;
1041        $html .= '</div>'; //# end of info div
1042        return $html;
1043    }
1044
1045    public function content()
1046    {
1047        /* return current content, and then clear it, so it won't show twice */
1048        $return = $this->infocontent;
1049        $this->infocontent = '';
1050
1051        return $return;
1052    }
1053}
1054
1055class button
1056{
1057    protected $link;
1058    protected $title;
1059    protected $linktext;
1060    protected $linkhtml = '';
1061    protected $js = '';
1062
1063    public function __construct($link, $linktext, $title = '')
1064    {
1065        $this->link = $link;
1066        $this->linktext = $linktext;
1067        $this->title = $title;
1068    }
1069
1070    public function showA()
1071    {
1072        $html = '<a href="'.$this->link.'" '.$this->linkhtml;
1073        if ($this->title) {
1074            $html .= ' title="'.htmlspecialchars($this->title).'"';
1075        } else {
1076            $html .= ' title="'.htmlspecialchars($this->linktext).'"';
1077        }
1078        $html .= '>';
1079        $html .= $this->linktext;
1080
1081        return $html;
1082    }
1083
1084    public function showAend()
1085    {
1086        $html = '</a>'.$this->js;
1087
1088        return $html;
1089    }
1090
1091    public function show()
1092    {
1093        return $this->showA().$this->showAend();
1094    }
1095}
1096
1097class confirmButton extends button
1098{
1099    protected $link;
1100    protected $title;
1101    protected $linktext;
1102    protected $linkhtml = '';
1103    protected $js;
1104
1105    public function __construct($confirmationtext, $link, $linktext, $title = '', $class = 'confirm')
1106    {
1107        $onclickevent = 'return confirm(\''.htmlspecialchars(strip_tags($confirmationtext)).'\')';
1108        $this->linkhtml = ' class="'.$class.'" onclick="'.$onclickevent.'"';
1109        $this->link = $link;
1110        $this->linktext = $linktext;
1111        $this->title = $title;
1112    }
1113}
1114
1115class buttonGroup
1116{
1117    private $buttons = array();
1118    private $topbutton = '';
1119
1120    public function __construct($topbutton = '')
1121    {
1122        $this->topbutton = $topbutton;
1123    }
1124
1125    public function addButton($button)
1126    {
1127        if (empty($this->topbutton)) {
1128            $this->topbutton = $button;
1129        } else {
1130            $this->buttons[] = $button;
1131        }
1132    }
1133
1134    public function show()
1135    {
1136        $html = '<div class="dropButton">';
1137
1138        $html .= $this->topbutton->showA();
1139
1140        if (count($this->buttons)) {
1141            $html .= '<img height="18" width="18" align="top" class="arrow" src="ui/'.$GLOBALS['ui'].'/images/menuarrow.png" />';
1142        }
1143
1144        $html .= $this->topbutton->showAend();
1145
1146        if (count($this->buttons)) {
1147            $html .= '<div class="submenu" style="display: none;">';
1148
1149            foreach ($this->buttons as $button) {
1150                $html .= $button->show();
1151            }
1152
1153            $html .= '</div>';
1154        }
1155
1156        $html .= '</div>';
1157
1158        return $html;
1159    }
1160}
1161
1162class WebblerShader
1163{
1164    public $name = 'Untitled';
1165    public $content = '';
1166    public $num = 0;
1167    public $isfirst = 0;
1168    public $display = 'block';
1169    public $initialstate = 'open';
1170
1171    public function __construct($name)
1172    {
1173        $this->name = $name;
1174        if (!isset($GLOBALS['shadercount'])) {
1175            $GLOBALS['shadercount'] = 0;
1176            $this->isfirst = 1;
1177        }
1178        $this->num = $GLOBALS['shadercount'];
1179        ++$GLOBALS['shadercount'];
1180    }
1181
1182    public function addContent($content)
1183    {
1184        $this->content = $content;
1185    }
1186
1187    public function hide()
1188    {
1189        $this->display = 'none';
1190    }
1191
1192    public function show()
1193    {
1194        $this->display = 'block';
1195    }
1196
1197    public function shaderJavascript()
1198    {
1199        if ($_SERVER['QUERY_STRING']) {
1200            $cookie = 'WS?'.$_SERVER['QUERY_STRING'];
1201        } else {
1202            $cookie = 'WS';
1203        }
1204        if (!isset($_COOKIE[$cookie])) {
1205            $_COOKIE[$cookie] = '';
1206        }
1207
1208        return '
1209  <script language="Javascript" type="text/javascript">
1210
1211  <!--
1212  var states = Array("' .implode('","', explode(',', $_COOKIE[$cookie])).'");
1213  var cookieloaded = 0;
1214  var expireDate = new Date;
1215  expireDate.setDate(expireDate.getDate()+365);
1216
1217  function cookieVal(cookieName) {
1218    var thisCookie = document.cookie.split("; ")
1219    for (var i = 0; i < thisCookie.length; i++) {
1220      if (cookieName == thisCookie[i].split("=")[0]) {
1221        return thisCookie[i].split("=")[1];
1222      }
1223    }
1224    return 0;
1225  }
1226
1227  function saveStates() {
1228    document.cookie = "WS"+escape(this.location.search)+"="+states+";expires=" + expireDate.toGMTString();
1229  }
1230
1231  var agt = navigator.userAgent.toLowerCase();
1232  var is_major = parseInt(navigator.appVersion);
1233  var is_nav = ((agt.indexOf(\'mozilla\') != -1) && (agt.indexOf(\'spoofer\') == -1) && (agt.indexOf(\'compatible\') == -1) && (agt.indexOf(\'opera\') == -1) && (agt.indexOf(\'webtv\') == -1));
1234  var is_nav4up = (is_nav && (is_major >= 4));
1235  var is_ie = (agt.indexOf("msie") != -1);
1236  var is_ie3  = (is_ie && (is_major < 4));
1237  var is_ie4  = (is_ie && (is_major == 4) && (agt.indexOf("msie 5") == -1) && (agt.indexOf("msie 6") == -1));
1238  var is_ie4up = (is_ie && (is_major >= 4));
1239  var is_ie5up  = (is_ie  && !is_ie3 && !is_ie4);
1240  var is_mac = (agt.indexOf("mac") != -1);
1241  var is_gecko = (agt.indexOf("gecko") != -1);
1242  var view;
1243
1244  function getItem (id) {
1245    var view;
1246    if (is_ie4) {
1247      view = eval(id);
1248    }
1249    if (is_ie5up || is_gecko) {
1250      view = document.getElementById(id);
1251    }
1252    return view;
1253  }
1254
1255  function shade(id) {
1256    if(is_ie4up || is_gecko) {
1257
1258      var shaderDiv = getItem(\'shader\'+id);
1259      var shaderSpan = getItem(\'shaderspan\'+id);
1260  //    var shaderImg = getItem(\'shaderimg\'+id);
1261      var shaderImg = false;
1262      var footerTitle = getItem(\'title\'+id);
1263      if(shaderDiv.style.display == \'block\') {
1264        states[id] = "closed";
1265        shaderDiv.style.display = \'none\';
1266        shaderSpan.innerHTML = \'<span class="shadersmall">' .$GLOBALS['I18N']->get('open').'&nbsp;</span><img alt="" src="images/shaderdown.gif" height="9" width="9" border="0" />\';
1267        footerTitle.style.visibility = \'visible\';
1268        if (shaderImg)
1269          shaderImg.src = \'images/expand.gif\';
1270      } else {
1271        states[id] = "open";
1272        shaderDiv.style.display = \'block\';
1273        footerTitle.style.visibility = \'hidden\';
1274        shaderSpan.innerHTML = \'<span class="shadersmall">' .$GLOBALS['I18N']->get('close').'&nbsp;</span><img alt="" src="images/shaderup.gif" height="9" width="9" border="0" />\';
1275        if (shaderImg)
1276          shaderImg.src = \'images/collapse.gif\';
1277      }
1278    }
1279    saveStates();
1280  }
1281
1282  function getPref(number) {
1283    if (states[number] == "open") {
1284      return "block";
1285    } else if (states[number] == "closed") {
1286      return "none";
1287    }
1288    return "";
1289  }
1290
1291  function start_div(number, default_status) {
1292    if (is_ie4up || is_gecko) {
1293      var pref = getPref(number);
1294      if (pref) {
1295        default_status = pref;
1296      }
1297
1298      document.writeln("<div id=\'shader" + number + "\' name=\'shader" + number + "\' class=\'shader\' style=\'display: " + default_status + ";\'>");
1299    }
1300  }
1301
1302
1303  function end_div(number, default_status) {
1304    if (is_ie4up || is_gecko) {
1305      document.writeln("</div>");
1306    }
1307  }
1308  var title_text = "";
1309  var span_text = "";
1310  var title_class = "";
1311
1312  function open_span(number, default_status) {
1313    if (is_ie4up || is_gecko) {
1314      var pref = getPref(number);
1315      if (pref) {
1316        default_status = pref;
1317      }
1318      if(default_status == \'block\') {
1319        span_text = \'<span class="shadersmall">' .$GLOBALS['I18N']->get('close').'&nbsp;</span><img src="images/shaderup.gif" alt="" height="9" width="9" border="0" />\';
1320      } else {
1321        span_text = \'<span class="shadersmall">' .$GLOBALS['I18N']->get('open').'&nbsp;</span><img src="images/shaderdown.gif" alt="" height="9" width="9" border="0" />\';
1322      }
1323      document.writeln("<a href=\'javascript: shade(" + number + ");\'><span id=\'shaderspan" + number + "\' class=\'shadersmalltext\'>" + span_text + "</span></a>");
1324    }
1325  }
1326
1327  function title_span(number,default_status,title) {
1328    if (is_ie4up || is_gecko) {
1329      var pref = getPref(number);
1330      if (pref) {
1331        default_status = pref;
1332      }
1333      if(default_status == \'none\') {
1334        title_text = \'<img src="images/expand.gif" alt="" height="9" width="9" border="0" />  \'+title;
1335        title_class = "shaderfootertextvisible";
1336      } else {
1337        title_text = \'<img src="images/collapse.gif" alt="" height="9" width="9" border="0" />   \'+title;
1338        title_class = "shaderfootertexthidden";
1339      }
1340      document.writeln("<a href=\'javascript: shade(" + number + ");\'><span id=\'title" + number + "\' class=\'"+title_class+"\'>" + title_text + "</span></a>");
1341    }
1342  }
1343//-->
1344</script>
1345    ';
1346    }
1347
1348    public function header()
1349    {
1350        $html = sprintf('
1351<div class="tablewrapper">
1352<table width="98%%" align="center" cellpadding="0" cellspacing="0" border="0">');
1353
1354        return $html;
1355    }
1356
1357    public function shadeIcon()
1358    {
1359        return sprintf('
1360<a href="javascript:shade(%d);" style="text-decoration:none;">&nbsp;<img id="shaderimg%d" src="images/collapse.gif" alt="" height="9" width="9" border="0" />
1361    ', $this->num, $this->num);
1362    }
1363
1364    public function titleBar()
1365    {
1366        return sprintf('
1367  <tr>
1368      <td colspan="4" class="shaderheader">%s
1369          <span class="shaderheadertext">&nbsp;%s</span>
1370         </a>
1371    </td>
1372  </tr>', $this->shadeIcon(), $this->name);
1373    }
1374
1375    public function dividerRow()
1376    {
1377        return '
1378  <tr>
1379      <td colspan="4" class="shaderdivider"><img src="images/transparent.png" height="1" alt="" border="0" width="1" /></td>
1380  </tr>
1381    ';
1382    }
1383
1384    public function footer()
1385    {
1386        $html = sprintf('
1387
1388  <tr>
1389    <td class="shaderborder"><img src="images/transparent.png" alt="" height="1" border="0" width="1" /></td>
1390    <td class="shaderfooter"><script language="javascript"  type="text/javascript">title_span(%d,\'%s\',\'%s\');</script>&nbsp;</td>
1391    <td class="shaderfooterright"><script language="javascript" type="text/javascript">open_span(%d,\'%s\');</script>&nbsp;</td>
1392    <td class="shaderborder"><img src="images/transparent.png" alt="" height="1" border="0" width="1" /></td>
1393  </tr>
1394' .$this->dividerRow().'
1395</table><!-- End table from header -->
1396</div><!-- End tablewrapper -->
1397    ', $this->num, $this->display, addslashes($this->name), $this->num, $this->display);
1398
1399        return $html;
1400    }
1401
1402    public function contentDiv()
1403    {
1404        $html = sprintf('
1405  <tr>
1406      <td class="shaderdivider"><img src="images/transparent.png" alt="" height="1" border="0" width="1" /></td>
1407      <td colspan="2">
1408      <script language="javascript" type="text/javascript">start_div(%d,\'%s\')</script>', $this->num, $this->display);
1409        $html .= $this->content;
1410
1411        $html .= '
1412    <script language="javascript" type="text/javascript">end_div();</script>
1413    </td>
1414
1415    <td class="shaderdivider"><img src="images/transparent.png" alt="" height="1" border="0" width="1" /></td>
1416  </tr>';
1417
1418        return $html;
1419    }
1420
1421    public function shaderStart()
1422    {
1423        if (!isset($GLOBALS['shaderJSset'])) {
1424            $html = $this->shaderJavascript();
1425            $GLOBALS['shaderJSset'] = 1;
1426        } else {
1427            $html = '';
1428        }
1429
1430        return $html;
1431    }
1432
1433    public function display()
1434    {
1435        $html = $this->shaderStart();
1436        $html .= $this->header();
1437        $html .= $this->titleBar();
1438        $html .= $this->dividerRow();
1439        $html .= $this->contentDiv();
1440        $html .= $this->footer();
1441
1442        return $html;
1443    }
1444}
1445