Rajout de doctrine/orm
[zf2.biz/galerie.git] / vendor / doctrine / orm / lib / Doctrine / ORM / Tools / Export / Driver / XmlExporter.php
1 <?php
2 /*
3  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14  *
15  * This software consists of voluntary contributions made by many individuals
16  * and is licensed under the MIT license. For more information, see
17  * <http://www.doctrine-project.org>.
18  */
19
20 namespace Doctrine\ORM\Tools\Export\Driver;
21
22 use Doctrine\ORM\Mapping\ClassMetadataInfo;
23
24 /**
25  * ClassMetadata exporter for Doctrine XML mapping files
26  *
27  * 
28  * @link    www.doctrine-project.org
29  * @since   2.0
30  * @author  Jonathan Wage <jonwage@gmail.com>
31  */
32 class XmlExporter extends AbstractExporter
33 {
34     protected $_extension = '.dcm.xml';
35
36     /**
37      * Converts a single ClassMetadata instance to the exported format
38      * and returns it
39      *
40      * @param ClassMetadataInfo $metadata
41      * @return mixed $exported
42      */
43     public function exportClassMetadata(ClassMetadataInfo $metadata)
44     {
45         $xml = new \SimpleXmlElement("<?xml version=\"1.0\" encoding=\"utf-8\"?><doctrine-mapping ".
46             "xmlns=\"http://doctrine-project.org/schemas/orm/doctrine-mapping\" " .
47             "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ".
48             "xsi:schemaLocation=\"http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd\" />");
49
50         /*$xml->addAttribute('xmlns', 'http://doctrine-project.org/schemas/orm/doctrine-mapping');
51         $xml->addAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');
52         $xml->addAttribute('xsi:schemaLocation', 'http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd');*/
53
54         if ($metadata->isMappedSuperclass) {
55             $root = $xml->addChild('mapped-superclass');
56         } else {
57             $root = $xml->addChild('entity');
58         }
59
60         if ($metadata->customRepositoryClassName) {
61             $root->addAttribute('repository-class', $metadata->customRepositoryClassName);
62         }
63
64         $root->addAttribute('name', $metadata->name);
65
66         if (isset($metadata->table['name'])) {
67             $root->addAttribute('table', $metadata->table['name']);
68         }
69
70         if (isset($metadata->table['schema'])) {
71             $root->addAttribute('schema', $metadata->table['schema']);
72         }
73
74         if (isset($metadata->table['inheritance-type'])) {
75             $root->addAttribute('inheritance-type', $metadata->table['inheritance-type']);
76         }
77
78         if ($metadata->discriminatorColumn) {
79             $discriminatorColumnXml = $root->addChild('discriminiator-column');
80             $discriminatorColumnXml->addAttribute('name', $metadata->discriminatorColumn['name']);
81             $discriminatorColumnXml->addAttribute('type', $metadata->discriminatorColumn['type']);
82             $discriminatorColumnXml->addAttribute('length', $metadata->discriminatorColumn['length']);
83         }
84
85         if ($metadata->discriminatorMap) {
86             $discriminatorMapXml = $root->addChild('discriminator-map');
87             foreach ($metadata->discriminatorMap as $value => $className) {
88                 $discriminatorMappingXml = $discriminatorMapXml->addChild('discriminator-mapping');
89                 $discriminatorMappingXml->addAttribute('value', $value);
90                 $discriminatorMappingXml->addAttribute('class', $className);
91             }
92         }
93
94         $trackingPolicy = $this->_getChangeTrackingPolicyString($metadata->changeTrackingPolicy);
95         if ( $trackingPolicy != 'DEFERRED_IMPLICIT') {
96             $root->addChild('change-tracking-policy', $trackingPolicy);
97         }
98
99         if (isset($metadata->table['indexes'])) {
100             $indexesXml = $root->addChild('indexes');
101
102             foreach ($metadata->table['indexes'] as $name => $index) {
103                 $indexXml = $indexesXml->addChild('index');
104                 $indexXml->addAttribute('name', $name);
105                 $indexXml->addAttribute('columns', implode(',', $index['columns']));
106             }
107         }
108
109         if (isset($metadata->table['uniqueConstraints'])) {
110             $uniqueConstraintsXml = $root->addChild('unique-constraints');
111
112             foreach ($metadata->table['uniqueConstraints'] as $unique) {
113                 $uniqueConstraintXml = $uniqueConstraintsXml->addChild('unique-constraint');
114                 $uniqueConstraintXml->addAttribute('name', $unique['name']);
115                 $uniqueConstraintXml->addAttribute('columns', implode(',', $unique['columns']));
116             }
117         }
118
119         $fields = $metadata->fieldMappings;
120
121         $id = array();
122         foreach ($fields as $name => $field) {
123             if (isset($field['id']) && $field['id']) {
124                 $id[$name] = $field;
125                 unset($fields[$name]);
126             }
127         }
128
129         if ( ! $metadata->isIdentifierComposite && $idGeneratorType = $this->_getIdGeneratorTypeString($metadata->generatorType)) {
130             $id[$metadata->getSingleIdentifierFieldName()]['generator']['strategy'] = $idGeneratorType;
131         }
132
133         if ($id) {
134             foreach ($id as $field) {
135                 $idXml = $root->addChild('id');
136                 $idXml->addAttribute('name', $field['fieldName']);
137                 $idXml->addAttribute('type', $field['type']);
138                 if (isset($field['columnName'])) {
139                     $idXml->addAttribute('column', $field['columnName']);
140                 }
141                 if (isset($field['associationKey']) && $field['associationKey']) {
142                     $idXml->addAttribute('association-key', 'true');
143                 }
144                 if ($idGeneratorType = $this->_getIdGeneratorTypeString($metadata->generatorType)) {
145                     $generatorXml = $idXml->addChild('generator');
146                     $generatorXml->addAttribute('strategy', $idGeneratorType);
147                 }
148             }
149         }
150
151         if ($fields) {
152             foreach ($fields as $field) {
153                 $fieldXml = $root->addChild('field');
154                 $fieldXml->addAttribute('name', $field['fieldName']);
155                 $fieldXml->addAttribute('type', $field['type']);
156                 if (isset($field['columnName'])) {
157                     $fieldXml->addAttribute('column', $field['columnName']);
158                 }
159                 if (isset($field['length'])) {
160                     $fieldXml->addAttribute('length', $field['length']);
161                 }
162                 if (isset($field['precision'])) {
163                     $fieldXml->addAttribute('precision', $field['precision']);
164                 }
165                 if (isset($field['scale'])) {
166                     $fieldXml->addAttribute('scale', $field['scale']);
167                 }
168                 if (isset($field['unique']) && $field['unique']) {
169                     $fieldXml->addAttribute('unique', $field['unique']);
170                 }
171                 if (isset($field['options'])) {
172                     $optionsXml = $fieldXml->addChild('options');
173                     foreach ($field['options'] as $key => $value) {
174                         $optionsXml->addAttribute($key, $value);
175                     }
176                 }
177                 if (isset($field['version'])) {
178                     $fieldXml->addAttribute('version', $field['version']);
179                 }
180                 if (isset($field['columnDefinition'])) {
181                     $fieldXml->addAttribute('column-definition', $field['columnDefinition']);
182                 }
183                 if (isset($field['nullable'])) {
184                     $fieldXml->addAttribute('nullable', $field['nullable'] ? 'true' : 'false');
185                 }
186             }
187         }
188         $orderMap = array(
189             ClassMetadataInfo::ONE_TO_ONE,
190             ClassMetadataInfo::ONE_TO_MANY,
191             ClassMetadataInfo::MANY_TO_ONE,
192             ClassMetadataInfo::MANY_TO_MANY,
193         );
194         uasort($metadata->associationMappings, function($m1, $m2)use(&$orderMap){
195             $a1 = array_search($m1['type'],$orderMap);
196             $a2 = array_search($m2['type'],$orderMap);
197             return strcmp($a1, $a2);
198         });
199         foreach ($metadata->associationMappings as $name => $associationMapping) {
200             if ($associationMapping['type'] == ClassMetadataInfo::ONE_TO_ONE) {
201                 $associationMappingXml = $root->addChild('one-to-one');
202             } else if ($associationMapping['type'] == ClassMetadataInfo::MANY_TO_ONE) {
203                 $associationMappingXml = $root->addChild('many-to-one');
204             } else if ($associationMapping['type'] == ClassMetadataInfo::ONE_TO_MANY) {
205                 $associationMappingXml = $root->addChild('one-to-many');
206             } else if ($associationMapping['type'] == ClassMetadataInfo::MANY_TO_MANY) {
207                 $associationMappingXml = $root->addChild('many-to-many');
208             }
209
210             $associationMappingXml->addAttribute('field', $associationMapping['fieldName']);
211             $associationMappingXml->addAttribute('target-entity', $associationMapping['targetEntity']);
212
213             if (isset($associationMapping['mappedBy'])) {
214                 $associationMappingXml->addAttribute('mapped-by', $associationMapping['mappedBy']);
215             }
216             if (isset($associationMapping['inversedBy'])) {
217                 $associationMappingXml->addAttribute('inversed-by', $associationMapping['inversedBy']);
218             }
219             if (isset($associationMapping['indexBy'])) {
220                 $associationMappingXml->addAttribute('index-by', $associationMapping['indexBy']);
221             }
222             if (isset($associationMapping['orphanRemoval']) && $associationMapping['orphanRemoval']!==false) {
223                 $associationMappingXml->addAttribute('orphan-removal', 'true');
224             }
225             if (isset($associationMapping['joinTable']) && $associationMapping['joinTable']) {
226                 $joinTableXml = $associationMappingXml->addChild('join-table');
227                 $joinTableXml->addAttribute('name', $associationMapping['joinTable']['name']);
228                 $joinColumnsXml = $joinTableXml->addChild('join-columns');
229                 foreach ($associationMapping['joinTable']['joinColumns'] as $joinColumn) {
230                     $joinColumnXml = $joinColumnsXml->addChild('join-column');
231                     $joinColumnXml->addAttribute('name', $joinColumn['name']);
232                     $joinColumnXml->addAttribute('referenced-column-name', $joinColumn['referencedColumnName']);
233                     if (isset($joinColumn['onDelete'])) {
234                         $joinColumnXml->addAttribute('on-delete', $joinColumn['onDelete']);
235                     }
236                 }
237                 $inverseJoinColumnsXml = $joinTableXml->addChild('inverse-join-columns');
238                 foreach ($associationMapping['joinTable']['inverseJoinColumns'] as $inverseJoinColumn) {
239                     $inverseJoinColumnXml = $inverseJoinColumnsXml->addChild('join-column');
240                     $inverseJoinColumnXml->addAttribute('name', $inverseJoinColumn['name']);
241                     $inverseJoinColumnXml->addAttribute('referenced-column-name', $inverseJoinColumn['referencedColumnName']);
242                     if (isset($inverseJoinColumn['onDelete'])) {
243                         $inverseJoinColumnXml->addAttribute('on-delete', $inverseJoinColumn['onDelete']);
244                     }
245                     if (isset($inverseJoinColumn['columnDefinition'])) {
246                         $inverseJoinColumnXml->addAttribute('column-definition', $inverseJoinColumn['columnDefinition']);
247                     }
248                     if (isset($inverseJoinColumn['nullable'])) {
249                         $inverseJoinColumnXml->addAttribute('nullable', $inverseJoinColumn['nullable']);
250                     }
251                     if (isset($inverseJoinColumn['orderBy'])) {
252                         $inverseJoinColumnXml->addAttribute('order-by', $inverseJoinColumn['orderBy']);
253                     }
254                 }
255             }
256             if (isset($associationMapping['joinColumns'])) {
257                 $joinColumnsXml = $associationMappingXml->addChild('join-columns');
258                 foreach ($associationMapping['joinColumns'] as $joinColumn) {
259                     $joinColumnXml = $joinColumnsXml->addChild('join-column');
260                     $joinColumnXml->addAttribute('name', $joinColumn['name']);
261                     $joinColumnXml->addAttribute('referenced-column-name', $joinColumn['referencedColumnName']);
262                     if (isset($joinColumn['onDelete'])) {
263                         $joinColumnXml->addAttribute('on-delete', $joinColumn['onDelete']);
264                     }
265                     if (isset($joinColumn['columnDefinition'])) {
266                         $joinColumnXml->addAttribute('column-definition', $joinColumn['columnDefinition']);
267                     }
268                     if (isset($joinColumn['nullable'])) {
269                         $joinColumnXml->addAttribute('nullable', $joinColumn['nullable']);
270                     }
271                 }
272             }
273             if (isset($associationMapping['orderBy'])) {
274                 $orderByXml = $associationMappingXml->addChild('order-by');
275                 foreach ($associationMapping['orderBy'] as $name => $direction) {
276                     $orderByFieldXml = $orderByXml->addChild('order-by-field');
277                     $orderByFieldXml->addAttribute('name', $name);
278                     $orderByFieldXml->addAttribute('direction', $direction);
279                 }
280             }
281             $cascade = array();
282             if ($associationMapping['isCascadeRemove']) {
283                 $cascade[] = 'cascade-remove';
284             }
285             if ($associationMapping['isCascadePersist']) {
286                 $cascade[] = 'cascade-persist';
287             }
288             if ($associationMapping['isCascadeRefresh']) {
289                 $cascade[] = 'cascade-refresh';
290             }
291             if ($associationMapping['isCascadeMerge']) {
292                 $cascade[] = 'cascade-merge';
293             }
294             if ($associationMapping['isCascadeDetach']) {
295                 $cascade[] = 'cascade-detach';
296             }
297             if (count($cascade) === 5) {
298                 $cascade  = array('cascade-all');
299             }
300             if ($cascade) {
301                 $cascadeXml = $associationMappingXml->addChild('cascade');
302                 foreach ($cascade as $type) {
303                     $cascadeXml->addChild($type);
304                 }
305             }
306         }
307
308         if (isset($metadata->lifecycleCallbacks) && count($metadata->lifecycleCallbacks)>0) {
309             $lifecycleCallbacksXml = $root->addChild('lifecycle-callbacks');
310             foreach ($metadata->lifecycleCallbacks as $name => $methods) {
311                 foreach ($methods as $method) {
312                     $lifecycleCallbackXml = $lifecycleCallbacksXml->addChild('lifecycle-callback');
313                     $lifecycleCallbackXml->addAttribute('type', $name);
314                     $lifecycleCallbackXml->addAttribute('method', $method);
315                 }
316             }
317         }
318
319         return $this->_asXml($xml);
320     }
321
322     /**
323      * @param \SimpleXMLElement $simpleXml
324      * @return string $xml
325      */
326     private function _asXml($simpleXml)
327     {
328         $dom = new \DOMDocument('1.0', 'UTF-8');
329         $dom->loadXML($simpleXml->asXML());
330         $dom->formatOutput = true;
331
332         $result = $dom->saveXML();
333         return $result;
334     }
335 }