# Source for file Configurable.php

Documentation is available at Configurable.php

1. <?php
2. /*
3. * $Id: Configurable.php 2153 2007-08-03 11:52:24Z zYne $
4. *
5. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
6. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
7. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
8. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
9. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
10. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
11. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
12. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
13. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
14. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
15. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16. *
17. * This software consists of voluntary contributions made by many individuals
18. * and is licensed under the LGPL. For more information, see
19. * <http://www.phpdoctrine.com>.
20. */
21. /**
22. * Doctrine_Configurable
23. * the base for Doctrine_Table, Doctrine_Manager and Doctrine_Connection
24. *
25. *
26. * @package Doctrine
27. * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
28. * @category Object Relational Mapping
29. * @link www.phpdoctrine.com
30. * @since 1.0
31. * @version $Revision: 2153 $
32. * @author Konsta Vesterinen <kvesteri@cc.hut.fi>
33. */
34. abstract class Doctrine_Configurable extends Doctrine_Object
35. {
36. /**
37. * @var array $attributes an array of containing all attributes
38. */
39. protected $attributes = array();
40. /**
41. * @var Doctrine_Configurable $parent the parent of this component
42. */
43. protected $parent;
44. /**
45. * @var array $_impl an array containing concrete implementations for class templates
46. * keys as template names and values as names of the concrete
47. * implementation classes
48. */
49. protected $_impl = array();
50. /**
51. * setAttribute
52. * sets a given attribute
53. *
54. * <code>
55. * $manager->setAttribute(Doctrine::ATTR_PORTABILITY, Doctrine::PORTABILITY_ALL);
56. *
57. * // or
58. *
59. * $manager->setAttribute('portability', Doctrine::PORTABILITY_ALL);
60. * </code>
61. *
62. * @param mixed $attribute either a Doctrine::ATTR_* integer constant or a string
63. * corresponding to a constant
64. * @param mixed $value the value of the attribute
65. * @see Doctrine::ATTR_* constants
66. * @throws Doctrine_Exception if the value is invalid
67. * @return void
68. */
69. public function setAttribute($attribute,$value)
70. {
71. if (is_string($attribute)) {
72. $upper = strtoupper($attribute);
74. $const = 'Doctrine::ATTR_' . $attribute;
75. if (defined($const)) {
76. $this->_state = constant($const);
77. } else {
78. throw new Doctrine_Exception('Unknown attribute ' . $attribute);
79. }
80. }
81. switch ($attribute) {
82. case Doctrine::ATTR_FETCHMODE:
83. if ($value < 0) {
84. throw new Doctrine_Exception("Unknown fetchmode. See Doctrine::FETCH_* constants.");
85. }
86. break;
87. case Doctrine::ATTR_LISTENER:
88. $this->setEventListener($value);
89. break;
90. case Doctrine::ATTR_LOCKMODE:
91. break;
92. case Doctrine::ATTR_CREATE_TABLES:
93. throw new Doctrine_Exception("ATTR_CREATE_TABLES has been deprecated. See exporting in the first chapter of the manual.");
94. break;
95. case Doctrine::ATTR_ACCESSORS:
96. throw new Doctrine_Exception("Get / Set filtering is deprecated (slowed down Doctrine too much).");
97. break;
98. case Doctrine::ATTR_COLL_LIMIT:
99. if ($value < 1) {
100. throw new Doctrine_Exception("Collection limit should be a value greater than or equal to 1.");
101. }
102. break;
103. case Doctrine::ATTR_COLL_KEY:
104. if ( ! ($this instanceof Doctrine_Table)) {
105. throw new Doctrine_Exception("This attribute can only be set at table level.");
106. }
107. if ($value !== null && ! $this->hasColumn($value)) {
108. throw new Doctrine_Exception("Couldn't set collection key attribute. No such column '$value'");
109. }
110. break;
111. case Doctrine::ATTR_CACHE:
112. if ($value !== null) {
113. if ( ! ($value instanceof Doctrine_Cache_Interface)) {
114. throw new Doctrine_Exception('Cache driver should implement Doctrine_Cache_Interface');
115. }
116. }
117. break;
118. case Doctrine::ATTR_VLD:
119. case Doctrine::ATTR_AUTO_LENGTH_VLD:
120. case Doctrine::ATTR_AUTO_TYPE_VLD:
121. case Doctrine::ATTR_QUERY_LIMIT:
122. case Doctrine::ATTR_QUOTE_IDENTIFIER:
123. case Doctrine::ATTR_PORTABILITY:
124. case Doctrine::ATTR_DEFAULT_TABLE_TYPE:
125. case Doctrine::ATTR_ACCESSOR_PREFIX_GET:
126. case Doctrine::ATTR_ACCESSOR_PREFIX_SET:
127. case Doctrine::ATTR_EMULATE_DATABASE:
128. case Doctrine::ATTR_DEFAULT_SEQUENCE:
129. case Doctrine::ATTR_EXPORT:
130. case Doctrine::ATTR_DECIMAL_PLACES:
131. case Doctrine::ATTR_LOAD_REFERENCES:
132. case Doctrine::ATTR_RECORD_LISTENER:
133. case Doctrine::ATTR_THROW_EXCEPTIONS:
135. break;
136. case Doctrine::ATTR_SEQCOL_NAME:
137. if ( ! is_string($value)) {
138. throw new Doctrine_Exception('Sequence column name attribute only accepts string values');
139. }
140. break;
141. case Doctrine::ATTR_FIELD_CASE:
142. if ($value != 0 && $value != CASE_LOWER && $value != CASE_UPPER)
143. throw new Doctrine_Exception('Field case attribute should be either 0, CASE_LOWER or CASE_UPPER constant.');
144. break;
145. case Doctrine::ATTR_SEQNAME_FORMAT:
146. case Doctrine::ATTR_IDXNAME_FORMAT:
147. if ($this instanceof Doctrine_Table) {
148. throw new Doctrine_Exception('Sequence / index name format attributes cannot be set'
149. . 'at table level (only at connection or global level).');
150. }
151. break;
152. default:
153. throw new Doctrine_Exception("Unknown attribute.");
154. }
156. $this->attributes[$attribute] = $value;
158. }
159. /**
160. * setImpl
161. * binds given class to given template name
162. *
163. * this method is the base of Doctrine dependency injection
164. *
165. * @param string $template name of the class template
166. * @param string $class name of the class to be bound
167. * @return Doctrine_Configurable this object
168. */
169. public function setImpl($template, $class)
170. {
171. $this->_impl[$template] = $class;
173. return $this;
174. }
175. /**
176. * getImpl
177. * returns the implementation for given class
178. *
179. * @return string name of the concrete implementation
180. */
181. public function getImpl($template)
182. {
183. if ( ! isset($this->_impl[$template])) {
184. if (isset($this->parent)) {
185. return $this->parent->getImpl($template);
186. }
187. return null;
188. }
189. return $this->_impl[$template];
190. }
191. /**
192. * getCacheDriver
193. *
194. * @return Doctrine_Cache_Interface
195. */
196. public function getCacheDriver()
197. {
198. if ( ! isset($this->attributes[Doctrine::ATTR_CACHE])) {
199. throw new Doctrine_Exception('Cache driver not initialized.');
200. }
202. return $this->attributes[Doctrine::ATTR_CACHE];
203. }
204. /**
205. * @param Doctrine_EventListener $listener
206. * @return void
207. */
208. public function setEventListener($listener)
209. {
210. return $this->setListener($listener);
211. }
212. /**
213. * addRecordListener
214. *
215. * @param Doctrine_EventListener_Interface|Doctrine_Overloadable$listener
216. * @return mixed this object
217. */
218. public function addRecordListener($listener, $name = null)
219. {
220. if ( ! isset($this->attributes[Doctrine::ATTR_RECORD_LISTENER]) ||
221. ! ($this->attributes[Doctrine::ATTR_RECORD_LISTENER] instanceof Doctrine_Record_Listener_Chain)) {
223. $this->attributes[Doctrine::ATTR_RECORD_LISTENER] = new Doctrine_Record_Listener_Chain();
224. }
225. $this->attributes[Doctrine::ATTR_RECORD_LISTENER]->add($listener, $name);
227. return $this;
228. }
229. /**
230. * getListener
231. *
232. * @return Doctrine_EventListener_Interface|Doctrine_Overloadable
233. */
234. public function getRecordListener()
235. {
236. if ( ! isset($this->attributes[Doctrine::ATTR_RECORD_LISTENER])) {
237. if (isset($this->parent)) {
238. return $this->parent->getRecordListener();
239. }
240. return null;
241. }
242. return $this->attributes[Doctrine::ATTR_RECORD_LISTENER];
243. }
244. /**
245. * setListener
246. *
247. * @param Doctrine_EventListener_Interface|Doctrine_Overloadable$listener
248. * @return Doctrine_Configurable this object
249. */
250. public function setRecordListener($listener)
251. {
252. if ( ! ($listener instanceof Doctrine_Record_Listener_Interface)
253. && ! ($listener instanceof Doctrine_Overloadable)
254. ) {
255. throw new Doctrine_Exception("Couldn't set eventlistener. Record listeners should implement either Doctrine_Record_Listener_Interface or Doctrine_Overloadable");
256. }
257. $this->attributes[Doctrine::ATTR_RECORD_LISTENER] = $listener;
259. return $this;
260. }
261. /**
262. * addListener
263. *
264. * @param Doctrine_EventListener_Interface|Doctrine_Overloadable$listener
265. * @return mixed this object
266. */
267. public function addListener($listener, $name = null)
268. {
269. if ( ! isset($this->attributes[Doctrine::ATTR_LISTENER]) ||
270. ! ($this->attributes[Doctrine::ATTR_LISTENER] instanceof Doctrine_EventListener_Chain)) {
272. $this->attributes[Doctrine::ATTR_LISTENER] = new Doctrine_EventListener_Chain();
273. }
274. $this->attributes[Doctrine::ATTR_LISTENER]->add($listener, $name);
276. return $this;
277. }
278. /**
279. * getListener
280. *
281. * @return Doctrine_EventListener_Interface|Doctrine_Overloadable
282. */
283. public function getListener()
284. {
285. if ( ! isset($this->attributes[Doctrine::ATTR_LISTENER])) {
286. if (isset($this->parent)) {
287. return $this->parent->getListener();
288. }
289. return null;
290. }
291. return $this->attributes[Doctrine::ATTR_LISTENER];
292. }
293. /**
294. * setListener
295. *
296. * @param Doctrine_EventListener_Interface|Doctrine_Overloadable$listener
297. * @return Doctrine_Configurable this object
298. */
299. public function setListener($listener)
300. {
301. if ( ! ($listener instanceof Doctrine_EventListener_Interface)
302. && ! ($listener instanceof Doctrine_Overloadable)
303. ) {
304. throw new Doctrine_EventListener_Exception("Couldn't set eventlistener. EventListeners should implement either Doctrine_EventListener_Interface or Doctrine_Overloadable");
305. }
306. $this->attributes[Doctrine::ATTR_LISTENER] = $listener;
308. return $this;
309. }
310. /**
311. * returns the value of an attribute
312. *
313. * @param integer $attribute
314. * @return mixed
315. */
316. public function getAttribute($attribute)
317. {
318. $attribute = (int) $attribute;
320. if ($attribute < 0) {
321. throw new Doctrine_Exception('Unknown attribute.');
322. }
324. if ( ! isset($this->attributes[$attribute])) {
325. if (isset($this->parent)) {
326. return $this->parent->getAttribute($attribute);
327. }
328. return null;
329. }
330. return $this->attributes[$attribute];
331. }
332. /**
333. * getAttributes
334. * returns all attributes as an array
335. *
336. * @return array
337. */
338. public function getAttributes()
339. {
340. return $this->attributes;
341. }
342. /**
343. * sets a parent for this configurable component
344. * the parent must be configurable component itself
345. *
346. * @param Doctrine_Configurable $component
347. * @return void
348. */
349. public function setParent(Doctrine_Configurable $component)
350. {
351. $this->parent = $component;
352. }
353. /**
354. * getParent
355. * returns the parent of this component
356. *
357. * @return Doctrine_Configurable
358. */
359. public function getParent()
360. {
361. return $this->parent;
362. }
363. }