Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
/**
3
 * HTML_TreeMenu
4
 *
5
 * PHP Versions 4 and 5
6
 *
7
 *   Copyright (c) 2002-2005, Richard Heyes, Harald Radi
8
 *   All rights reserved.
9
 *
10
 *   Redistribution and use in source and binary forms, with or without
11
 *   modification, are permitted provided that the following conditions
12
 *   are met:
13
 *
14
 *   o Redistributions of source code must retain the above copyright
15
 *     notice, this list of conditions and the following disclaimer.
16
 *   o Redistributions in binary form must reproduce the above copyright
17
 *     notice, this list of conditions and the following disclaimer in the
18
 *     documentation and/or other materials provided with the distribution.
19
 *   o The names of the authors may not be used to endorse or promote
20
 *     products derived from this software without specific prior written
21
 *     permission.
22
 *
23
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
 *
35
 * @category HTML
36
 * @package  HTML_TreeMenu
37
 * @author   Richard Heyes <richard@php.net>
38
 * @author   Harald Radi <harald.radi@nme.at>
39
 * @license  http://www.opensource.org/licenses/bsd-license.php  BSD License
40
 * @version  CVS: $Id: TreeMenu.php 304737 2010-10-25 09:08:58Z clockwerx $
41
 * @link     http://pear.php.net/package/HTML_TreeMenu
42
 * @todo     PEAR CS - split classes into individual files
43
 */
44
 
45
/**
46
 * HTML_TreeMenu Class
47
 *
48
 * A simple couple of PHP classes and some not so simple
49
 * Jabbascript which produces a tree menu. In IE this menu
50
 * is dynamic, with branches being collapsable. In IE5+ the
51
 * status of the collapsed/open branches persists across page
52
 * refreshes.In any other browser the tree is static. Code is
53
 * based on work of Harald Radi.
54
 *
55
 * Usage.
56
 *
57
 * After installing the package, copy the example php script to
58
 * your servers document root. Also place the TreeMenu.js and the
59
 * images folder in the same place. Running the script should
60
 * then produce the tree.
61
 *
62
 * Thanks go to Chip Chapin (http://www.chipchapin.com) for many
63
 * excellent ideas and improvements.
64
 *
65
 * @category HTML
66
 * @package  HTML_TreeMenu
67
 * @author   Richard Heyes <richard@php.net>
68
 * @author   Harald Radi <harald.radi@nme.at>
69
 * @license  http://www.opensource.org/licenses/bsd-license.php  BSD License
70
 * @link     http://pear.php.net/package/HTML_TreeMenu
71
 */
72
class HTML_TreeMenu
73
{
74
    /**
75
     * Indexed array of subnodes
76
     * @var array
77
     * @access public
78
     */
79
    var $items;
80
 
81
    /**
82
     * Constructor
83
     *
84
     * @access public
85
     */
86
    function HTML_TreeMenu()
87
    {
88
        // Not much to do here :(
89
    }
90
 
91
    /**
92
     * This function adds an item to the the tree.
93
     *
94
     * @param HTML_TreeNode &$node The node to add.
95
     *                             This object should be a HTML_TreeNode object.
96
     *
97
     * @return int Returns a reference to the new node inside the tree.
98
     * @access public
99
     */
100
    function &addItem(&$node)
101
    {
102
        $this->items[] = &$node;
103
        return $this->items[count($this->items) - 1];
104
    }
105
 
106
    /**
107
     * Import method for creating {@link HTML_TreeMenu} objects/structures
108
     * out of existing tree objects/structures.
109
     *
110
     * Currently supported are Wolfram Kriesings' PEAR Tree class, and
111
     * Richard Heyes' Tree class ({@link http://www.phpguru.org/}). This
112
     * method is intended to be used statically, eg:
113
     * <code>
114
     * $treeMenu = &HTML_TreeMenu::createFromStructure($myTreeStructureObj);
115
     * </code>
116
     *
117
     * @param array $params An array of parameters that determine
118
     *                      how the import happens. This can consist of:
119
     *                      <pre>
120
     *                          structure   => The tree structure
121
     *                          type        => The type of the structure, currently
122
     *                                         can be either 'heyes' or 'kriesing'
123
     *                          nodeOptions => Default options for each node
124
     *                      </pre>
125
     *
126
     * @return HTML_TreeMenu The resulting {@link HTML_TreeMenu} object
127
     * @access public
128
     * @static
129
     */
130
    function createFromStructure($params)
131
    {
132
        if (!isset($params['nodeOptions'])) {
133
            $params['nodeOptions'] = array();
134
        }
135
 
136
        switch (@$params['type']) {
137
 
138
        /*
139
         * Wolfram Kriesings' PEAR Tree class
140
         */
141
        case 'kriesing':
142
            $className   = get_class($params['structure']->dataSourceClass);
143
            $className   = strtolower($className);
144
            $isXMLStruct = strpos($className, '_xml') !== false ? true : false;
145
 
146
            // Get the entire tree, the $nodes are sorted like in the tree view
147
            // from top to bottom, so we can easily put them in the nodes
148
            $nodes = $params['structure']->getNode();
149
 
150
            // Make a new menu and fill it with the values from the tree
151
            $treeMenu = new HTML_TreeMenu();
152
            // we need the current node as the reference
153
            $curNode[0] = &$treeMenu;
154
 
155
            foreach ($nodes as $aNode) {
156
                $events = array();
157
                $data   = array();
158
 
159
                /* In an XML, all the attributes are saved in an array, but
160
                 * since they might be  used as the parameters, we simply
161
                 * extract them here if we handle an XML-structure
162
                 */
163
                if ( $isXMLStruct && sizeof($aNode['attributes'])) {
164
                    foreach ($aNode['attributes'] as $key=>$val) {
165
                        if ( !$aNode[$key] ) {
166
                            // dont overwrite existing values
167
                            $aNode[$key] = $val;
168
                        }
169
                    }
170
                }
171
 
172
                // Process all the data that are saved in $aNode and put them
173
                // in the data and/or events array
174
                foreach ($aNode as $key=>$val) {
175
                    if (!is_array($val)) {
176
                        // Dont get the recursive data in here! they are
177
                        // always arrays
178
                        if (substr($key, 0, 2) == 'on') {
179
                            // get the events
180
                            $events[$key] = $val;
181
                        }
182
 
183
                        // I put it in data too, so in case an options starts
184
                        // with 'on' its also passed to the node ... not too
185
                        // cool i know
186
                        $data[$key] = $val;
187
                    }
188
                }
189
 
190
                // Normally the text is in 'name' in the Tree class, so we
191
                // check both but 'text' is used if found
192
                $data['text'] = $aNode['text'] ?
193
                    $aNode['text'] : $aNode['name'];
194
 
195
                // Add the item to the proper node
196
                $thisNode = &$curNode[$aNode['level']]->addItem(new
197
                            HTML_TreeNode($data, $events));
198
 
199
                $curNode[$aNode['level']+1] = &$thisNode;
200
            }
201
            break;
202
 
203
        /*
204
         * Richard Heyes' (me!) second (array based) Tree class
205
         */
206
        case 'heyes_array':
207
            // Need to create a HTML_TreeMenu object ?
208
            if (!isset($params['treeMenu'])) {
209
                $treeMenu = &new HTML_TreeMenu();
210
                $parentID = 0;
211
            } else {
212
                $treeMenu = &$params['treeMenu'];
213
                $parentID = $params['parentID'];
214
            }
215
 
216
            // Loop thru the trees nodes
217
            foreach ($params['structure']->getChildren($parentID)
218
                    as $nodeID) {
219
                $data       = $params['structure']->getData($nodeID);
220
                $parentNode = &$treeMenu->addItem(new
221
                    HTML_TreeNode(array_merge($params['nodeOptions'], $data)));
222
 
223
                // Recurse ?
224
                if ($params['structure']->hasChildren($nodeID)) {
225
                    $recurseParams['type']        = 'heyes_array';
226
                    $recurseParams['parentID']    = $nodeID;
227
                    $recurseParams['nodeOptions'] = $params['nodeOptions'];
228
                    $recurseParams['structure']   = &$params['structure'];
229
                    $recurseParams['treeMenu']    = &$parentNode;
230
                    HTML_TreeMenu::createFromStructure($recurseParams);
231
                }
232
            }
233
 
234
            break;
235
 
236
        /*
237
         * Richard Heyes' (me!) original OO based Tree class
238
         */
239
        case 'heyes':
240
        default:
241
            // Need to create a HTML_TreeMenu object ?
242
            if (!isset($params['treeMenu'])) {
243
                $treeMenu = &new HTML_TreeMenu();
244
            } else {
245
                $treeMenu = &$params['treeMenu'];
246
            }
247
 
248
            // Loop thru the trees nodes
249
            foreach ($params['structure']->nodes->nodes as $node) {
250
                $tag        = $node->getTag();
251
                $parentNode = &$treeMenu->addItem(new
252
                 HTML_TreeNode(array_merge($params['nodeOptions'], $tag)));
253
 
254
                // Recurse ?
255
                if (!empty($node->nodes->nodes)) {
256
                    $recurseParams['structure']   = $node;
257
                    $recurseParams['nodeOptions'] = $params['nodeOptions'];
258
                    $recurseParams['treeMenu']    = &$parentNode;
259
                    HTML_TreeMenu::createFromStructure($recurseParams);
260
                }
261
            }
262
            break;
263
 
264
        }
265
        return $treeMenu;
266
    }
267
 
268
    /**
269
     * Creates a treeMenu from XML.
270
     *
271
     * The structure of your XML should be like so:
272
     * <code>
273
     * <treemenu>
274
     *     <node text="First node" icon="folder.gif"
275
     *           expandedIcon="folder-expanded.gif" />
276
     *     <node text="Second node" icon="folder.gif"
277
     *           expandedIcon="folder-expanded.gif">
278
     *         <node text="Sub node" icon="folder.gif"
279
     *               expandedIcon="folder-expanded.gif" />
280
     *     </node>
281
     *     <node text="Third node" icon="folder.gif"
282
     *           expandedIcon="folder-expanded.gif">
283
     * </treemenu>
284
     * </code>
285
     *
286
     * Any of the options you can supply to the HTML_TreeNode constructor can
287
     * be supplied as attributes to the <node> tag. If there are no
288
     * subnodes for a particular node, you can use the XML shortcut
289
     * <node ... /> instead of <node ... ></node>. The $xml argument
290
     * can be either the XML as a string, or an pre-created XML_Tree
291
     * object. Also, this method REQUIRES my own Tree class to work
292
     * ({@link http://www.phpguru.org/static/tree.html}). If this has not been
293
     * include()ed or require()ed this method will die().
294
     *
295
     * @param string|XML_Tree $xml This can be either a string containing the XML,
296
     *                             or an
297
     *                             {@link http://pear.php.net/package/XML_Tree
298
     *                             XML_Tree} object
299
     *
300
     * @return HTML_TreeMenu The {@link HTML_TreeMenu} object
301
     * @access public
302
     * @static
303
     * @todo update {@link http://pear.php.net/package/XML_Tree XML_Tree} usage
304
     *       to {@link http://pear.php.net/package/XML_Serializer XML_Serializer}
305
     */
306
    function createFromXML($xml)
307
    {
308
        if (!class_exists('Tree')) {
309
            die('Could not find Tree class');
310
        }
311
 
312
        if (is_string($xml)) {
313
            // Supplied $xml is a string
314
            include_once 'XML/Tree.php';
315
            $xmlTree = &new XML_Tree();
316
            $xmlTree->getTreeFromString($xml);
317
        } else {
318
            // Supplied $xml is an XML_Tree object
319
            $xmlTree = $xml;
320
        }
321
 
322
        // Now process the XML_Tree object, setting the XML attributes
323
        // to be the tag data (with out the XML tag name or contents).
324
        $treeStructure = Tree::createFromXMLTree($xmlTree, true);
325
        $treeStructure->nodes->traverse(create_function('&$node', '
326
         $tagData = $node->getTag(); $node->setTag($tagData["attributes"]);'));
327
 
328
        return HTML_TreeMenu::createFromStructure(array(
329
                                               'structure' => $treeStructure));
330
    }
331
} // HTML_TreeMenu
332
 
333
 
334
/**
335
 * HTML_TreeNode class
336
 *
337
 * This class is supplementary to the above and provides a way to
338
 * add nodes to the tree. A node can have other nodes added to it.
339
 *
340
 * @category HTML
341
 * @package  HTML_TreeMenu
342
 * @author   Richard Heyes <richard@php.net>
343
 * @author   Harald Radi <harald.radi@nme.at>
344
 * @license  http://www.opensource.org/licenses/bsd-license.php  BSD License
345
 * @link     http://pear.php.net/package/HTML_TreeMenu
346
 * @todo     PEAR CS - rename to HTML_TreeMenu_Node
347
 */
348
class HTML_TreeNode
349
{
350
    /**#@+
351
     * @var string
352
     * @access public
353
     */
354
 
355
    /**
356
     * The text for this node.
357
     */
358
    var $text;
359
 
360
    /**
361
     * The link for this node.
362
     */
363
    var $link;
364
 
365
    /**
366
     * The icon for this node.
367
     */
368
    var $icon;
369
 
370
    /**
371
     * The icon to show when expanded for this node.
372
     */
373
    var $expandedIcon;
374
 
375
    /**
376
     * The css class for this node
377
     */
378
    var $cssClass;
379
 
380
    /**
381
     * The link target for this node
382
     */
383
    var $linkTarget;
384
 
385
    /**#@-*/
386
 
387
    /**#@+
388
     * @access public
389
     */
390
 
391
    /**
392
     * Indexed array of subnodes
393
     * @var array
394
     */
395
    var $items;
396
 
397
    /**
398
     * Whether this node is expanded or not
399
     * @var bool
400
     */
401
    var $expanded;
402
 
403
    /**
404
     * Whether this node is dynamic or not
405
     * @var bool
406
     */
407
    var $isDynamic;
408
 
409
    /**
410
     * Should this node be made visible?
411
     * @var bool
412
     */
413
    var $ensureVisible;
414
 
415
    /**
416
     * The parent node. Null if top level
417
     * @var HTML_TreeNode
418
     */
419
    var $parent;
420
 
421
    /**
422
     * Javascript event handlers;
423
     * @var array
424
     */
425
    var $events;
426
 
427
    /**#@-*/
428
 
429
    /**
430
     * Constructor
431
     *
432
     * @param array $options An array of options which you can pass to change
433
     *                       the way this node looks/acts. This can consist of:
434
     *                       <pre>
435
     *                         o text          The title of the node,
436
     *                                         defaults to blank
437
     *                         o link          The link for the node,
438
     *                                         defaults to blank
439
     *                         o icon          The icon for the node,
440
     *                                         defaults to blank
441
     *                         o expandedIcon  The icon to show when the node
442
     *                                         is expanded
443
     *                         o cssClass      The CSS class for this node,
444
     *                                         defaults to blank
445
     *                         o expanded      The default expanded status of
446
     *                                         this node, defaults to false
447
     *                                         This doesn't affect non dynamic
448
     *                                         presentation types
449
     *                         o linkTarget    Target for the links.
450
     *                                         Defaults to linkTarget of the
451
     *                                         HTML_TreeMenu_Presentation.
452
     *                         o isDynamic     If this node is dynamic or not.
453
     *                                         Only affects certain
454
     *                                         presentation types.
455
     *                         o ensureVisible If true this node will be made
456
     *                                         visible despite the expanded
457
     *                                         settings, and client side
458
     *                                         persistence. Will not affect
459
     *                                         some presentation styles, such as
460
     *                                         Listbox.
461
     *                                         Default is false
462
     *                        </pre>
463
     * @param array $events  An array of javascript events and the
464
     *                       corresponding event handlers.
465
     *                       Additionally to the standard javascript events you
466
     *                       can specify handlers for the 'onexpand',
467
     *                       'oncollapse' and 'ontoggle' events which will be
468
     *                       fired whenever a node is collapsed and/or expanded.
469
     *
470
     * @access public
471
     */
472
    function HTML_TreeNode($options = array(), $events = array())
473
    {
474
        $this->text          = '';
475
        $this->link          = '';
476
        $this->icon          = '';
477
        $this->expandedIcon  = '';
478
        $this->cssClass      = '';
479
        $this->expanded      = false;
480
        $this->isDynamic     = true;
481
        $this->ensureVisible = false;
482
        $this->linkTarget    = null;
483
 
484
        $this->parent = null;
485
        $this->events = $events;
486
 
487
        foreach ($options as $option => $value) {
488
            $this->$option = $value;
489
        }
490
    }
491
 
492
    /**
493
     * Allows setting of various parameters after the initial constructor call
494
     *
495
     * Possible options you can set are:
496
     * <pre>
497
     *  o text
498
     *  o link
499
     *  o icon
500
     *  o cssClass
501
     *  o expanded
502
     *  o isDynamic
503
     *  o ensureVisible
504
     * </pre>
505
     *
506
     * NOTE:  The same options as in {@link HTML_TreeNode()}
507
     *
508
     * @param string $option Option to set
509
     * @param string $value  Value to set the option to
510
     *
511
     * @return void
512
     * @access public
513
     */
514
    function setOption($option, $value)
515
    {
516
        $this->$option = $value;
517
    }
518
 
519
    /**
520
     * Adds a new subnode to this node.
521
     *
522
     * @param HTML_TreeNode &$node The new node
523
     *
524
     * @return int
525
     * @access public
526
     */
527
    function &addItem(&$node)
528
    {
529
        $node->parent  = &$this;
530
        $this->items[] = &$node;
531
 
532
        /*
533
         * If the subnode has ensureVisible set it needs
534
         * to be handled, and all parents set accordingly.
535
         */
536
        if ($node->ensureVisible) {
537
            $this->_ensureVisible();
538
        }
539
 
540
        return $this->items[count($this->items) - 1];
541
    }
542
 
543
    /**
544
     * Private function to handle ensureVisible stuff
545
     *
546
     * @return void
547
     * @access private
548
     */
549
    function _ensureVisible()
550
    {
551
        $this->ensureVisible = true;
552
        $this->expanded      = true;
553
 
554
        if (!is_null($this->parent)) {
555
            $this->parent->_ensureVisible();
556
        }
557
    }
558
} // HTML_TreeNode
559
 
560
 
561
/**
562
 * HTML_TreeMenu_Presentation class
563
 *
564
 * Base class for other presentation classes to
565
 * inherit from.
566
 *
567
 * @category HTML
568
 * @package  HTML_TreeMenu
569
 * @author   Richard Heyes <richard@php.net>
570
 * @author   Harald Radi <harald.radi@nme.at>
571
 * @license  http://www.opensource.org/licenses/bsd-license.php  BSD License
572
 * @link     http://pear.php.net/package/HTML_TreeMenu
573
 */
574
class HTML_TreeMenu_Presentation
575
{
576
    /**
577
     * The TreeMenu structure
578
     * @var HTML_TreeMenu
579
     * @access public
580
     */
581
    var $menu;
582
 
583
    /**
584
     * Base constructor simply sets the menu object
585
     *
586
     * @param HTML_TreeMenu &$structure The menu structure
587
     */
588
    function HTML_TreeMenu_Presentation(&$structure)
589
    {
590
        $this->menu = &$structure;
591
    }
592
 
593
    /**
594
     * Prints the HTML generated by the toHTML() method.
595
     * toHTML() must therefore be defined by the derived
596
     * class.
597
     *
598
     * @param array $options Options to set. Any options taken by the
599
     *                       presentation class can be specified here.
600
     *
601
     * @return void
602
     * @access public
603
     */
604
    function printMenu($options = array())
605
    {
606
        foreach ($options as $option => $value) {
607
            $this->$option = $value;
608
        }
609
 
610
        echo $this->toHTML();
611
    }
612
}
613
 
614
 
615
/**
616
 * HTML_TreeMenu_DHTML class
617
 *
618
 * This class is a presentation class for the tree structure
619
 * created using the TreeMenu/TreeNode. It presents the
620
 * traditional tree, static for browsers that can't handle
621
 * the DHTML.
622
 *
623
 * @category HTML
624
 * @package  HTML_TreeMenu
625
 * @author   Richard Heyes <richard@php.net>
626
 * @author   Harald Radi <harald.radi@nme.at>
627
 * @license  http://www.opensource.org/licenses/bsd-license.php  BSD License
628
 * @link     http://pear.php.net/package/HTML_TreeMenu
629
 */
630
class HTML_TreeMenu_DHTML extends HTML_TreeMenu_Presentation
631
{
632
    /**#@+
633
     * @access public
634
     */
635
 
636
    /**
637
     * Dynamic status of the treemenu.
638
     * If true (default) this has no effect. If
639
     * false it will override all dynamic status vars and set the menu to be
640
     * fully expanded an non-dynamic.
641
     * @var bool
642
     */
643
    var $isDynamic;
644
 
645
    /**
646
     * Path to the images
647
     * @var string
648
     */
649
    var $images;
650
 
651
    /**
652
     * Target for the links generated
653
     * @var string
654
     */
655
    var $linkTarget;
656
 
657
    /**
658
     * Whether to use clientside persistence or not
659
     * @var bool
660
     */
661
    var $usePersistence;
662
 
663
    /**
664
     * The default CSS class for the nodes
665
     * @var string
666
     */
667
    var $defaultClass;
668
 
669
    /**
670
     * Whether to skip first level branch images
671
     * @var bool
672
     */
673
    var $noTopLevelImages;
674
 
675
    /**
676
     * Name of Jabbascript object to use
677
     * @var string
678
     */
679
    var $jsObjectName;
680
 
681
    /**#@-*/
682
 
683
    /**
684
     * Constructor
685
     *
686
     * Takes the tree structure as an argument and an array of options
687
     * which can consist of:
688
     * <pre>
689
     *  o images            -  The path to the images folder.
690
     *                         Defaults to "images"
691
     *  o linkTarget        -  The target for the link.
692
     *                         Defaults to "_self"
693
     *  o defaultClass      -  The default CSS class to apply to a node.
694
     *                         Default is none.
695
     *  o usePersistence    -  Whether to use clientside persistence. This
696
     *                         persistence is achieved using cookies.
697
     *                         Default is true.
698
     *  o noTopLevelImages  -  Whether to skip displaying the first level of
699
     *                         images if there is multiple top level branches.
700
     *  o maxDepth          -  The maximum depth of indentation. Useful for
701
     *                         ensuring deeply nested trees don't go way off to
702
     *                         the right of your page etc.
703
     *                         Defaults to no limit.
704
     *  o jsObjectName      -  Name to use for jabbascript object. Set this if
705
     *                         you have different menus that should maintain
706
     *                         their persistence information separately.
707
     * </pre>
708
     *
709
     * And also a boolean for whether the entire tree is dynamic or not.
710
     * This overrides any perNode dynamic settings.
711
     *
712
     * @param HTML_TreeMenu &$structure The menu structure
713
     * @param array         $options    Array of options
714
     * @param bool          $isDynamic  Whether the tree is dynamic or not
715
     *
716
     * @access public
717
     */
718
    function HTML_TreeMenu_DHTML(&$structure, $options = array(), $isDynamic = true)
719
    {
720
        $this->HTML_TreeMenu_Presentation($structure);
721
        $this->isDynamic = $isDynamic;
722
 
723
        // Defaults
724
        $this->images           = 'images';
725
        $this->maxDepth         = 0;        // No limit
726
        $this->linkTarget       = '_self';
727
        $this->jsObjectName     = 'objTreeMenu';
728
        $this->defaultClass     = '';
729
        $this->usePersistence   = true;
730
        $this->noTopLevelImages = false;
731
 
732
        foreach ($options as $option => $value) {
733
            $this->$option = $value;
734
        }
735
    }
736
 
737
    /**
738
     * Returns the HTML for the menu.
739
     *
740
     * This method can be used instead of
741
     * {@link HTML_TreeMenu_Presentation::printMenu()}
742
     * to use the menu system with a template system.
743
     *
744
     * @return string The HTML for the menu
745
     * @access public
746
     */
747
    function toHTML()
748
    {
749
        static $count = 0;
750
 
751
        $menuObj = $this->jsObjectName . '_' . ++$count;
752
 
753
        $html  = "\n";
754
        $html .= '<script type="text/javascript">' . "\n//<![CDATA[\n\t";
755
        $html .= sprintf('%s = new TreeMenu("%s", "%s", "%s", "%s", %s, %s);',
756
                         $menuObj,
757
                         $this->images,
758
                         $menuObj,
759
                         $this->linkTarget,
760
                         $this->defaultClass,
761
                         $this->usePersistence ? 'true' : 'false',
762
                         $this->noTopLevelImages ? 'true' : 'false');
763
 
764
        $html .= "\n";
765
 
766
        /*
767
         * Loop through subnodes
768
         */
769
        if (isset($this->menu->items)) {
770
            for ($i=0; $i<count($this->menu->items); $i++) {
771
                $html .= $this->_nodeToHTML($this->menu->items[$i], $menuObj);
772
            }
773
        }
774
 
775
        $html .= sprintf("\n\t%s.drawMenu();", $menuObj);
776
        $html .= sprintf("\n\t%s.writeOutput();", $menuObj);
777
 
778
        if ($this->usePersistence && $this->isDynamic) {
779
            $html .= sprintf("\n\t%s.resetBranches();", $menuObj);
780
        }
781
        $html .= "\n// ]]>\n</script>";
782
 
783
        return $html;
784
    }
785
 
786
    /**
787
     * Prints a node of the menu
788
     *
789
     * @param HTML_TreeNode $nodeObj        node object
790
     * @param mixed         $prefix         prefix
791
     * @param string        $return         default to 'newNode'
792
     * @param int           $currentDepth   default to 0
793
     * @param mixed         $maxDepthPrefix default to null
794
     *
795
     * @return string
796
     * @access private
797
     */
798
    function _nodeToHTML($nodeObj,
799
                         $prefix,
800
                         $return         = 'newNode',
801
                         $currentDepth   = 0,
802
                         $maxDepthPrefix = null)
803
    {
804
        $prefix = empty($maxDepthPrefix) ? $prefix : $maxDepthPrefix;
805
 
806
        $expanded  = $this->isDynamic ?
807
                        ($nodeObj->expanded  ? 'true' : 'false') : 'true';
808
        $isDynamic = $this->isDynamic ?
809
                        ($nodeObj->isDynamic ? 'true' : 'false') : 'false';
810
        $html      = sprintf("\t %s = %s.addItem(new TreeNode" .
811
                        "('%s', %s, %s, %s, %s, '%s', '%s', %s));\n",
812
                        $return,
813
                        $prefix,
814
                        str_replace("'", "\\'", $nodeObj->text),
815
                        !empty($nodeObj->icon) ? "'" . $nodeObj->icon . "'" : 'null',
816
                        !empty($nodeObj->link) ? "'" . $nodeObj->link . "'" : 'null',
817
                        $expanded,
818
                        $isDynamic,
819
                        $nodeObj->cssClass,
820
                        $nodeObj->linkTarget,
821
                        !empty($nodeObj->expandedIcon) ?
822
                            "'" . $nodeObj->expandedIcon . "'" : 'null');
823
 
824
        foreach ($nodeObj->events as $event => $handler) {
825
            $html .= sprintf("\t %s.setEvent('%s', '%s');\n",
826
                             $return,
827
                             $event,
828
                             str_replace(array("\r", "\n", "'"),
829
                                array('\r', '\n', "\'"),
830
                             $handler));
831
        }
832
 
833
        if ($this->maxDepth > 0 AND $currentDepth == $this->maxDepth) {
834
            $maxDepthPrefix = $prefix;
835
        }
836
 
837
        /*
838
         * Loop through subnodes
839
         */
840
        if (!empty($nodeObj->items)) {
841
            for ($i=0; $i<count($nodeObj->items); $i++) {
842
                $html .= $this->_nodeToHTML($nodeObj->items[$i],
843
                                            $return,
844
                                            $return . '_' . ($i + 1),
845
                                            $currentDepth + 1,
846
                                            $maxDepthPrefix);
847
            }
848
        }
849
 
850
        return $html;
851
    }
852
} // End class HTML_TreeMenu_DHTML
853
 
854
 
855
/**
856
 * HTML_TreeMenu_Listbox class
857
 *
858
 * This class presents the menu as a listbox
859
 *
860
 * @category HTML
861
 * @package  HTML_TreeMenu
862
 * @author   Richard Heyes <richard@php.net>
863
 * @author   Harald Radi <harald.radi@nme.at>
864
 * @license  http://www.opensource.org/licenses/bsd-license.php  BSD License
865
 * @link     http://pear.php.net/package/HTML_TreeMenu
866
 */
867
class HTML_TreeMenu_Listbox extends HTML_TreeMenu_Presentation
868
{
869
    /**#@+
870
     * @access public
871
     */
872
 
873
    /**
874
     * The text that is displayed in the first option
875
     * @var string
876
     */
877
    var $promoText;
878
 
879
    /**
880
     * The character used for indentation
881
     * @var string
882
     */
883
    var $indentChar;
884
 
885
    /**
886
     * How many of the indent chars to use per indentation level
887
     * @var int
888
     */
889
    var $indentNum;
890
 
891
    /**
892
     * Target for the links generated
893
     * @var string
894
     */
895
    var $linkTarget;
896
 
897
    /**#@-*/
898
 
899
    /**
900
     * Constructor
901
     *
902
     * @param object $structure The menu structure
903
     * @param array  $options   Options which affect the display of the listbox.
904
     *                          These can consist of:
905
     *                          <pre>
906
     *                           o promoText  The text that appears at the the
907
     *                                        top of the listbox
908
     *                                        Defaults to "Select..."
909
     *                           o indentChar The character to use for indenting
910
     *                                        the nodes
911
     *                                        Defaults to "&nbsp;"
912
     *                           o indentNum  How many of the indentChars to use
913
     *                                        per indentation level
914
     *                                        Defaults to 2
915
     *                           o linkTarget Target for the links.
916
     *                                        Defaults to "_self"
917
     *                           o submitText Text for the submit button.
918
     *                                        Defaults to "Go"
919
     *                           </pre>
920
     *
921
     * @access public
922
     */
923
    function HTML_TreeMenu_Listbox($structure, $options = array())
924
    {
925
        $this->HTML_TreeMenu_Presentation($structure);
926
 
927
        $this->promoText  = 'Select...';
928
        $this->indentChar = '&nbsp;';
929
        $this->indentNum  = 2;
930
        $this->linkTarget = '_self';
931
        $this->submitText = 'Go';
932
 
933
        foreach ($options as $option => $value) {
934
            $this->$option = $value;
935
        }
936
    }
937
 
938
    /**
939
     * Returns the HTML generated
940
     *
941
     * @return string
942
     * @access public
943
     */
944
    function toHTML()
945
    {
946
        static $count = 0;
947
 
948
        $nodeHTML = '';
949
 
950
        /*
951
         * Loop through subnodes
952
         */
953
        if (isset($this->menu->items)) {
954
            for ($i=0; $i<count($this->menu->items); $i++) {
955
                $nodeHTML .= $this->_nodeToHTML($this->menu->items[$i]);
956
            }
957
        }
958
 
959
        return sprintf('<form target="%s" action="" onsubmit="var link = ' .
960
                       'this.%s.options[this.%s.selectedIndex].value; ' .
961
                       'if (link) {this.action = link; return true} else ' .
962
                       'return false"><select name="%s">' .
963
                       '<option value="">%s</option>%s</select> ' .
964
                       '<input type="submit" value="%s" /></form>',
965
                       $this->linkTarget,
966
                       'HTML_TreeMenu_Listbox_' . ++$count,
967
                       'HTML_TreeMenu_Listbox_' . $count,
968
                       'HTML_TreeMenu_Listbox_' . $count,
969
                       $this->promoText,
970
                       $nodeHTML,
971
                       $this->submitText);
972
    }
973
 
974
    /**
975
     * Returns HTML for a single node
976
     *
977
     * @param HTML_TreeNode $node   node
978
     * @param string        $prefix defaults to empty string
979
     *
980
     * @return string
981
     * @access private
982
     */
983
    function _nodeToHTML($node, $prefix = '')
984
    {
985
        $html = sprintf('<option value="%s">%s%s</option>',
986
                        $node->link,
987
                        $prefix,
988
                        $node->text);
989
 
990
        /*
991
         * Loop through subnodes
992
         */
993
        if (isset($node->items)) {
994
            for ($i=0; $i<count($node->items); $i++) {
995
                $html .= $this->_nodeToHTML($node->items[$i],
996
                    $prefix . str_repeat($this->indentChar,
997
                    $this->indentNum));
998
            }
999
        }
1000
 
1001
        return $html;
1002
    }
1003
} // End class HTML_TreeMenu_Listbox
1004
?>