1: <?php
2: /**
3: * The Horde_DataTree_null class provides a dummy implementation of the
4: * Horde_DataTree API; no data will last beyond a single page request.
5: *
6: * Copyright 1999-2012 Horde LLC (http://www.horde.org/)
7: *
8: * See the enclosed file COPYING for license information (LGPL). If you
9: * did not receive this file, see http://www.horde.org/licenses/lgpl21.
10: *
11: * @author Stephane Huther <shuther1@free.fr>
12: * @author Chuck Hagenbuch <chuck@horde.org>
13: * @package DataTree
14: */
15: class Horde_DataTree_Null extends Horde_DataTree {
16:
17: /**
18: * Cache of attributes for any objects created during this page request.
19: *
20: * @var array
21: */
22: var $_attributeCache = array();
23:
24: /**
25: * Cache of data for any objects created during this page request.
26: *
27: * @var array
28: */
29: var $_dataCache = array();
30:
31: /**
32: * Load (a subset of) the datatree into the $_data array. Part of the
33: * Horde_DataTree API that must be overridden by subclasses.
34: *
35: * @param string $root Which portion of the tree to load. Defaults to
36: * all of it.
37: * @param boolean $reload Re-load already loaded values?
38: *
39: * @return mixed True on success or a PEAR_Error on failure.
40: *
41: * @access private
42: */
43: function _load($root = null, $reload = false)
44: {
45: }
46:
47: /**
48: * Load a specific object identified by its unique ID ($id), and
49: * its parents, into the $_data array.
50: *
51: * @param integer $cid The unique ID of the object to load.
52: *
53: * @return mixed True on success or a PEAR_Error on failure.
54: *
55: * @access private
56: */
57: function _loadById($cid)
58: {
59: }
60:
61: /**
62: * Check for existance of an object in a backend-specific manner.
63: *
64: * @param string $object_name Object name to check for.
65: *
66: * @return boolean True if the object exists, false otherwise.
67: */
68: function _exists($object_name)
69: {
70: return false;
71: }
72:
73: /**
74: * Look up a datatree id by name.
75: *
76: * @param string $name
77: *
78: * @return integer Horde_DataTree id
79: */
80: function _getId($name)
81: {
82: return null;
83: }
84:
85: /**
86: * Look up a datatree name by id.
87: *
88: * @param integer $id
89: *
90: * @return string Horde_DataTree name
91: */
92: function _getName($id)
93: {
94: return null;
95: }
96:
97: /**
98: * Get a tree sorted by the specified attribute name and/or key.
99: *
100: * @param string $root Which portion of the tree to sort.
101: * Defaults to all of it.
102: * @param boolean $loadTree Sort the tree starting at $root, or just the
103: * requested level and direct parents?
104: * Defaults to single level.
105: * @param array $sortby_name Attribute name to use for sorting.
106: * @param array $sortby_key Attribute key to use for sorting.
107: * @param array $direction Sort direction:
108: * 0 - ascending
109: * 1 - descending
110: *
111: * @return array TODO
112: */
113: function getSortedTree($root, $loadTree = false, $sortby_name = null, $sortby_key = null, $direction = 0)
114: {
115: return array();
116: }
117:
118: /**
119: * Add an object. Part of the Horde_DataTree API that must be
120: * overridden by subclasses.
121: *
122: * @param mixed $fullname The object to add (string or Horde_DataTreeObject).
123: */
124: function add($object)
125: {
126: if (is_a($object, 'Horde_DataTreeObject')) {
127: $fullname = $object->getName();
128: $order = $object->order;
129: } else {
130: $fullname = $object;
131: $order = null;
132: }
133:
134: $id = md5(mt_rand());
135: if (strpos($fullname, ':') !== false) {
136: $parts = explode(':', $fullname);
137: $name = array_pop($parts);
138: $parent = implode(':', $parts);
139: $pid = $this->getId($parent);
140: if (is_a($pid, 'PEAR_Error')) {
141: $this->add($parent);
142: }
143: } else {
144: $pid = DATATREE_ROOT;
145: }
146:
147: if (parent::exists($fullname)) {
148: return PEAR::raiseError('Already exists');
149: }
150:
151: $added = parent::_add($fullname, $id, $pid, $order);
152: if (is_a($added, 'PEAR_Error')) {
153: return $added;
154: }
155: return $this->updateData($object);
156: }
157:
158: /**
159: * Change order of the children of an object.
160: *
161: * @param string $parents The parent id string path.
162: * @param mixed $order A specific new order position or an array
163: * containing the new positions for the given
164: * $parents object.
165: * @param integer $cid If provided indicates insertion of a new child
166: * to the object, and will be used to avoid
167: * incrementing it when shifting up all other
168: * children's order. If not provided indicates
169: * deletion, hence shift all other positions down
170: * one.
171: */
172: function reorder($parents, $order = null, $cid = null)
173: {
174: if (is_array($order) && !empty($order)) {
175: // Multi update.
176: $this->_reorder($pid, $order);
177: }
178: }
179:
180: /**
181: * Explicitly set the order for a datatree object.
182: *
183: * @param integer $id The datatree object id to change.
184: * @param integer $order The new order.
185: */
186: function setOrder($id, $order)
187: {
188: }
189:
190: /**
191: * Removes an object.
192: *
193: * @param mixed $object The object to remove.
194: * @param boolean $force Force removal of every child object?
195: */
196: function remove($object, $force = false)
197: {
198: }
199:
200: /**
201: * Remove one or more objects by id. This function does *not* do
202: * the validation, reordering, etc. that remove() does. If you
203: * need to check for children, re-do ordering, etc., then you must
204: * remove() objects one-by-one. This is for code that knows it's
205: * dealing with single (non-parented) objects and needs to delete
206: * a batch of them quickly.
207: *
208: * @param array $ids The objects to remove.
209: */
210: function removeByIds($ids)
211: {
212: }
213:
214: /**
215: * Remove one or more objects by name. This function does *not* do
216: * the validation, reordering, etc. that remove() does. If you
217: * need to check for children, re-do ordering, etc., then you must
218: * remove() objects one-by-one. This is for code that knows it's
219: * dealing with single (non-parented) objects and needs to delete
220: * a batch of them quickly.
221: *
222: * @param array $names The objects to remove.
223: */
224: function removeByNames($names)
225: {
226: }
227:
228: /**
229: * Move an object to a new parent.
230: *
231: * @param mixed $object The object to move.
232: * @param string $newparent The new parent object. Defaults to the root.
233: */
234: function move($object, $newparent = null)
235: {
236: }
237:
238: /**
239: * Change an object's name.
240: *
241: * @param mixed $old_object The old object.
242: * @param string $new_object_name The new object name.
243: */
244: function rename($old_object, $new_object_name)
245: {
246: }
247:
248: /**
249: * Retrieve data for an object from the datatree_data field.
250: *
251: * @param integer $cid The object id to fetch, or an array of object ids.
252: */
253: function getData($cid)
254: {
255: return isset($this->_dataCache[$cid]) ?
256: $this->_dataCache[$cid] :
257: array();
258: }
259:
260: /**
261: * Retrieve data for an object.
262: *
263: * @param integer $cid The object id to fetch.
264: */
265: function getAttributes($cid)
266: {
267: if (is_array($cid)) {
268: $data = array();
269: foreach ($cid as $id) {
270: if (isset($this->_attributeCache[$id])) {
271: $data[$id] = $this->_attributeCache[$id];
272: }
273: }
274:
275: return $data;
276: } else {
277: return isset($this->_attributeCache[$cid]) ?
278: $this->_attributeCache[$cid] :
279: array();
280: }
281: }
282:
283: /**
284: * Returns the number of objects matching a set of attribute
285: * criteria.
286: *
287: * @see buildAttributeQuery()
288: *
289: * @param array $criteria The array of criteria.
290: * @param string $parent The parent node to start searching from.
291: * @param boolean $allLevels Return all levels, or just the direct
292: * children of $parent? Defaults to all levels.
293: * @param string $restrict Only return attributes with the same
294: * attribute_name or attribute_id.
295: */
296: function countByAttributes($criteria, $parent = DATATREE_ROOT, $allLevels = true, $restrict = 'name')
297: {
298: if (!count($criteria)) {
299: return 0;
300: }
301:
302: return count($this->_attributeCache);
303: }
304:
305: /**
306: * Returns a set of object ids based on a set of attribute criteria.
307: *
308: * @see buildAttributeQuery()
309: *
310: * @param array $criteria The array of criteria.
311: * @param string $parent The parent node to start searching from.
312: * @param boolean $allLevels Return all levels, or just the direct
313: * children of $parent? Defaults to all levels.
314: * @param string $restrict Only return attributes with the same
315: * attribute_name or attribute_id.
316: * @param integer $from The object to start to fetching
317: * @param integer $count The number of objects to fetch
318: * @param string $sortby_name Attribute name to use for sorting.
319: * @param string $sortby_key Attribute key to use for sorting.
320: * @param integer $direction Sort direction:
321: * 0 - ascending
322: * 1 - descending
323: */
324: function getByAttributes($criteria, $parent = DATATREE_ROOT, $allLevels = true, $restrict = 'name', $from = 0, $count = 0,
325: $sortby_name = null, $sortby_key = null, $direction = 0)
326: {
327: if (!count($criteria)) {
328: return PEAR::raiseError('no criteria');
329: }
330:
331: $cids = array();
332: foreach (array_keys($this->_attributeCache) as $cid) {
333: $cids[$cid] = null;
334: }
335: return $cids;
336: }
337:
338: /**
339: * Sorts IDs by attribute values. IDs without attributes will be
340: * added to the end of the sorted list.
341: *
342: * @param array $unordered_ids Array of ids to sort.
343: * @param array $sortby_name Attribute name to use for sorting.
344: * @param array $sortby_key Attribute key to use for sorting.
345: * @param array $direction Sort direction:
346: * 0 - ascending
347: * 1 - descending
348: *
349: * @return array Sorted ids.
350: */
351: function sortByAttributes($unordered_ids, $sortby_name = null, $sortby_key = null, $direction = 0)
352: {
353: return $unordered_ids;
354: }
355:
356: /**
357: * Returns a list of all of the available values of the given
358: * attribute name/key combination. Either attribute_name or
359: * attribute_key MUST be supplied, and both MAY be supplied.
360: *
361: * @param string $attribute_name The name of the attribute.
362: * @param string $attribute_key The key value of the attribute.
363: * @param string $parent The parent node to start searching from.
364: * @param boolean $allLevels Return all levels, or just the direct
365: * children of $parent?
366: *
367: * @return array An array of all of the available values.
368: */
369: function getAttributeValues($attribute_name = null, $attribute_key = null, $parent = DATATREE_ROOT, $allLevels = true)
370: {
371: return array();
372: }
373:
374: /**
375: * Update the data in an object. Does not change the object's
376: * parent or name, just serialized data.
377: *
378: * @param string $object The object.
379: */
380: function updateData($object)
381: {
382: if (!is_a($object, 'Horde_DataTreeObject')) {
383: return true;
384: }
385:
386: $cid = $this->getId($object->getName());
387: if (is_a($cid, 'PEAR_Error')) {
388: return $cid;
389: }
390:
391: // We handle data differently if we can map it to
392: // attributes.
393: if (method_exists($object, '_toAttributes')) {
394: $this->_attributeCache[$cid] = $object->_toAttributes();
395: } else {
396: $this->_dataCache[$cid] = $object->getData();
397: }
398:
399: return true;
400: }
401:
402: /**
403: * Init the object.
404: *
405: * @return boolean True.
406: */
407: function _init()
408: {
409: return true;
410: }
411:
412: }
413: