1<?php
2
3/**
4 * dwoo data object, use it for complex data assignments or if you want to easily pass it
5 * around multiple functions to avoid passing an array by reference
6 *
7 * This software is provided 'as-is', without any express or implied warranty.
8 * In no event will the authors be held liable for any damages arising from the use of this software.
9 *
10 * @author     Jordi Boggiano <j.boggiano@seld.be>
11 * @copyright  Copyright (c) 2008, Jordi Boggiano
12 * @license    http://dwoo.org/LICENSE   Modified BSD License
13 * @link       http://dwoo.org/
14 * @version    1.0.0
15 * @date       2008-10-23
16 * @package    Dwoo
17 */
18class Dwoo_Data implements Dwoo_IDataProvider
19{
20	/**
21	 * data array
22	 *
23	 * @var array
24	 */
25	protected $data = array();
26
27	/**
28	 * returns the data array
29	 *
30	 * @return array
31	 */
32	public function getData()
33	{
34		return $this->data;
35	}
36
37	/**
38	 * clears a the entire data or only the given key
39	 *
40	 * @param array|string $name clears only one value if you give a name, multiple values if
41	 * 							  you give an array of names, or the entire data if left null
42	 */
43	public function clear($name = null)
44	{
45		if ($name === null) {
46			$this->data = array();
47		} elseif (is_array($name)) {
48			foreach ($name as $index)
49				unset($this->data[$index]);
50		} else {
51			unset($this->data[$name]);
52		}
53	}
54
55	/**
56	 * overwrites the entire data with the given array
57	 *
58	 * @param array $data the new data array to use
59	 */
60	public function setData(array $data)
61	{
62		$this->data = $data;
63	}
64
65	/**
66	 * merges the given array(s) with the current data with array_merge
67	 *
68	 * @param array $data the array to merge
69	 * @param array $data2 $data3 ... other arrays to merge, optional, etc.
70	 */
71	public function mergeData(array $data)
72	{
73		$args = func_get_args();
74		while (list(,$v) = each($args)) {
75			if (is_array($v)) {
76				$this->data = array_merge($this->data, $v);
77			}
78		}
79	}
80
81	/**
82	 * assigns a value or an array of values to the data object
83	 *
84	 * @param array|string $name an associative array of multiple (index=>value) or a string
85	 * 					   that is the index to use, i.e. a value assigned to "foo" will be
86	 * 					   accessible in the template through {$foo}
87	 * @param mixed $val the value to assign, or null if $name was an array
88	 */
89	public function assign($name, $val = null)
90	{
91		if (is_array($name)) {
92			reset($name);
93			while (list($k,$v) = each($name))
94				$this->data[$k] = $v;
95		} else {
96			$this->data[$name] = $val;
97		}
98	}
99
100   	/**
101   	 * allows to assign variables using the object syntax
102   	 *
103   	 * @param string $name the variable name
104   	 * @param string $value the value to assign to it
105   	 */
106   	public function __set($name, $value)
107   	{
108   		$this->assign($name, $value);
109   	}
110
111	/**
112	 * assigns a value by reference to the data object
113	 *
114	 * @param string $name the index to use, i.e. a value assigned to "foo" will be
115	 * 					   accessible in the template through {$foo}
116	 * @param mixed $val the value to assign by reference
117	 */
118	public function assignByRef($name, &$val)
119	{
120		$this->data[$name] =& $val;
121	}
122
123	/**
124	 * appends values or an array of values to the data object
125	 *
126	 * @param array|string $name an associative array of multiple (index=>value) or a string
127	 * 					   that is the index to use, i.e. a value assigned to "foo" will be
128	 * 					   accessible in the template through {$foo}
129	 * @param mixed $val the value to assign, or null if $name was an array
130	 * @param bool $merge true to merge data or false to append, defaults to false
131	 */
132   	public function append($name, $val = null, $merge = false)
133   	{
134   		if (is_array($name)) {
135			foreach ($name as $key=>$val) {
136				if (isset($this->data[$key]) && !is_array($this->data[$key])) {
137					settype($this->data[$key], 'array');
138				}
139
140				if ($merge === true && is_array($val)) {
141					$this->data[$key] = $val + $this->data[$key];
142				} else {
143					$this->data[$key][] = $val;
144				}
145			}
146   		} elseif ($val !== null) {
147			if (isset($this->data[$name]) && !is_array($this->data[$name])) {
148				settype($this->data[$name], 'array');
149			} elseif (!isset($this->data[$name])) {
150				$this->data[$name] = array();
151			}
152
153			if ($merge === true && is_array($val)) {
154				$this->data[$name] = $val + $this->data[$name];
155			} else {
156				$this->data[$name][] = $val;
157			}
158   		}
159   	}
160
161	/**
162	 * appends a value by reference to the data object
163	 *
164	 * @param string $name the index to use, i.e. a value assigned to "foo" will be
165	 * 					   accessible in the template through {$foo}
166	 * @param mixed $val the value to append by reference
167	 * @param bool $merge true to merge data or false to append, defaults to false
168	 */
169   	public function appendByRef($name, &$val, $merge = false)
170   	{
171   		if (isset($this->data[$name]) && !is_array($this->data[$name])) {
172			settype($this->data[$name], 'array');
173		}
174
175   		if ($merge === true && is_array($val)) {
176   			foreach ($val as $key => &$val) {
177   				$this->data[$name][$key] =& $val;
178   			}
179   		} else {
180   			$this->data[$name][] =& $val;
181   		}
182   	}
183
184   	/**
185   	 * returns true if the variable has been assigned already, false otherwise
186   	 *
187   	 * @param string $name the variable name
188   	 * @return bool
189   	 */
190   	public function isAssigned($name)
191   	{
192   		return isset($this->data[$name]);
193   	}
194
195   	/**
196   	 * supports calls to isset($dwooData->var)
197   	 *
198   	 * @param string $name the variable name
199   	 */
200   	public function __isset($name)
201   	{
202   		return isset($this->data[$name]);
203   	}
204
205   	/**
206   	 * unassigns/removes a variable
207   	 *
208   	 * @param string $name the variable name
209   	 */
210   	public function unassign($name)
211   	{
212   		unset($this->data[$name]);
213   	}
214
215   	/**
216   	 * supports unsetting variables using the object syntax
217   	 *
218   	 * @param string $name the variable name
219   	 */
220   	public function __unset($name)
221   	{
222   		unset($this->data[$name]);
223   	}
224
225   	/**
226   	 * returns a variable if it was assigned
227   	 *
228   	 * @param string $name the variable name
229   	 * @return mixed
230   	 */
231   	public function get($name)
232   	{
233   		return $this->__get($name);
234   	}
235
236   	/**
237   	 * allows to read variables using the object syntax
238   	 *
239   	 * @param string $name the variable name
240   	 * @return mixed
241   	 */
242   	public function __get($name)
243   	{
244   		if (isset($this->data[$name])) {
245   			return $this->data[$name];
246   		} else {
247   			throw new Dwoo_Exception('Tried to read a value that was not assigned yet : "'.$name.'"');
248   		}
249   	}
250}
251