source: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/ConvertDoctrine1Schema.php @ 353

Last change on this file since 353 was 345, checked in by quyenla, 11 years ago

collaborator page

File size: 10.2 KB
Line 
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
22namespace Doctrine\ORM\Tools;
23
24use Doctrine\ORM\Mapping\ClassMetadataInfo,
25    Doctrine\ORM\Tools\Export\Driver\AbstractExporter,
26    Doctrine\Common\Util\Inflector;
27
28/**
29 * Class to help with converting Doctrine 1 schema files to Doctrine 2 mapping files
30 *
31 * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
32 * @link    www.doctrine-project.org
33 * @since   2.0
34 * @version $Revision$
35 * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
36 * @author  Jonathan Wage <jonwage@gmail.com>
37 * @author  Roman Borschel <roman@code-factory.org>
38 */
39class ConvertDoctrine1Schema
40{
41    private $_legacyTypeMap = array(
42        // TODO: This list may need to be updated
43        'clob' => 'text',
44        'timestamp' => 'datetime',
45        'enum' => 'string'
46    );
47
48    /**
49     * Constructor passes the directory or array of directories
50     * to convert the Doctrine 1 schema files from
51     *
52     * @param array $from
53     * @author Jonathan Wage
54     */
55    public function __construct($from)
56    {
57        $this->_from = (array) $from;
58    }
59
60    /**
61     * Get an array of ClassMetadataInfo instances from the passed
62     * Doctrine 1 schema
63     *
64     * @return array $metadatas  An array of ClassMetadataInfo instances
65     */
66    public function getMetadata()
67    {
68        $schema = array();
69        foreach ($this->_from as $path) {
70            if (is_dir($path)) {
71                $files = glob($path . '/*.yml');
72                foreach ($files as $file) {
73                    $schema = array_merge($schema, (array) \Symfony\Component\Yaml\Yaml::parse($file));
74                }
75            } else {
76                $schema = array_merge($schema, (array) \Symfony\Component\Yaml\Yaml::parse($path));
77            }
78        }
79
80        $metadatas = array();
81        foreach ($schema as $className => $mappingInformation) {
82            $metadatas[] = $this->_convertToClassMetadataInfo($className, $mappingInformation);
83        }
84
85        return $metadatas;
86    }
87
88    private function _convertToClassMetadataInfo($className, $mappingInformation)
89    {
90        $metadata = new ClassMetadataInfo($className);
91
92        $this->_convertTableName($className, $mappingInformation, $metadata);
93        $this->_convertColumns($className, $mappingInformation, $metadata);
94        $this->_convertIndexes($className, $mappingInformation, $metadata);
95        $this->_convertRelations($className, $mappingInformation, $metadata);
96
97        return $metadata;
98    }
99
100    private function _convertTableName($className, array $model, ClassMetadataInfo $metadata)
101    {
102        if (isset($model['tableName']) && $model['tableName']) {
103            $e = explode('.', $model['tableName']);
104
105            if (count($e) > 1) {
106                $metadata->table['schema'] = $e[0];
107                $metadata->table['name'] = $e[1];
108            } else {
109                $metadata->table['name'] = $e[0];
110            }
111        }
112    }
113
114    private function _convertColumns($className, array $model, ClassMetadataInfo $metadata)
115    {
116        $id = false;
117
118        if (isset($model['columns']) && $model['columns']) {
119            foreach ($model['columns'] as $name => $column) {
120                $fieldMapping = $this->_convertColumn($className, $name, $column, $metadata);
121
122                if (isset($fieldMapping['id']) && $fieldMapping['id']) {
123                    $id = true;
124                }
125            }
126        }
127
128        if ( ! $id) {
129            $fieldMapping = array(
130                'fieldName' => 'id',
131                'columnName' => 'id',
132                'type' => 'integer',
133                'id' => true
134            );
135            $metadata->mapField($fieldMapping);
136            $metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_AUTO);
137        }
138    }
139
140    private function _convertColumn($className, $name, $column, ClassMetadataInfo $metadata)
141    {
142        if (is_string($column)) {
143            $string = $column;
144            $column = array();
145            $column['type'] = $string;
146        }
147        if ( ! isset($column['name'])) {
148            $column['name'] = $name;
149        }
150        // check if a column alias was used (column_name as field_name)
151        if (preg_match("/(\w+)\sas\s(\w+)/i", $column['name'], $matches)) {
152            $name = $matches[1];
153            $column['name'] = $name;
154            $column['alias'] = $matches[2];
155        }
156        if (preg_match("/([a-zA-Z]+)\(([0-9]+)\)/", $column['type'], $matches)) {
157            $column['type'] = $matches[1];
158            $column['length'] = $matches[2];
159        }
160        $column['type'] = strtolower($column['type']);
161        // check if legacy column type (1.x) needs to be mapped to a 2.0 one
162        if (isset($this->_legacyTypeMap[$column['type']])) {
163            $column['type'] = $this->_legacyTypeMap[$column['type']];
164        }
165        if ( ! \Doctrine\DBAL\Types\Type::hasType($column['type'])) {
166            throw ToolsException::couldNotMapDoctrine1Type($column['type']);
167        }
168
169        $fieldMapping = array();
170        if (isset($column['primary'])) {
171            $fieldMapping['id'] = true;
172        }
173        $fieldMapping['fieldName'] = isset($column['alias']) ? $column['alias'] : $name;
174        $fieldMapping['columnName'] = $column['name'];
175        $fieldMapping['type'] = $column['type'];
176        if (isset($column['length'])) {
177            $fieldMapping['length'] = $column['length'];
178        }
179        $allowed = array('precision', 'scale', 'unique', 'options', 'notnull', 'version');
180        foreach ($column as $key => $value) {
181            if (in_array($key, $allowed)) {
182                $fieldMapping[$key] = $value;
183            }
184        }
185
186        $metadata->mapField($fieldMapping);
187
188        if (isset($column['autoincrement'])) {
189            $metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_AUTO);
190        } else if (isset($column['sequence'])) {
191            $metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_SEQUENCE);
192            $definition = array(
193                'sequenceName' => is_array($column['sequence']) ? $column['sequence']['name']:$column['sequence']
194            );
195            if (isset($column['sequence']['size'])) {
196                $definition['allocationSize'] = $column['sequence']['size'];
197            }
198            if (isset($column['sequence']['value'])) {
199                $definition['initialValue'] = $column['sequence']['value'];
200            }
201            $metadata->setSequenceGeneratorDefinition($definition);
202        }
203        return $fieldMapping;
204    }
205
206    private function _convertIndexes($className, array $model, ClassMetadataInfo $metadata)
207    {
208        if (isset($model['indexes']) && $model['indexes']) {
209            foreach ($model['indexes'] as $name => $index) {
210                $type = (isset($index['type']) && $index['type'] == 'unique')
211                    ? 'uniqueConstraints' : 'indexes';
212
213                $metadata->table[$type][$name] = array(
214                    'columns' => $index['fields']
215                );
216            }
217        }
218    }
219
220    private function _convertRelations($className, array $model, ClassMetadataInfo $metadata)
221    {
222        if (isset($model['relations']) && $model['relations']) {
223            foreach ($model['relations'] as $name => $relation) {
224                if ( ! isset($relation['alias'])) {
225                    $relation['alias'] = $name;
226                }
227                if ( ! isset($relation['class'])) {
228                    $relation['class'] = $name;
229                }
230                if ( ! isset($relation['local'])) {
231                    $relation['local'] = Inflector::tableize($relation['class']);
232                }
233                if ( ! isset($relation['foreign'])) {
234                    $relation['foreign'] = 'id';
235                }
236                if ( ! isset($relation['foreignAlias'])) {
237                    $relation['foreignAlias'] = $className;
238                }
239
240                if (isset($relation['refClass'])) {
241                    $type = 'many';
242                    $foreignType = 'many';
243                    $joinColumns = array();
244                } else {
245                    $type = isset($relation['type']) ? $relation['type'] : 'one';
246                    $foreignType = isset($relation['foreignType']) ? $relation['foreignType'] : 'many';
247                    $joinColumns = array(
248                        array(
249                            'name' => $relation['local'],
250                            'referencedColumnName' => $relation['foreign'],
251                            'onDelete' => isset($relation['onDelete']) ? $relation['onDelete'] : null,
252                        )
253                    );
254                }
255
256                if ($type == 'one' && $foreignType == 'one') {
257                    $method = 'mapOneToOne';
258                } else if ($type == 'many' && $foreignType == 'many') {
259                    $method = 'mapManyToMany';
260                } else {
261                    $method = 'mapOneToMany';
262                }
263
264                $associationMapping = array();
265                $associationMapping['fieldName'] = $relation['alias'];
266                $associationMapping['targetEntity'] = $relation['class'];
267                $associationMapping['mappedBy'] = $relation['foreignAlias'];
268                $associationMapping['joinColumns'] = $joinColumns;
269
270                $metadata->$method($associationMapping);
271            }
272        }
273    }
274}
Note: See TracBrowser for help on using the repository browser.