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: Export.php 2552 2007-09-19 19:33:00Z Jonathan.Wage $
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_Data_Export
24
 *
25
 * @package     Doctrine
26
 * @subpackage  Data
27
 * @author      Jonathan H. Wage <jwage@mac.com>
28
 * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
29
 * @link        www.doctrine-project.org
30
 * @since       1.0
31
 * @version     $Revision: 2552 $
32
 */
33
class Doctrine_Data_Export extends Doctrine_Data
34
{
35
    /**
36
     * constructor
37
     *
38
     * @param string $directory
39
     * @return void
40
     */
41
    public function __construct($directory)
42
    {
43
        $this->setDirectory($directory);
44
    }
45
 
46
    /**
47
     * doExport
48
     *
49
     * FIXME: This function has ugly hacks in it for temporarily disabling INDEXBY query parts of tables
50
     * to export.
51
     *
52
     * Update from jwage: I am not sure if their is any other better solution for this. It may be the correct
53
     * solution to disable the indexBy settings for tables when exporting data fixtures. Maybe a better idea
54
     * would be to extract this functionality to a pair of functions to enable/disable the index by settings
55
     * so simply turn them on and off when they need to query for the translations standalone and don't need
56
     * it to be indexed by the lang.
57
     *
58
     * @return void
59
     */
60
    public function doExport()
61
    {
62
        $models = Doctrine_Core::getLoadedModels();
63
        $specifiedModels = $this->getModels();
64
 
65
        $data = array();
66
 
67
		    // for situation when the $models array is empty, but the $specifiedModels array isn't
68
        if (empty($models)) {
69
          $models = $specifiedModels;
70
        }
71
 
72
        $models = Doctrine_Core::initializeModels($models);
73
 
74
        // temporarily disable indexBy query parts of selected and related tables
75
        $originalIndexBy = array();
76
        foreach ($models AS $name) {
77
          $table = Doctrine_Core::getTable($name);
78
          if ( !is_null($indexBy = $table->getBoundQueryPart('indexBy'))) {
79
            $originalIndexBy[$name] = $indexBy;
80
            $table->bindQueryPart('indexBy', null);
81
          }
82
        }
83
 
84
        foreach ($models AS $name) {
85
            if ( ! empty($specifiedModels) AND ! in_array($name, $specifiedModels)) {
86
                continue;
87
            }
88
 
89
            $results = Doctrine_Core::getTable($name)->findAll();
90
 
91
            if ($results->count() > 0) {
92
                $data[$name] = $results;
93
            }
94
        }
95
 
96
        // Restore the temporarily disabled indexBy query parts
97
        foreach($originalIndexBy AS $name => $indexBy) {
98
            Doctrine_Core::getTable($name)->bindQueryPart('indexBy', $indexBy);
99
        }
100
 
101
        $data = $this->prepareData($data);
102
 
103
        return $this->dumpData($data);
104
    }
105
 
106
    /**
107
     * dumpData
108
     *
109
     * Dump the prepared data to the fixtures files
110
     *
111
     * @param string $array
112
     * @return void
113
     */
114
    public function dumpData(array $data)
115
    {
116
        $directory = $this->getDirectory();
117
        $format = $this->getFormat();
118
 
119
        if ($this->exportIndividualFiles()) {
120
            if (is_array($directory)) {
121
                throw new Doctrine_Data_Exception('You must specify a single path to a folder in order to export individual files.');
122
            } else if ( ! is_dir($directory) && is_file($directory)) {
123
                $directory = dirname($directory);
124
            }
125
 
126
            foreach ($data as $className => $classData) {
127
                if ( ! empty($classData)) {
128
                    Doctrine_Parser::dump(array($className => $classData), $format, $directory.DIRECTORY_SEPARATOR.$className.'.'.$format);
129
                }
130
            }
131
        } else {
132
            if (is_dir($directory)) {
133
                $directory .= DIRECTORY_SEPARATOR . 'data.' . $format;
134
            }
135
 
136
            if ( ! empty($data)) {
137
                return Doctrine_Parser::dump($data, $format, $directory);
138
            }
139
        }
140
    }
141
 
142
    /**
143
     * prepareData
144
     *
145
     * Prepare the raw data to be exported with the parser
146
     *
147
     * @param string $data
148
     * @return array
149
     */
150
    public function prepareData($data)
151
    {
152
        $preparedData = array();
153
 
154
        foreach ($data AS $className => $classData) {
155
            $preparedData[$className] = array();
156
            $keyType = $classData->getTable()->getIdentifierType();
157
            foreach ($classData as $record) {
158
                $className = get_class($record);
159
                $recordKey = $className . '_' . implode('_', $record->identifier());
160
                $preparedData[$className][$recordKey] = array();
161
 
162
                // skip single primary keys, we need to maintain composite primary keys
163
                $keys = $record->getTable()->getIdentifier();
164
 
165
                $recordData = $record->toArray(false);
166
 
167
                foreach ($recordData as $key => $value) {
168
                    if ( ! is_array($keys)) {
169
                      $keys = array($keys);
170
                    }
171
 
172
                    if ($keyType !== Doctrine_Core::IDENTIFIER_NATURAL && count($keys) <= 1 && in_array($key, $keys)) {
173
                        continue;
174
                    }
175
 
176
                    if (is_object($record[$key])) {
177
                        // If the field is an object serialize it
178
                        $value = serialize($record[$key]);
179
                    }
180
 
181
                    if ($relation = $this->isRelation($record, $key)) {
182
                        if ( ! $value) {
183
                            continue;
184
                        }
185
                        $relationAlias = $relation['alias'];
186
                        $relationRecord = $record->$relationAlias;
187
 
188
                        // If collection then get first so we have an instance of the related record
189
                        if ($relationRecord instanceof Doctrine_Collection) {
190
                            $relationRecord = $relationRecord->getFirst();
191
                        }
192
 
193
                        // If relation is null or does not exist then continue
194
                        if ($relationRecord instanceof Doctrine_Null || ! $relationRecord) {
195
                            continue;
196
                        }
197
 
198
                        // Get class name for relation
199
                        $relationClassName = get_class($relationRecord);
200
 
201
                        $relationValue = $relationClassName . '_' . $value;
202
 
203
                        $preparedData[$className][$recordKey][$relationAlias] = $relationValue;
204
                    } else if ($record->getTable()->hasField($key)) {
205
                        $preparedData[$className][$recordKey][$key] = $value;
206
                    }
207
                }
208
            }
209
        }
210
 
211
        return $preparedData;
212
    }
213
}