Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 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.doctrine-project.org>.
20
 */
21
 
22
/**
23
 * Doctrine_IntegrityMapper
24
 *
25
 * @package     Doctrine
26
 * @subpackage  IntegrityMapper
27
 * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
28
 * @link        www.doctrine-project.org
29
 * @since       1.0
30
 * @version     $Revision$
31
 * @author      Konsta Vesterinen <kvesteri@cc.hut.fi>
32
 */
33
class Doctrine_IntegrityMapper
34
{
35
    /**
36
     * processDeleteIntegrity
37
     *
38
     * @param Doctrine_Record $record
39
     * @return void
40
     */
41
    public function processDeleteIntegrity(Doctrine_Record $record)
42
    {
43
        $coll = $this->buildIntegrityRelationQuery($record);
44
 
45
        $this->invokeIntegrityActions($record);
46
    }
47
 
48
    /**
49
     * invokeIntegrityActions
50
     *
51
     * @param Doctrine_Record $record
52
     * @return void
53
     */
54
    public function invokeIntegrityActions(Doctrine_Record $record)
55
    {
56
        $deleteActions = Doctrine_Manager::getInstance()
57
                         ->getDeleteActions($record->getTable()->getComponentName());
58
 
59
        foreach ($record->getTable()->getRelations() as $relation) {
60
            $componentName = $relation->getTable()->getComponentName();
61
 
62
            foreach($record->get($relation->getAlias()) as $coll) {
63
                if ( ! ($coll instanceof Doctrine_Collection)) {
64
                    $coll = array($coll);
65
                }
66
                foreach ($coll as $record) {
67
                    $this->invokeIntegrityActions($record);
68
 
69
                    if (isset($deleteActions[$componentName])) {
70
                        if ($deleteActions[$componentName] === 'SET NULL') {
71
                            $record->set($relation->getForeign(), null);
72
                        } elseif ($deleteActions[$componentName] === 'CASCADE') {
73
                            $this->conn->transaction->addDelete($record);
74
                        }
75
                    }
76
 
77
                }
78
            }
79
        }
80
    }
81
 
82
    /**
83
     * buildIntegrityRelationQuery
84
     *
85
     * @param Doctrine_Record $record
86
     * @return array The result
87
     */
88
    public function buildIntegrityRelationQuery(Doctrine_Record $record)
89
    {
90
        $q = $record->getTable()->createQuery();
91
 
92
        $aliases = array();
93
        $indexes = array();
94
 
95
        $root = $record->getTable()->getComponentName();
96
        $rootAlias = strtolower(substr($root, 0, 1));
97
        $aliases[$rootAlias] = $root;
98
 
99
        foreach ((array) $record->getTable()->getIdentifier() as $id) {
100
            $field = $rootAlias . '.' . $id;
101
            $cond[]   = $field . ' = ?';
102
            $fields[] = $field;
103
            $params   = $record->get($id);
104
        }
105
        $fields = implode(', ', $fields);
106
        $components[] = $root;
107
        $this->buildIntegrityRelations($record->getTable(), $aliases, $fields, $indexes, $components);
108
 
109
        $q->select($fields)->from($root. ' ' . $rootAlias);
110
 
111
        foreach ($aliases as $alias => $name) {
112
            $q->leftJoin($rootAlias . '.' . $name . ' ' . $alias);
113
        }
114
        $q->where(implode(' AND ', $cond));
115
 
116
        return $q->execute(array($params));
117
    }
118
 
119
    /**
120
     * buildIntegrityRelations
121
     *
122
     * @param Doctrine_Table $table
123
     * @param mixed $aliases
124
     * @param mixed $fields
125
     * @param mixed $indexes
126
     * @param mixed $components
127
     * @return void
128
     */
129
    public function buildIntegrityRelations(Doctrine_Table $table, &$aliases, &$fields, &$indexes, &$components)
130
    {
131
        $deleteActions = Doctrine_Manager::getInstance()
132
                         ->getDeleteActions($table->getComponentName());
133
 
134
        foreach ($table->getRelations() as $relation) {
135
            $componentName = $relation->getTable()->getComponentName();
136
            if (in_array($componentName, $components)) {
137
                continue;
138
            }
139
            $components[] = $componentName;
140
 
141
            $alias = strtolower(substr($relation->getAlias(), 0, 1));
142
 
143
            if ( ! isset($indexes[$alias])) {
144
                $indexes[$alias] = 1;
145
            }
146
 
147
            if (isset($deleteActions[$componentName])) {
148
                if (isset($aliases[$alias])) {
149
                    $alias = $alias . ++$indexes[$alias];
150
                }
151
                $aliases[$alias] = $relation->getAlias();
152
 
153
                if ($deleteActions[$componentName] === 'SET NULL') {
154
                    if ($relation instanceof Doctrine_Relation_ForeignKey) {
155
                        foreach ((array) $relation->getForeign() as $foreign) {
156
                            $fields .= ', ' . $alias . '.' . $foreign;
157
                        }
158
                    } elseif ($relation instanceof Doctrine_Relation_LocalKey) {
159
                        foreach ((array) $relation->getLocal() as $foreign) {
160
                            $fields .= ', ' . $alias . '.' . $foreign;
161
                        }
162
                    }
163
                }
164
                foreach ((array) $relation->getTable()->getIdentifier() as $id) {
165
                    $fields .= ', ' . $alias . '.' . $id;
166
                }
167
                if ($deleteActions[$componentName] === 'CASCADE') {
168
                    $this->buildIntegrityRelations($relation->getTable(), $aliases, $fields, $indexes, $components);
169
                }
170
            }
171
        }
172
    }
173
}