# Source for file IntegrityMapper.php

Documentation is available at IntegrityMapper.php

1. <?php
2. /*
3. * $Id$
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. */
22. /**
23. * Doctrine_IntegrityMapper
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$
31. * @author Konsta Vesterinen <kvesteri@cc.hut.fi>
32. */
33. class Doctrine_IntegrityMapper
34. {
35. public function processDeleteIntegrity(Doctrine_Record $record)
36. {
37. $coll = $this->buildIntegrityRelationQuery($record);
39. $this->invokeIntegrityActions($record);
40. }
41. public function invokeIntegrityActions(Doctrine_Record $record)
42. {
43. $deleteActions = Doctrine_Manager::getInstance()
44. ->getDeleteActions($record->getTable()->getComponentName());
46. foreach ($record->getTable()->getRelations() as $relation) {
47. $componentName = $relation->getTable()->getComponentName();
49. foreach($record->get($relation->getAlias()) as $coll) {
50. if ( ! ($coll instanceof Doctrine_Collection)) {
51. $coll = array($coll);
52. }
53. foreach ($coll as $record) {
54. $this->invokeIntegrityActions($record);
56. if (isset($deleteActions[$componentName])) {
57. if ($deleteActions[$componentName] === 'SET NULL') {
58. $record->set($relation->getForeign(), null);
59. } elseif ($deleteActions[$componentName] === 'CASCADE') {
60. $this->conn->transaction->addDelete($record);
61. }
62. }
64. }
65. }
66. }
67. }
68. public function buildIntegrityRelationQuery(Doctrine_Record $record)
69. {
70. $q = new Doctrine_Query();
72. $aliases = array();
73. $indexes = array();
75. $root = $record->getTable()->getComponentName();
76. $rootAlias = strtolower(substr($root, 0, 1));
77. $aliases[$rootAlias] = $root;
79. foreach ((array) $record->getTable()->getIdentifier() as $id) {
80. $field = $rootAlias . '.' . $id;
81. $cond[] = $field . ' = ?';
82. $fields[] = $field;
83. $params = $record->get($id);
84. }
85. $fields = implode(', ', $fields);
86. $components[] = $root;
87. $this->buildIntegrityRelations($record->getTable(), $aliases, $fields, $indexes, $components);
89. $q->select($fields)->from($root. ' ' . $rootAlias);
91. foreach ($aliases as $alias => $name) {
92. $q->leftJoin($rootAlias . '.' . $name . ' ' . $alias);
93. }
94. $q->where(implode(' AND ', $cond));
96. return $q->execute(array($params));
97. }
98. public function buildIntegrityRelations(Doctrine_Table $table, &$aliases, &$fields, &$indexes, &$components)
99. {
100. $deleteActions = Doctrine_Manager::getInstance()
101. ->getDeleteActions($table->getComponentName());
103. foreach ($table->getRelations() as $relation) {
104. $componentName = $relation->getTable()->getComponentName();
105. if (in_array($componentName, $components)) {
106. continue;
107. }
108. $components[] = $componentName;
110. $alias = strtolower(substr($relation->getAlias(), 0, 1));
112. if ( ! isset($indexes[$alias])) {
113. $indexes[$alias] = 1;
114. }
116. if (isset($deleteActions[$componentName])) {
117. if (isset($aliases[$alias])) {
118. $alias = $alias . ++$indexes[$alias];
119. }
120. $aliases[$alias] = $relation->getAlias();
122. if ($deleteActions[$componentName] === 'SET NULL') {
123. if ($relation instanceof Doctrine_Relation_ForeignKey) {
124. foreach ((array) $relation->getForeign() as $foreign) {
125. $fields .= ', ' . $alias . '.' . $foreign;
126. }
127. } elseif ($relation instanceof Doctrine_Relation_LocalKey) {
128. foreach ((array) $relation->getLocal() as $foreign) {
129. $fields .= ', ' . $alias . '.' . $foreign;
130. }
131. }
132. }
133. foreach ((array) $relation->getTable()->getIdentifier() as $id) {
134. $fields .= ', ' . $alias . '.' . $id;
135. }
136. if ($deleteActions[$componentName] === 'CASCADE') {
137. $this->buildIntegrityRelations($relation->getTable(), $aliases, $fields, $indexes, $components);
138. }
139. }
140. }
141. }
142. }