1: <?php
2: // $Id: tree.php,v 1.2 2008/06/22 11:36:07 minahito Exp $
3: // ------------------------------------------------------------------------ //
4: // XOOPS - PHP Content Management System //
5: // Copyright (c) 2000 XOOPS.org //
6: // <http://www.xoops.org/> //
7: // ------------------------------------------------------------------------ //
8: // This program is free software; you can redistribute it and/or modify //
9: // it under the terms of the GNU General Public License as published by //
10: // the Free Software Foundation; either version 2 of the License, or //
11: // (at your option) any later version. //
12: // //
13: // You may not change or alter any portion of this comment or credits //
14: // of supporting developers from this source code or any supporting //
15: // source code which is considered copyrighted (c) material of the //
16: // original comment or credit authors. //
17: // //
18: // This program is distributed in the hope that it will be useful, //
19: // but WITHOUT ANY WARRANTY; without even the implied warranty of //
20: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
21: // GNU General Public License for more details. //
22: // //
23: // You should have received a copy of the GNU General Public License //
24: // along with this program; if not, write to the Free Software //
25: // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA //
26: // ------------------------------------------------------------------------ //
27: // Author: Kazumi Ono (AKA onokazu) //
28: // URL: http://www.xoops.org/ http://jp.xoops.org/ http://www.myweb.ne.jp/ //
29: // Project: The XOOPS Project (http://www.xoops.org/) //
30: // ------------------------------------------------------------------------- //
31:
32: /**
33: * A tree structures with {@link XoopsObject}s as nodes
34: *
35: * @package kernel
36: * @subpackage core
37: *
38: * @author Kazumi Ono <onokazu@xoops.org>
39: * @copyright (c) 2000-2003 The Xoops Project - www.xoops.org
40: */
41: class XoopsObjectTree {
42:
43: /**#@+
44: * @access private
45: */
46: var $_parentId;
47: var $_myId;
48: var $_rootId = null;
49: var $_tree = array();
50: var $_objects;
51: /**#@-*/
52:
53: /**
54: * Constructor
55: *
56: * @param array $objectArr Array of {@link XoopsObject}s
57: * @param string $myId field name of object ID
58: * @param string $parentId field name of parent object ID
59: * @param string $rootId field name of root object ID
60: **/
61: function XoopsObjectTree(&$objectArr, $myId, $parentId, $rootId = null)
62: {
63: $this->_objects =& $objectArr;
64: $this->_myId = $myId;
65: $this->_parentId = $parentId;
66: if (isset($rootId)) {
67: $this->_rootId = $rootId;
68: }
69: $this->_initialize();
70: }
71:
72: /**
73: * Initialize the object
74: *
75: * @access private
76: **/
77: function _initialize()
78: {
79: foreach (array_keys($this->_objects) as $i) {
80: $key1 = $this->_objects[$i]->getVar($this->_myId);
81: $this->_tree[$key1]['obj'] =& $this->_objects[$i];
82: $key2 = $this->_objects[$i]->getVar($this->_parentId);
83: $this->_tree[$key1]['parent'] = $key2;
84: $this->_tree[$key2]['child'][] = $key1;
85: if (isset($this->_rootId)) {
86: $this->_tree[$key1]['root'] = $this->_objects[$i]->getVar($this->_rootId);
87: }
88: }
89: }
90:
91: /**
92: * Get the tree
93: *
94: * @return array Associative array comprising the tree
95: **/
96: function &getTree()
97: {
98: return $this->_tree;
99: }
100:
101: /**
102: * returns an object from the tree specified by its id
103: *
104: * @param string $key ID of the object to retrieve
105: * @return object Object within the tree
106: **/
107: function &getByKey($key)
108: {
109: return $this->_tree[$key]['obj'];
110: }
111:
112: /**
113: * returns an array of all the first child object of an object specified by its id
114: *
115: * @param string $key ID of the parent object
116: * @return array Array of children of the parent
117: **/
118: function &getFirstChild($key)
119: {
120: $ret = array();
121: if (isset($this->_tree[$key]['child'])) {
122: foreach ($this->_tree[$key]['child'] as $childkey) {
123: $ret[$childkey] =& $this->_tree[$childkey]['obj'];
124: }
125: }
126: return $ret;
127: }
128:
129: /**
130: * returns an array of all child objects of an object specified by its id
131: *
132: * @param string $key ID of the parent
133: * @param array $ret (Empty when called from client) Array of children from previous recursions.
134: * @return array Array of child nodes.
135: **/
136: function &getAllChild($key, $ret = array())
137: {
138: if (isset($this->_tree[$key]['child'])) {
139: foreach ($this->_tree[$key]['child'] as $childkey) {
140: $ret[$childkey] =& $this->_tree[$childkey]['obj'];
141: $children =& $this->getAllChild($childkey, $ret);
142: foreach (array_keys($children) as $newkey) {
143: $ret[$newkey] =& $children[$newkey];
144: }
145: }
146: }
147: return $ret;
148: }
149:
150: /**
151: * returns an array of all parent objects.
152: * the key of returned array represents how many levels up from the specified object
153: *
154: * @param string $key ID of the child object
155: * @param array $ret (empty when called from outside) Result from previous recursions
156: * @param int $uplevel (empty when called from outside) level of recursion
157: * @return array Array of parent nodes.
158: **/
159: function &getAllParent($key, $ret = array(), $uplevel = 1)
160: {
161: if (isset($this->_tree[$key]['parent']) && isset($this->_tree[$this->_tree[$key]['parent']]['obj'])) {
162: $ret[$uplevel] =& $this->_tree[$this->_tree[$key]['parent']]['obj'];
163: $parents =& $this->getAllParent($this->_tree[$key]['parent'], $ret, $uplevel+1);
164: foreach (array_keys($parents) as $newkey) {
165: $ret[$newkey] =& $parents[$newkey];
166: }
167: }
168: return $ret;
169: }
170:
171: /**
172: * Make options for a select box from
173: *
174: * @param string $fieldName Name of the member variable from the
175: * node objects that should be used as the title for the options.
176: * @param string $selected Value to display as selected
177: * @param int $key ID of the object to display as the root of select options
178: * @param string $ret (reference to a string when called from outside) Result from previous recursions
179: * @param string $prefix_orig String to indent items at deeper levels
180: * @param string $prefix_curr String to indent the current item
181: * @return
182: *
183: * @access private
184: **/
185: function _makeSelBoxOptions($fieldName, $selected, $key, &$ret, $prefix_orig, $prefix_curr = '')
186: {
187: if ($key > 0) {
188: $value = $this->_tree[$key]['obj']->getVar($this->_myId);
189: $ret .= '<option value="'.$value.'"';
190: if ($value == $selected) {
191: $ret .= ' selected="selected"';
192: }
193: $ret .= '>'.$prefix_curr.$this->_tree[$key]['obj']->getVar($fieldName).'</option>';
194: $prefix_curr .= $prefix_orig;
195: }
196: if (isset($this->_tree[$key]['child']) && !empty($this->_tree[$key]['child'])) {
197: foreach ($this->_tree[$key]['child'] as $childkey) {
198: $this->_makeSelBoxOptions($fieldName, $selected, $childkey, $ret, $prefix_orig, $prefix_curr);
199: }
200: }
201: }
202:
203: /**
204: * Make a select box with options from the tree
205: *
206: * @param string $name Name of the select box
207: * @param string $fieldName Name of the member variable from the
208: * node objects that should be used as the title for the options.
209: * @param string $prefix String to indent deeper levels
210: * @param string $selected Value to display as selected
211: * @param bool $addEmptyOption Set TRUE to add an empty option with value "0" at the top of the hierarchy
212: * @param integer $key ID of the object to display as the root of select options
213: * @return string HTML select box
214: **/
215: function &makeSelBox($name, $fieldName, $prefix='-', $selected='', $addEmptyOption = false, $key=0)
216: {
217: $ret = '<select name="'.$name.'" id="'.$name.'">';
218: if (false != $addEmptyOption) {
219: $ret .= '<option value="0"></option>';
220: }
221: $this->_makeSelBoxOptions($fieldName, $selected, $key, $ret, $prefix);
222: $ret .= "</select>";
223: return $ret;
224: }
225:
226:
227: }
228: ?>