Coverage for Doctrine_Import_Builder

Back to coverage report

1 <?php
2 /*
3  *  $Id: Builder.php 3174 2007-11-15 23:26:29Z 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.phpdoctrine.com>.
20  */
21
22 /**
23  * Doctrine_Import_Builder
24  *
25  * Import builder is responsible of building Doctrine_Record classes
26  * based on a database schema.
27  *
28  * @package     Doctrine
29  * @subpackage  Import
30  * @link        www.phpdoctrine.com
31  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
32  * @since       1.0
33  * @version     $Revision: 3174 $
34  * @author      Konsta Vesterinen <kvesteri@cc.hut.fi>
35  * @author      Jukka Hassinen <Jukka.Hassinen@BrainAlliance.com>
36  * @author      Nicolas BĂ©rard-Nault <nicobn@php.net>
37  * @author      Jonathan H. Wage <jwage@mac.com>
38  */
39 class Doctrine_Import_Builder
40 {
41     /**
42      * Path
43      * 
44      * the path where imported files are being generated
45      *
46      * @var string $_path
47      */
48     protected $_path = '';
49     
50     /**
51      * packagesPrefix
52      *
53      * @var string
54      */
55     protected $_packagesPrefix = 'Package';
56
57     /**
58      * packagesPath
59      *
60      * @var string
61      */
62     protected $_packagesPath = '';
63     
64     /**
65      * suffix
66      * 
67      * File suffix to use when writing class definitions
68      *
69      * @var string $suffix
70      */
71     protected $_suffix = '.php';
72
73     /**
74      * generateBaseClasses
75      * 
76      * Bool true/false for whether or not to generate base classes
77      *
78      * @var string $suffix
79      */
80     protected $_generateBaseClasses = true;
81     
82     /**
83      * generateTableClasses
84      *
85      * @var string
86      */
87     protected $_generateTableClasses = true;
88     
89     /**
90      * baseClassesDirectory
91      * 
92      * Directory to put the generate base classes in
93      *
94      * @var string $suffix
95      */
96     protected $_baseClassesDirectory = 'generated';
97     
98     /**
99      * baseClassName
100      *
101      * @var string
102      */
103     protected $_baseClassName = 'Doctrine_Record';
104     
105     /**
106      * tpl
107      *
108      * Class template used for writing classes
109      *
110      * @var $_tpl
111      */
112     protected static $_tpl;
113
114     /**
115      * __construct
116      *
117      * @return void
118      */
119     public function __construct()
120     {
121         $this->loadTemplate();
122     }
123
124     /**
125      * setTargetPath
126      *
127      * @param string path   the path where imported files are being generated
128      * @return
129      */
130     public function setTargetPath($path)
131     {
132         if ( ! $this->_packagesPath) {
133             $this->setPackagesPath($path . DIRECTORY_SEPARATOR . 'packages');
134         }
135
136         $this->_path = $path;
137     }
138     
139     /**
140      * setPackagePath
141      *
142      * @param string $packagesPrefix 
143      * @return void
144      */
145     public function setPackagesPrefix($packagesPrefix)
146     {
147         $this->_packagesPrefix = $packagesPrefix;
148     }
149
150     /**
151      * setPackagesPath
152      *
153      * @param string $packagesPath 
154      * @return void
155      */
156     public function setPackagesPath($packagesPath)
157     {
158         $this->_packagesPath = $packagesPath;
159     }
160     
161     /**
162      * generateBaseClasses
163      *
164      * Specify whether or not to generate classes which extend from generated base classes
165      *
166      * @param string $bool
167      * @return void
168      */
169     public function generateBaseClasses($bool = null)
170     {
171         if ($bool !== null) {
172             $this->_generateBaseClasses = $bool;
173         }
174
175         return $this->_generateBaseClasses;
176     }
177     
178     /**
179      * generateTableClasses
180      *
181      * Specify whether or not to generate table classes which extend from Doctrine_Table
182      *
183      * @param string $bool
184      * @return void
185      */
186     public function generateTableClasses($bool = null)
187     {
188         if ($bool !== null) {
189             $this->_generateTableClasses = $bool;
190         }
191
192         return $this->_generateTableClasses;
193     }
194
195     /**
196      * setBaseClassesDirectory
197      *
198      * @return void
199      */
200     public function setBaseClassesDirectory($baseClassesDirectory)
201     {
202         $this->_baseClassesDirectory;
203     }
204     
205     /**
206      * setBaseClassName
207      *
208      * @package default
209      */
210     public function setBaseClassName($className)
211     {
212         $this->_baseClassName = $className;
213     }
214     
215     /**
216      * setSuffix
217      *
218      * @param string $suffix 
219      * @return void
220      */
221     public function setSuffix($suffix)
222     {
223         $this->_suffix = $suffix;
224     }
225
226     /**
227      * getTargetPath
228      *
229      * @return string       the path where imported files are being generated
230      */
231     public function getTargetPath()
232     {
233         return $this->_path;
234     }
235
236     /**
237      * setOptions
238      *
239      * @param string $options 
240      * @return void
241      */
242     public function setOptions($options)
243     {
244         if (!empty($options)) {
245             foreach ($options as $key => $value) {
246                 $this->setOption($key, $value);
247             }
248         }
249     }
250
251     /**
252      * setOption
253      *
254      * @param string $key 
255      * @param string $value 
256      * @return void
257      */
258     public function setOption($key, $value)
259     {
260         $name = 'set' . Doctrine::classify($key);
261         
262         if (method_exists($this, $name)) {
263             $this->$name($value);
264         } else {
265             $key = '_' . $key;
266             $this->$key = $value;
267         }
268     }
269
270     /**
271      * loadTemplate
272      * 
273      * Loads the class template used for generating classes
274      *
275      * @return void
276      */
277     public function loadTemplate() 
278     {
279         if (isset(self::$_tpl)) {
280             return;
281         }
282
283         self::$_tpl =<<<END
284 /**
285  * This class has been auto-generated by the Doctrine ORM Framework
286  */
287 %sclass %s extends %s
288 {
289 %s
290 %s
291 %s
292 }
293 END;
294     }
295
296     /*
297      * Build the accessors
298      *
299      * @param  string $table
300      * @param  array  $columns
301      */
302     public function buildAccessors(array $options, array $columns)
303     {
304         $ret = '';
305         foreach ($columns as $name => $column) {
306             // getters
307             $ret .= "\n  public function get".Doctrine::classify($name)."(\$load = true)\n";
308             $ret .= "  {\n";
309             $ret .= "    return \$this->get('{$name}', \$load);\n";
310             $ret .= "  }\n";
311
312             // setters
313             $ret .= "\n  public function set".Doctrine::classify($name)."(\${$name}, \$load = true)\n";
314             $ret .= "  {\n";
315             $ret .= "    return \$this->set('{$name}', \${$name}, \$load);\n";
316             $ret .= "  }\n";
317         }
318
319         return $ret;
320     }
321
322     /*
323      * Build the table definition of a Doctrine_Record object
324      *
325      * @param  string $table
326      * @param  array  $tableColumns
327      */
328     public function buildTableDefinition(array $options, array $columns, array $relations, array $indexes, array $attributes, array $tableOptions)
329     {
330         $ret = array();
331         
332         $i = 0;
333         
334         if (isset($options['inheritance']['extends']) && !(isset($options['override_parent']) && $options['override_parent'] == false)) {
335             $ret[$i] = "    parent::setTableDefinition();";
336             $i++;
337         }
338         
339         if (isset($options['tableName']) && !empty($options['tableName'])) {
340             $ret[$i] = "    ".'$this->setTableName(\''. $options['tableName'].'\');';
341             
342             $i++;
343         }
344         
345         foreach ($columns as $name => $column) {
346             $ret[$i] = "    ".'$this->hasColumn(\'' . $name . '\', \'' . $column['type'] . '\'';
347             
348             if ($column['length']) {
349                 $ret[$i] .= ', ' . $column['length'];
350             } else {
351                 $ret[$i] .= ', null';
352             }
353
354             $options = $column;
355             $unset = array('name', 'type', 'length', 'ptype');
356             foreach ($options as $key => $value) {
357                 if (in_array($key, $unset) || $value === null) {
358                     unset($options[$key]);
359                 }
360             }
361             
362             $ret[$i] .= ', ' . var_export($options, true);
363             
364             $ret[$i] .= ');';
365
366             if ($i < (count($columns) - 1)) {
367                 $ret[$i] .= PHP_EOL;
368             }
369             $i++;
370         }
371         
372         $ret[$i] = $this->buildIndexes($indexes);
373         $i++;
374         
375         $ret[$i] = $this->buildAttributes($attributes);
376         $i++;
377         
378         $ret[$i] = $this->buildTableOptions($tableOptions);
379         
380         $code = implode("\n", $ret);
381         $code = trim($code);
382         
383         if ($code) {
384           return "\n  public function setTableDefinition()"."\n  {\n    ".$code."\n  }";
385         }
386     }
387
388     /**
389      * buildTemplates
390      *
391      * @param string $array 
392      * @return void
393      */
394     public function buildTemplates(array $templates)
395     {
396         $build = '';
397         foreach ($templates as $name => $options) {
398             
399             if (is_array($options) && !empty($options)) {
400                 $optionsPhp = var_export($options, true);
401             
402                 $build .= "    \$this->loadTemplate('" . $name . "', " . $optionsPhp . ");\n";
403             } else {
404                 if (isset($templates[0])) {
405                     $build .= "    \$this->loadTemplate('" . $options . "');\n";
406                 } else {
407                     $build .= "    \$this->loadTemplate('" . $name . "');\n";
408                 }
409             }
410         }
411         
412         return $build;
413     }
414
415     /**
416      * buildActAs
417      *
418      * @param string $array 
419      * @return void
420      */
421     public function buildActAs(array $actAs)
422     {
423         $build = '';
424         foreach ($actAs as $name => $options) {
425             if (is_array($options) && !empty($options)) {
426                 $optionsPhp = var_export($options, true);
427                 
428                 $build .= "    \$this->actAs('" . $name . "', " . $optionsPhp . ");\n";
429             } else {
430                 if (isset($actAs[0])) {
431                     $build .= "    \$this->actAs('" . $options . "');\n";
432                 } else {
433                     $build .= "    \$this->actAs('" . $name . "');\n";
434                 }
435             }
436         }
437         
438         return $build;
439     }
440
441     /**
442      * buildAttributes
443      *
444      * @param string $array 
445      * @return void
446      */
447     public function buildAttributes(array $attributes)
448     {
449         $build = "\n";
450         foreach ($attributes as $key => $value) {
451           
452             if (is_bool($value))
453             {
454               $values = $value ? 'true':'false';
455             } else {
456                 if ( ! is_array($value)) {
457                     $value = array($value);
458                 }
459             
460                 $values = '';
461                 foreach ($value as $attr) {
462                     $values .= "Doctrine::" . strtoupper($key) . "_" . strtoupper($attr) . ' ^ ';
463                 }
464                 
465                 // Trim last ^
466                 $values = substr($values, 0, strlen($values) - 3);
467             }
468             
469             $build .= "    \$this->setAttribute(Doctrine::ATTR_" . strtoupper($key) . ", " . $values . ");\n";
470         }
471         
472         return $build;
473     }
474     
475     /**
476      * buildTableOptions
477      *
478      * @param string $array 
479      * @return void
480      */
481     public function buildTableOptions(array $options)
482     {
483         $build = '';
484         foreach ($options as $name => $value) {
485             $build .= "    \$this->option('$name', " . var_export($value, true) . ");\n";
486         }
487         
488         return $build;
489     }
490
491     /**
492      * buildIndexes
493      *
494      * @param string $array 
495      * @return void
496      */
497     public function buildIndexes(array $indexes)
498     {
499       $build = '';
500
501       foreach ($indexes as $indexName => $definitions) {
502           $build .= "\n    \$this->index('" . $indexName . "'";
503           $build .= ', ' . var_export($definitions, true);
504           $build .= ');';
505       }
506
507       return $build;
508     }
509
510     /**
511      * buildSetUp
512      *
513      * @param  array $options 
514      * @param  array $columns 
515      * @param  array $relations 
516      * @return string
517      */
518     public function buildSetUp(array $options, array $columns, array $relations, array $templates, array $actAs)
519     {
520         $ret = array();
521         $i = 0;
522         
523         if (isset($options['inheritance']['extends']) && !(isset($options['override_parent']) && $options['override_parent'] == false)) {
524             $ret[$i] = "    parent::setUp();";
525             $i++;
526         }
527         
528         foreach ($relations as $name => $relation) {
529             $class = isset($relation['class']) ? $relation['class']:$name;
530             $alias = (isset($relation['alias']) && $relation['alias'] !== $relation['class']) ? ' as ' . $relation['alias'] : '';
531
532             if ( ! isset($relation['type'])) {
533                 $relation['type'] = Doctrine_Relation::ONE;
534             }
535
536             if ($relation['type'] === Doctrine_Relation::ONE || 
537                 $relation['type'] === Doctrine_Relation::ONE_COMPOSITE) {
538                 $ret[$i] = "    ".'$this->hasOne(\'' . $class . $alias . '\'';
539             } else {
540                 $ret[$i] = "    ".'$this->hasMany(\'' . $class . $alias . '\'';
541             }
542             
543             $a = array();
544
545             if (isset($relation['refClass'])) {
546                 $a[] = '\'refClass\' => ' . var_export($relation['refClass'], true);
547             }
548             
549             if (isset($relation['deferred']) && $relation['deferred']) {
550                 $a[] = '\'default\' => ' . var_export($relation['deferred'], true);
551             }
552             
553             if (isset($relation['local']) && $relation['local']) {
554                 $a[] = '\'local\' => ' . var_export($relation['local'], true);
555             }
556             
557             if (isset($relation['foreign']) && $relation['foreign']) {
558                 $a[] = '\'foreign\' => ' . var_export($relation['foreign'], true);
559             }
560             
561             if (isset($relation['onDelete']) && $relation['onDelete']) {
562                 $a[] = '\'onDelete\' => ' . var_export($relation['onDelete'], true);
563             }
564             
565             if (isset($relation['onUpdate']) && $relation['onUpdate']) {
566                 $a[] = '\'onUpdate\' => ' . var_export($relation['onUpdate'], true);
567             }
568             
569             if (isset($relation['equal']) && $relation['equal']) { 
570                 $a[] = '\'equal\' => ' . var_export($relation['equal'], true); 
571             }
572             
573             if ( ! empty($a)) {
574                 $ret[$i] .= ', ' . 'array(';
575                 $length = strlen($ret[$i]);
576                 $ret[$i] .= implode(',' . PHP_EOL . str_repeat(' ', $length), $a) . ')';
577             }
578             
579             $ret[$i] .= ');'."\n";
580             $i++;
581         }
582         
583         if (isset($options['inheritance']['keyField']) && isset($options['inheritance']['keyValue'])) {
584             $i++;
585             $ret[$i] = "    ".'$this->setInheritanceMap(array(\''.$options['inheritance']['keyField'].'\' => \''.$options['inheritance']['keyValue'].'\'));';
586         }
587         
588         $ret[$i] = $this->buildTemplates($templates);
589         $i++;
590         
591         $ret[$i] = $this->buildActAs($actAs);
592         $i++;
593         
594         $code = implode("\n", $ret);
595         $code = trim($code);
596         
597         if ($code) {
598           return "\n  public function setUp()\n  {\n    ".$code."\n  }";
599         }
600     }
601
602     /**
603      * buildDefinition
604      *
605      * @param array $options 
606      * @param array $columns 
607      * @param array $relations 
608      * @param array $indexes 
609      * @param array $attributes 
610      * @param array $templates 
611      * @param array $actAs 
612      * @return string
613      */
614     public function buildDefinition(array $options, array $columns, array $relations = array(), array $indexes = array(), $attributes = array(), array $templates = array(), array $actAs = array(), array $tableOptions = array())
615     {
616         if ( ! isset($options['className'])) {
617             throw new Doctrine_Import_Builder_Exception('Missing class name.');
618         }
619
620         $abstract = isset($options['abstract']) && $options['abstract'] === true ? 'abstract ':null;
621         $className = $options['className'];
622         $extends = isset($options['inheritance']['extends']) ? $options['inheritance']['extends']:$this->_baseClassName;
623
624         if ( ! (isset($options['no_definition']) && $options['no_definition'] === true)) {
625             $definition = $this->buildTableDefinition($options, $columns, $relations, $indexes, $attributes, $tableOptions);
626             $setUp = $this->buildSetUp($options, $columns, $relations, $templates, $actAs);
627         } else {
628             $definition = null;
629             $setUp = null;
630         }
631         
632         $accessors = (isset($options['generate_accessors']) && $options['generate_accessors'] === true) ? $this->buildAccessors($options, $columns):null;
633         
634         $content = sprintf(self::$_tpl, $abstract,
635                                        $className,
636                                        $extends,
637                                        $definition,
638                                        $setUp,
639                                        $accessors);
640         
641         return $content;
642     }
643
644     /**
645      * buildRecord
646      *
647      * @param array $options 
648      * @param array $columns 
649      * @param array $relations 
650      * @param array $indexes 
651      * @param array $attributes 
652      * @param array $templates 
653      * @param array $actAs 
654      * @return void=
655      */
656     public function buildRecord(array $options, array $columns, array $relations = array(), array $indexes = array(), array $attributes = array(), array $templates = array(), array $actAs = array(), array $tableOptions = array())
657     {
658         if ( !isset($options['className'])) {
659             throw new Doctrine_Import_Builder_Exception('Missing class name.');
660         }
661
662         if ($this->generateBaseClasses()) {
663             $options['is_package'] = (isset($options['package']) && $options['package']) ? true:false;
664             
665             if ($options['is_package']) {
666                 $e = explode('.', $options['package']);
667                 $options['package_name'] = $e[0];
668                 unset($e[0]);
669                 
670                 $options['package_path'] = implode(DIRECTORY_SEPARATOR, $e);
671             }
672             
673             // Top level definition that extends from all the others
674             $topLevel = $options;
675             unset($topLevel['tableName']);
676             
677             // If we have a package then we need to make this extend the package definition and not the base definition
678             // The package definition will then extends the base definition
679             $topLevel['inheritance']['extends'] = (isset($topLevel['package']) && $topLevel['package']) ? $this->_packagesPrefix . $topLevel['className']:'Base' . $topLevel['className'];
680             $topLevel['no_definition'] = true;
681             $topLevel['generate_once'] = true;
682             $topLevel['is_main_class'] = true;
683             unset($topLevel['connection']);
684
685             // Package level definition that extends from the base definition
686             if (isset($options['package'])) {
687                 
688                 $packageLevel = $options;
689                 $packageLevel['className'] = $topLevel['inheritance']['extends'];
690                 $packageLevel['inheritance']['extends'] = 'Base' . $topLevel['className'];
691                 $packageLevel['no_definition'] = true;
692                 $packageLevel['abstract'] = true;
693                 $packageLevel['override_parent'] = true;
694                 $packageLevel['generate_once'] = true;
695                 $packageLevel['is_package_class'] = true;
696                 unset($packageLevel['connection']);
697             }
698
699             $baseClass = $options;
700             $baseClass['className'] = 'Base' . $baseClass['className'];
701             $baseClass['abstract'] = true;
702             $baseClass['override_parent'] = true;
703             $baseClass['is_base_class'] = true;
704
705             $this->writeDefinition($baseClass, $columns, $relations, $indexes, $attributes, $templates, $actAs, $tableOptions);
706             
707             if (!empty($packageLevel)) {
708                 $this->writeDefinition($packageLevel);
709             }
710             
711             $this->writeDefinition($topLevel);
712         } else {
713             $this->writeDefinition($options, $columns, $relations, $indexes, $attributes, $templates, $actAs, $tableOptions);
714         }
715     }
716     
717     /**
718      * writeTableDefinition
719      *
720      * @return void
721      */
722     public function writeTableDefinition($className, $path, $options = array())
723     {
724         $className = $className . 'Table';
725         
726         $content  = '<?php' . PHP_EOL;
727         $content .= sprintf(self::$_tpl, false,
728                                        $className,
729                                        isset($options['extends']) ? $options['extends']:'Doctrine_Table',
730                                        null,
731                                        null,
732                                        null
733                                        );
734         
735         Doctrine::makeDirectories($path);
736         
737         $writePath = $path . DIRECTORY_SEPARATOR . $className . $this->_suffix;
738         
739         if (!file_exists($writePath)) {
740             file_put_contents($writePath, $content);
741         }
742     }
743     
744     /**
745      * writeDefinition
746      *
747      * @param array $options 
748      * @param array $columns 
749      * @param array $relations 
750      * @param array $indexes 
751      * @param array $attributes 
752      * @param array $templates 
753      * @param array $actAs 
754      * @return void
755      */
756     public function writeDefinition(array $options, array $columns = array(), array $relations = array(), array $indexes = array(), array $attributes = array(), array $templates = array(), array $actAs = array(), array $tableOptions = array())
757     {
758         $definition = $this->buildDefinition($options, $columns, $relations, $indexes, $attributes, $templates, $actAs, $tableOptions);
759
760         $fileName = $options['className'] . $this->_suffix;
761
762         $packagesPath = $this->_packagesPath ? $this->_packagesPath:$this->_path;
763
764         // If this is a main class that either extends from Base or Package class
765         if (isset($options['is_main_class']) && $options['is_main_class']) {
766             // If is package then we need to put it in a package subfolder
767             if (isset($options['is_package']) && $options['is_package']) {
768                 $writePath = $this->_path . DIRECTORY_SEPARATOR . $options['package_name'];
769                 
770                 $this->writeTableDefinition($options['className'], $writePath, array('extends' => $options['inheritance']['extends'] . 'Table'));
771             // Otherwise lets just put it in the root of the path
772             } else {
773                 $writePath = $this->_path;
774                 
775                 $this->writeTableDefinition($options['className'], $writePath);
776             }
777         }
778
779         // If is the package class then we need to make the path to the complete package
780         if (isset($options['is_package_class']) && $options['is_package_class']) {
781             $path = str_replace('.', DIRECTORY_SEPARATOR, trim($options['package']));
782             
783             $writePath = $packagesPath . DIRECTORY_SEPARATOR . $path;
784             
785             $this->writeTableDefinition($options['className'], $writePath);
786         }
787         
788         // If it is the base class of the doctrine record definition
789         if (isset($options['is_base_class']) && $options['is_base_class']) {
790             // If it is a part of a package then we need to put it in a package subfolder
791             if (isset($options['is_package']) && $options['is_package']) {
792                 $writePath  = $this->_path . DIRECTORY_SEPARATOR . $options['package_name'] . DIRECTORY_SEPARATOR . $this->_baseClassesDirectory;
793             // Otherwise lets just put it in the root generated folder
794             } else {
795                 $writePath = $this->_path . DIRECTORY_SEPARATOR . $this->_baseClassesDirectory;
796             }
797         }
798
799         if (isset($writePath)) {
800             Doctrine::makeDirectories($writePath);
801             
802             $writePath .= DIRECTORY_SEPARATOR . $fileName;
803         } else {
804             Doctrine::makeDirectories($this->_path);
805             
806             $writePath = $this->_path . DIRECTORY_SEPARATOR . $fileName;
807         }
808
809         $code = "<?php" . PHP_EOL;
810
811         if (isset($options['connection']) && $options['connection']) {
812             $code .= "// Connection Component Binding\n";
813             $code .= "Doctrine_Manager::getInstance()->bindComponent('" . $options['connectionClassName'] . "', '" . $options['connection'] . "');\n";
814         }
815
816         $code .= PHP_EOL . $definition;
817
818         if (isset($options['generate_once']) && $options['generate_once'] === true) {
819             if (!file_exists($writePath)) {
820                 $bytes = file_put_contents($writePath, $code);
821             }
822         } else {
823             $bytes = file_put_contents($writePath, $code);
824         }
825
826         if (isset($bytes) && $bytes === false) {
827             throw new Doctrine_Import_Builder_Exception("Couldn't write file " . $writePath);
828         }
829     }
830 }