# Source for file Relation.php

Documentation is available at Relation.php

1. <?php
2. /*
3. * $Id: Relation.php 1973 2007-07-11 14:39:15Z 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_Relation
23. * This class represents a relation between components
24. *
25. * @package Doctrine
26. * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
27. * @category Object Relational Mapping
28. * @link www.phpdoctrine.com
29. * @since 1.0
30. * @version $Revision: 1973 $
31. * @author Konsta Vesterinen <kvesteri@cc.hut.fi>
32. */
33. abstract class Doctrine_Relation implements ArrayAccess
34. {
35. /**
36. * RELATION CONSTANTS
37. */
39. /**
40. * constant for ONE_TO_ONE and MANY_TO_ONE aggregate relationships
41. */
42. const ONE_AGGREGATE = 0;
43. /**
44. * constant for ONE_TO_ONE and MANY_TO_ONE composite relationships
45. */
46. const ONE_COMPOSITE = 1;
47. /**
48. * constant for MANY_TO_MANY and ONE_TO_MANY aggregate relationships
49. */
50. const MANY_AGGREGATE = 2;
51. /**
52. * constant for MANY_TO_MANY and ONE_TO_MANY composite relationships
53. */
54. const MANY_COMPOSITE = 3;
56. const ONE = 0;
57. const MANY = 2;
59. protected $definition = array('alias' => true,
60. 'foreign' => true,
61. 'local' => true,
62. 'class' => true,
63. 'type' => true,
64. 'table' => true,
65. 'name' => false,
66. 'refTable' => false,
67. 'onDelete' => false,
68. 'onUpdate' => false,
69. 'deferred' => false,
70. 'deferrable' => false,
71. 'constraint' => false,
72. 'equal' => false,
73. );
74. /**
75. * constructor
76. *
77. * @param array $definition an associative array with the following structure:
78. * name foreign key constraint name
79. *
80. * local the local field(s)
81. *
82. * foreign the foreign reference field(s)
83. *
84. * table the foreign table object
85. *
86. * refTable the reference table object (if any)
87. *
88. * onDelete referential delete action
89. *
90. * onUpdate referential update action
91. *
92. * deferred deferred constraint checking
93. *
94. * alias relation alias
95. *
96. * type the relation type, either Doctrine_Relation::ONE or Doctrine_Relation::MANY
97. *
98. * constraint boolean value, true if the relation has an explicit referential integrity constraint
99. *
100. * The onDelete and onUpdate keys accept the following values:
101. *
102. * CASCADE: Delete or update the row from the parent table and automatically delete or
103. * update the matching rows in the child table. Both ON DELETE CASCADE and ON UPDATE CASCADE are supported.
104. * Between two tables, you should not define several ON UPDATE CASCADE clauses that act on the same column
105. * in the parent table or in the child table.
106. *
107. * SET NULL: Delete or update the row from the parent table and set the foreign key column or columns in the
108. * child table to NULL. This is valid only if the foreign key columns do not have the NOT NULL qualifier
109. * specified. Both ON DELETE SET NULL and ON UPDATE SET NULL clauses are supported.
110. *
111. * NO ACTION: In standard SQL, NO ACTION means no action in the sense that an attempt to delete or update a primary
112. * key value is not allowed to proceed if there is a related foreign key value in the referenced table.
113. *
114. * RESTRICT: Rejects the delete or update operation for the parent table. NO ACTION and RESTRICT are the same as
115. * omitting the ON DELETE or ON UPDATE clause.
116. *
117. * SET DEFAULT
118. */
119. public function __construct(array $definition)
120. {
121. $def = array();
122. foreach ($this->definition as $key => $val) {
123. if ( ! isset($definition[$key]) && $val) {
124. throw new Doctrine_Exception($key . ' is required!');
125. }
126. if (isset($definition[$key])) {
127. $def[$key] = $definition[$key];
128. } else {
129. $def[$key] = null;
130. }
131. }
133. $this->definition = $def;
134. }
135. /**
136. * hasConstraint
137. * whether or not this relation has an explicit constraint
138. *
139. * @return boolean
140. */
141. public function hasConstraint()
142. {
143. return ($this->definition['constraint'] ||
144. ($this->definition['onUpdate']) ||
145. ($this->definition['onDelete']));
146. }
147. public function isDeferred()
148. {
149. return $this->definition['deferred'];
150. }
152. public function isDeferrable()
153. {
154. return $this->definition['deferrable'];
155. }
156. public function isEqual()
157. {
158. return $this->definition['equal'];
159. }
161. public function offsetExists($offset)
162. {
163. return isset($this->definition[$offset]);
164. }
166. public function offsetGet($offset)
167. {
168. if (isset($this->definition[$offset])) {
169. return $this->definition[$offset];
170. }
172. return null;
173. }
175. public function offsetSet($offset, $value)
176. {
177. if (isset($this->definition[$offset])) {
178. $this->definition[$offset] = $value;
179. }
180. }
182. public function offsetUnset($offset)
183. {
184. $this->definition[$offset] = false;
185. }
186. /**
187. * toArray
188. *
189. * @return array
190. */
191. public function toArray()
192. {
193. return $this->definition;
194. }
195. /**
196. * getAlias
197. * returns the relation alias
198. *
199. * @return string
200. */
201. final public function getAlias()
202. {
203. return $this->definition['alias'];
204. }
205. /**
206. * getType
207. * returns the relation type, either 0 or 1
208. *
209. * @see Doctrine_Relation MANY_* and ONE_* constants
210. * @return integer
211. */
212. final public function getType()
213. {
214. return $this->definition['type'];
215. }
216. /**
217. * getTable
218. * returns the foreign table object
219. *
220. * @return object Doctrine_Table
221. */
222. final public function getTable()
223. {
224. return Doctrine_Manager::getInstance()
225. ->getConnectionForComponent($this->definition['class'])
226. ->getTable($this->definition['class']);
227. }
228. /**
229. * getLocal
230. * returns the name of the local column
231. *
232. * @return string
233. */
234. final public function getLocal()
235. {
236. return $this->definition['local'];
237. }
238. /**
239. * getForeign
240. * returns the name of the foreignkey column where
241. * the localkey column is pointing at
242. *
243. * @return string
244. */
245. final public function getForeign()
246. {
247. return $this->definition['foreign'];
248. }
249. /**
250. * isComposite
251. * returns whether or not this relation is a composite relation
252. *
253. * @return boolean
254. */
255. final public function isComposite()
256. {
257. return ($this->definition['type'] == Doctrine_Relation::ONE_COMPOSITE ||
258. $this->definition['type'] == Doctrine_Relation::MANY_COMPOSITE);
259. }
260. /**
261. * isOneToOne
262. * returns whether or not this relation is a one-to-one relation
263. *
264. * @return boolean
265. */
266. final public function isOneToOne()
267. {
268. return ($this->definition['type'] == Doctrine_Relation::ONE_AGGREGATE ||
269. $this->definition['type'] == Doctrine_Relation::ONE_COMPOSITE);
270. }
271. /**
272. * getRelationDql
273. *
274. * @param integer $count
275. * @return string
276. */
277. public function getRelationDql($count)
278. {
279. $component = $this->getTable()->getComponentName();
281. $dql = 'FROM ' . $component
282. . ' WHERE ' . $component . '.' . $this->definition['foreign']
283. . ' IN (' . substr(str_repeat('?, ', $count), 0, -2) . ')';
285. return $dql;
286. }
287. /**
288. * fetchRelatedFor
289. *
290. * fetches a component related to given record
291. *
292. * @param Doctrine_Record $record
293. * @return Doctrine_Record|Doctrine_Collection
294. */
295. abstract public function fetchRelatedFor(Doctrine_Record $record);
296. /**
297. /**
298. * __toString
299. *
300. * @return string
301. */
302. public function __toString()
303. {
304. $r[] = "<pre>";
305. foreach ($this->definition as $k => $v) {
306. if(is_object($v)) {
307. $v = 'Object(' . get_class($v) . ')';
308. }
309. $r[] = $k . ' : ' . $v;
310. }
311. $r[] = "</pre>";
312. return implode("\n", $r);
313. }
314. }