home *** CD-ROM | disk | FTP | other *** search
/ Enter 2004 June / ENTER.ISO / files / xampp-win32-1.4.5-installer.exe / xampp / TreeMenu.php < prev    next >
Encoding:
PHP Script  |  2004-03-24  |  18.8 KB  |  598 lines

  1. <?php
  2. // +-----------------------------------------------------------------------+
  3. // | Copyright (c) 2002, Richard Heyes, Harald Radi                        |
  4. // | All rights reserved.                                                  |
  5. // |                                                                       |
  6. // | Redistribution and use in source and binary forms, with or without    |
  7. // | modification, are permitted provided that the following conditions    |
  8. // | are met:                                                              |
  9. // |                                                                       |
  10. // | o Redistributions of source code must retain the above copyright      |
  11. // |   notice, this list of conditions and the following disclaimer.       |
  12. // | o Redistributions in binary form must reproduce the above copyright   |
  13. // |   notice, this list of conditions and the following disclaimer in the |
  14. // |   documentation and/or other materials provided with the distribution.| 
  15. // | o The names of the authors may not be used to endorse or promote      |
  16. // |   products derived from this software without specific prior written  |
  17. // |   permission.                                                         |
  18. // |                                                                       |
  19. // | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS   |
  20. // | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT     |
  21. // | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
  22. // | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT  |
  23. // | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
  24. // | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT      |
  25. // | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
  26. // | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
  27. // | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT   |
  28. // | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
  29. // | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  |
  30. // |                                                                       |
  31. // +-----------------------------------------------------------------------+
  32. // | Author: Richard Heyes <richard@phpguru.org>                           |
  33. // |         Harald Radi <harald.radi@nme.at>                              |
  34. // +-----------------------------------------------------------------------+
  35. //
  36. // $Id: TreeMenu.php,v 1.2 2003/02/02 07:44:24 CelloG Exp $
  37.  
  38. /**
  39. * @package HTML_TreeMenu
  40. */
  41. /**
  42. * HTML_TreeMenu Class
  43. *
  44. * A simple couple of PHP classes and some not so simple
  45. * Jabbascript which produces a tree menu. In IE this menu
  46. * is dynamic, with branches being collapsable. In IE5+ the
  47. * status of the collapsed/open branches persists across page
  48. * refreshes.In any other browser the tree is static. Code is
  49. * based on work of Harald Radi.
  50. *
  51. * Usage.
  52. *
  53. * After installing the package, copy the example php script to
  54. * your servers document root. Also place the TreeMenu.js and the
  55. * images folder in the same place. Running the script should
  56. * then produce the tree.
  57. *
  58. * Thanks go to Chip Chapin (http://www.chipchapin.com) for many
  59. * excellent ideas and improvements.
  60. *
  61. * @author  Richard Heyes <richard@php.net>
  62. * @author  Harald Radi <harald.radi@nme.at>
  63. * @access  public
  64. * @package HTML_TreeMenu
  65. */
  66.  
  67. class HTML_TreeMenu
  68. {
  69.     /**
  70.     * Indexed array of subnodes
  71.     * @var array
  72.     */
  73.     var $items;
  74.  
  75.     /**
  76.     * Constructor
  77.     *
  78.     * @access public
  79.     */
  80.     function HTML_TreeMenu()
  81.     {
  82.         // Not much to do here :(
  83.     }
  84.  
  85.     /**
  86.     * This function adds an item to the the tree.
  87.     *
  88.     * @access public
  89.     * @param  object $node The node to add. This object should be
  90.     *                      a HTML_TreeNode object.
  91.     * @return object       Returns a reference to the new node inside
  92.     *                      the tree.
  93.     */
  94.     function &addItem(&$node)
  95.     {
  96.         $this->items[] = &$node;
  97.         return $this->items[count($this->items) - 1];
  98.     }
  99. } // HTML_TreeMenu
  100.  
  101.  
  102. /**
  103. * HTML_TreeNode class
  104. * This class is supplementary to the above and provides a way to
  105. * add nodes to the tree. A node can have other nodes added to it. 
  106. *
  107. * @author  Richard Heyes <richard@php.net>
  108. * @author  Harald Radi <harald.radi@nme.at>
  109. * @access  public
  110. * @package HTML_TreeMenu
  111. */
  112. class HTML_TreeNode
  113. {
  114.     /**
  115.     * The text for this node.
  116.     * @var string
  117.     */
  118.     var $text;
  119.  
  120.     /**
  121.     * The link for this node.
  122.     * @var string
  123.     */
  124.     var $link;
  125.  
  126.     /**
  127.     * The icon for this node.
  128.     * @var string
  129.     */
  130.     var $icon;
  131.     
  132.     /**
  133.     * The css class for this node
  134.     * @var string
  135.     */
  136.     var $cssClass;
  137.  
  138.     /**
  139.     * Indexed array of subnodes
  140.     * @var array
  141.     */
  142.     var $items;
  143.  
  144.     /**
  145.     * Whether this node is expanded or not
  146.     * @var bool
  147.     */
  148.     var $expanded;
  149.     
  150.     /**
  151.     * Whether this node is dynamic or not
  152.     * @var bool
  153.     */
  154.     var $isDynamic;
  155.     
  156.     /**
  157.     * Should this node be made visible?
  158.     * @var bool
  159.     */
  160.     var $ensureVisible;
  161.     
  162.     /**
  163.     * The parent node. Null if top level
  164.     * @var object
  165.     */
  166.     var $parent;
  167.  
  168.     /**
  169.     * Javascript event handlers;
  170.     * @var array
  171.     */
  172.     var $events;
  173.  
  174.     /**
  175.     * Constructor
  176.     *
  177.     * @access public
  178.     * @param  array $options An array of options which you can pass to change
  179.     *                        the way this node looks/acts. This can consist of:
  180.     *                         o text          The title of the node, defaults to blank
  181.     *                         o link          The link for the node, defaults to blank
  182.     *                         o icon          The icon for the node, defaults to blank
  183.     *                         o class         The CSS class for this node, defaults to blank
  184.     *                         o expanded      The default expanded status of this node, defaults to false
  185.     *                                         This doesn't affect non dynamic presentation types
  186.     *                         o isDynamic     If this node is dynamic or not. Only affects
  187.     *                                         certain presentation types.
  188.     *                         o ensureVisible If true this node will be made visible despite the expanded
  189.     *                                         settings, and client side persistence. Will not affect
  190.     *                                         some presentation styles, such as Listbox. Default is false
  191.     * @param  array $events An array of javascript events and the corresponding event handlers.
  192.     *                       Additionally to the standard javascript events you can specify handlers
  193.     *                       for the 'onexpand', 'oncollapse' and 'ontoggle' events which will be fired
  194.     *                       whenever a node is collapsed and/or expanded.
  195.     */
  196.     function HTML_TreeNode($options = array(), $events = array())
  197.     {
  198.         $this->text          = '';
  199.         $this->link          = '';
  200.         $this->icon          = '';
  201.         $this->cssClass      = '';
  202.         $this->expanded      = false;
  203.         $this->isDynamic     = true;
  204.         $this->ensureVisible = false;
  205.  
  206.         $this->parent        = null;
  207.         $this->events        = $events;
  208.         
  209.         foreach ($options as $option => $value) {
  210.             $this->$option = $value;
  211.         }
  212.     }
  213.  
  214.     /**
  215.     * Allows setting of various parameters after the initial
  216.     * constructor call. Possible options you can set are:
  217.     *  o text
  218.     *  o link
  219.     *  o icon
  220.     *  o cssClass
  221.     *  o expanded
  222.     *  o isDynamic
  223.     *  o ensureVisible
  224.     * ie The same options as in the constructor
  225.     *
  226.     * @access public
  227.     * @param  string $option Option to set
  228.     * @param  string $value  Value to set the option to
  229.     */
  230.     function setOption($option, $value)
  231.     {
  232.         $this->$option = $value;
  233.     }
  234.  
  235.     /**
  236.     * Adds a new subnode to this node.
  237.     *
  238.     * @access public
  239.     * @param  object $node The new node
  240.     */
  241.     function &addItem(&$node)
  242.     {
  243.         $node->parent  = &$this;
  244.         $this->items[] = &$node;
  245.         
  246.         /**
  247.         * If the subnode has ensureVisible set it needs
  248.         * to be handled, and all parents set accordingly.
  249.         */
  250.         if ($node->ensureVisible) {
  251.             $this->_ensureVisible();
  252.         }
  253.  
  254.         return $this->items[count($this->items) - 1];
  255.     }
  256.     
  257.     /**
  258.     * Private function to handle ensureVisible stuff
  259.     *
  260.     * @access private
  261.     */
  262.     function _ensureVisible()
  263.     {
  264.         $this->ensureVisible = true;
  265.         $this->expanded      = true;
  266.  
  267.         if (!is_null($this->parent)) {
  268.             $this->parent->_ensureVisible();
  269.         }
  270.     }
  271. } // HTML_TreeNode
  272.  
  273.  
  274. /**
  275. * HTML_TreeMenu_Presentation class
  276. * Base class for other presentation classes to
  277. * inherit from.
  278. * @package HTML_TreeMenu
  279. */
  280. class HTML_TreeMenu_Presentation
  281. {
  282.     /**
  283.     * The TreeMenu structure
  284.     * @var object
  285.     */
  286.     var $menu;
  287.  
  288.     /**
  289.     * Base constructor simply sets the menu object
  290.     *
  291.     * @param object $structure The menu structure
  292.     */
  293.     function HTML_TreeMenu_Presentation(&$structure)
  294.     {
  295.         $this->menu = &$structure;
  296.     }
  297.  
  298.     /**
  299.     * Prints the HTML generated by the toHTML() method.
  300.     * toHTML() must therefore be defined by the derived
  301.     * class.
  302.     *
  303.     * @access public
  304.     * @param  array  Options to set. Any options taken by
  305.     *                the presentation class can be specified
  306.     *                here.
  307.     */
  308.     function printMenu($options = array())
  309.     {
  310.         foreach ($options as $option => $value) {
  311.             $this->$option = $value;
  312.         }
  313.  
  314.         echo $this->toHTML();
  315.     }
  316. }
  317.  
  318. /**
  319. * HTML_TreeMenu_DHTML class
  320. *
  321. * This class is a presentation class for the tree structure
  322. * created using the TreeMenu/TreeNode. It presents the 
  323. * traditional tree, static for browsers that can't handle
  324. * the DHTML.
  325. * @package HTML_TreeMenu
  326. */
  327. class HTML_TreeMenu_DHTML extends HTML_TreeMenu_Presentation
  328. {
  329.     /**
  330.     * Dynamic status of the treemenu. If true (default) this has no effect. If
  331.     * false it will override all dynamic status vars and set the menu to be
  332.     * fully expanded an non-dynamic.
  333.     */
  334.     var $isDynamic;
  335.  
  336.     /**
  337.     * Path to the images
  338.     * @var string
  339.     */
  340.     var $images;
  341.     
  342.     /**
  343.     * Target for the links generated
  344.     * @var string
  345.     */
  346.     var $linkTarget;
  347.     
  348.     /**
  349.     * Whether to use clientside persistence or not
  350.     * @var bool
  351.     */
  352.     var $userPersistence;
  353.     
  354.     /**
  355.     * The default CSS class for the nodes
  356.     */
  357.     var $defaultClass;
  358.     
  359.     /**
  360.     * Whether to skip first level branch images
  361.     * @var bool
  362.     */
  363.     var $noTopLevelImages;
  364.  
  365.     /**
  366.     * Constructor, takes the tree structure as
  367.     * an argument and an array of options which
  368.     * can consist of:
  369.     *  o images            -  The path to the images folder. Defaults to "images"
  370.     *  o linkTarget        -  The target for the link. Defaults to "_self"
  371.     *  o defaultClass      -  The default CSS class to apply to a node. Default is none.
  372.     *  o usePersistence    -  Whether to use clientside persistence. This persistence
  373.     *                         is achieved using cookies. Default is true.
  374.     *  o noTopLevelImages  -  Whether to skip displaying the first level of images if
  375.     *                         there is multiple top level branches.
  376.     *
  377.     * And also a boolean for whether the entire tree is dynamic or not.
  378.     * This overrides any perNode dynamic settings.
  379.     *
  380.     * @param object $structure The menu structure
  381.     * @param array  $options   Array of options
  382.     * @param bool   $isDynamic Whether the tree is dynamic or not
  383.     */
  384.     function HTML_TreeMenu_DHTML(&$structure, $options = array(), $isDynamic = true)
  385.     {
  386.         $this->menu      = &$structure;
  387.         $this->isDynamic = $isDynamic;
  388.  
  389.         // Defaults
  390.         $this->images           = 'images';
  391.         $this->linkTarget       = '_self';
  392.         $this->defaultClass     = '';
  393.         $this->usePersistence   = true;
  394.         $this->noTopLevelImages = false;
  395.  
  396.         foreach ($options as $option => $value) {
  397.             $this->$option = $value;
  398.         }
  399.     }
  400.  
  401.     /**
  402.     * Returns the HTML for the menu. This method can be
  403.     * used instead of printMenu() to use the menu system
  404.     * with a template system.
  405.     *
  406.     * @access public
  407.     * @return string The HTML for the menu
  408.     */    
  409.     function toHTML()
  410.     {
  411.         static $count = 0;
  412.         $menuObj = 'objTreeMenu_' . ++$count;
  413.  
  414.         $html  = "\n";
  415.         $html .= '<script language="javascript" type="text/javascript">' . "\n\t";
  416.         $html .= sprintf('%s = new TreeMenu("%s", "%s", "%s", "%s", %s, %s);',
  417.                          $menuObj,
  418.                          $this->images,
  419.                          $menuObj,
  420.                          $this->linkTarget,
  421.                          $this->defaultClass,
  422.                          $this->usePersistence ? 'true' : 'false',
  423.                          $this->noTopLevelImages ? 'true' : 'false');
  424.  
  425.         $html .= "\n";
  426.  
  427.         /**
  428.         * Loop through subnodes
  429.         */
  430.         if (isset($this->menu->items)) {
  431.             for ($i=0; $i<count($this->menu->items); $i++) {
  432.                 $html .= $this->_nodeToHTML($this->menu->items[$i], $menuObj);
  433.             }
  434.         }
  435.  
  436.          $html .= sprintf("\n\t%s.drawMenu();", $menuObj);
  437.         if ($this->usePersistence && $this->isDynamic) {
  438.             $html .= sprintf("\n\t%s.resetBranches();", $menuObj);
  439.         }
  440.         $html .= "\n</script>";
  441.  
  442.         return $html;
  443.     }
  444.     
  445.     /**
  446.     * Prints a node of the menu
  447.     *
  448.     * @access private
  449.     */
  450.     function _nodeToHTML($nodeObj, $prefix, $return = 'newNode')
  451.     {
  452.         $expanded  = $this->isDynamic ? ($nodeObj->expanded  ? 'true' : 'false') : 'true';
  453.         $isDynamic = $this->isDynamic ? ($nodeObj->isDynamic ? 'true' : 'false') : 'false';
  454.         $html = sprintf("\t %s = %s.addItem(new TreeNode('%s', %s, %s, %s, %s, '%s'));\n",
  455.                         $return,
  456.                         $prefix,
  457.                         $nodeObj->text,
  458.                         !empty($nodeObj->icon) ? "'" . $nodeObj->icon . "'" : 'null',
  459.                         !empty($nodeObj->link) ? "'" . addslashes($nodeObj->link) . "'" : 'null',
  460.                         $expanded,
  461.                         $isDynamic,
  462.                         $nodeObj->cssClass);
  463.  
  464.         foreach ($nodeObj->events as $event => $handler) {
  465.             $html .= sprintf("\t %s.setEvent('%s', '%s');\n",
  466.                              $return,
  467.                              $event,
  468.                              str_replace(array("\r", "\n", "'"), array('\r', '\n', "\'"), $handler));
  469.         }
  470.  
  471.         /**
  472.         * Loop through subnodes
  473.         */
  474.         if (!empty($nodeObj->items)) {
  475.             for ($i=0; $i<count($nodeObj->items); $i++) {
  476.                 $html .= $this->_nodeToHTML($nodeObj->items[$i], $return, $return . '_' . ($i + 1));
  477.             }
  478.         }
  479.  
  480.         return $html;
  481.     }
  482. }
  483.  
  484.  
  485. /**
  486. * HTML_TreeMenu_Listbox class
  487. * This class presents the menu as a listbox
  488. * @package HTML_TreeMenu
  489. */
  490. class HTML_TreeMenu_Listbox extends HTML_TreeMenu_Presentation
  491. {
  492.     /**
  493.     * The text that is displayed in the first option
  494.     * @var string
  495.     */
  496.     var $promoText;
  497.     
  498.     /**
  499.     * The character used for indentation
  500.     * @var string
  501.     */
  502.     var $indentChar;
  503.     
  504.     /**
  505.     * How many of the indent chars to use
  506.     * per indentation level
  507.     * @var integer
  508.     */
  509.     var $indentNum;
  510.     
  511.     /**
  512.     * Target for the links generated
  513.     * @var string
  514.     */
  515.     var $linkTarget;
  516.  
  517.     /**
  518.     * Constructor
  519.     *
  520.     * @param object $structure The menu structure
  521.     * @param array  $options   Options whic affect the display of the listbox.
  522.     *                          These can consist of:
  523.     *                           o promoText  The text that appears at the the top of the listbox
  524.     *                                        Defaults to "Select..."
  525.     *                           o indentChar The character to use for indenting the nodes
  526.     *                                        Defaults to " "
  527.     *                           o indentNum  How many of the indentChars to use per indentation level
  528.     *                                        Defaults to 2
  529.     *                           o linkTarget Target for the links. Defaults to "_self"
  530.     *                           o submitText Text for the submit button. Defaults to "Go"
  531.     */
  532.     function HTML_TreeMenu_Listbox($structure, $options = array())
  533.     {
  534.         $this->menu       = $structure;
  535.         $this->promoText  = 'Select...';
  536.         $this->indentChar = ' ';
  537.         $this->indentNum  = 2;
  538.         $this->linkTarget = '_self';
  539.         $this->submitText = 'Go';
  540.         
  541.         foreach ($options as $option => $value) {
  542.             $this->$option = $value;
  543.         }
  544.     }
  545.  
  546.     /**
  547.     * Returns the HTML generated
  548.     */
  549.     function toHTML()
  550.     {
  551.         static $count = 0;
  552.         $nodeHTML = '';
  553.  
  554.         /**
  555.         * Loop through subnodes
  556.         */
  557.         if (isset($this->menu->items)) {
  558.             for ($i=0; $i<count($this->menu->items); $i++) {
  559.                 $nodeHTML .= $this->_nodeToHTML($this->menu->items[$i]);
  560.             }
  561.         }
  562.  
  563.         return sprintf('<form target="%s" action="" onsubmit="var link = this.%s.options[this.%s.selectedIndex].value; if (link) {this.action = link; return true} else return false"><select name="%s"><option value="">%s</option>%s</select> <input type="submit" value="%s" /></form>',
  564.                        $this->linkTarget,
  565.                        'HTML_TreeMenu_Listbox_' . ++$count,
  566.                        'HTML_TreeMenu_Listbox_' . $count,
  567.                        'HTML_TreeMenu_Listbox_' . $count,
  568.                        $this->promoText,
  569.                        $nodeHTML,
  570.                        $this->submitText);
  571.     }
  572.     
  573.     /**
  574.     * Returns HTML for a single node
  575.     * 
  576.     * @access private
  577.     */
  578.     function _nodeToHTML($node, $prefix = '')
  579.     {
  580.         $html = sprintf('<option value="%s">%s%s</option>', $node->link, $prefix, $node->text);
  581.         
  582.         /**
  583.         * Loop through subnodes
  584.         */
  585.         if (isset($node->items)) {
  586.             for ($i=0; $i<count($node->items); $i++) {
  587.                 $html .= $this->_nodeToHTML($node->items[$i], $prefix . str_repeat($this->indentChar, $this->indentNum));
  588.             }
  589.         }
  590.         
  591.         return $html;
  592.     }
  593. }
  594. ?>
  595.