diff --git a/lib/Doctrine/Import/Builder.php b/lib/Doctrine/Import/Builder.php index 789cc8f8e..6fb7e54d1 100644 --- a/lib/Doctrine/Import/Builder.php +++ b/lib/Doctrine/Import/Builder.php @@ -38,6 +38,13 @@ */ class Doctrine_Import_Builder { + /** + * written + * + * @var array + */ + private $written = array(); + /** * Path * @@ -47,12 +54,20 @@ class Doctrine_Import_Builder */ private $path = ''; - private $packagesPrefix = 'Package'; - + /** + * packagesPrefix + * + * @var string + */ + private $packagePrefix = 'Package'; + + /** + * packagesPath + * + * @var string + */ private $packagesPath = ''; - private $pathAfterPackage = DIRECTORY_SEPARATOR; - /** * suffix * @@ -69,8 +84,15 @@ class Doctrine_Import_Builder * * @var string $suffix */ - private $generateBaseClasses = false; - + private $generateBaseClasses = true; + + /** + * generateTableClasses + * + * @var string + */ + private $generateTableClasses = true; + /** * baseClassesDirectory * @@ -107,13 +129,37 @@ class Doctrine_Import_Builder */ public function setTargetPath($path) { - if ( ! file_exists($path)) { - mkdir($path, 0777); + Doctrine::makeDirectories($path); + + if (!$this->packagesPath) { + $this->packagesPath = $path . DIRECTORY_SEPARATOR . 'packages'; } $this->path = $path; } + + /** + * setPackagePath + * + * @param string $packagePrefix + * @return void + */ + public function setPackagePrefix($packagePrefix) + { + $this->packagePrefix = $packagePrefix; + } + /** + * setPackagesPath + * + * @param string $packagesPath + * @return void + */ + public function setPackagesPath($packagesPath) + { + $this->packagesPath = $packagesPath; + } + /** * generateBaseClasses * @@ -121,15 +167,52 @@ class Doctrine_Import_Builder * * @param string $bool * @return void - * @author Jonathan H. Wage */ public function generateBaseClasses($bool = null) { - if ($bool !== null) { - $this->generateBaseClasses = $bool; - } - - return $this->generateBaseClasses; + if ($bool !== null) { + $this->generateBaseClasses = $bool; + } + + return $this->generateBaseClasses; + } + + /** + * generateTableClasses + * + * Specify whether or not to generate table classes which extend from Doctrine_Table + * + * @param string $bool + * @return void + */ + public function generateTableClasses($bool = null) + { + if ($bool !== null) { + $this->generateTableClasses = $bool; + } + + return $this->generateTableClasses; + } + + /** + * setBaseClassesDirectory + * + * @return void + */ + public function setBaseClassesDirectory($baseClassesDirectory) + { + $this->baseClassesDirectory; + } + + /** + * setSuffix + * + * @param string $suffix + * @return void + */ + public function setSuffix($suffix) + { + $this->suffix = $suffix; } /** @@ -586,52 +669,88 @@ END; throw new Doctrine_Import_Builder_Exception('Missing class name.'); } - if ( !isset($options['fileName'])) { - if (empty($this->path)) { - throw new Doctrine_Import_Builder_Exception('No build target directory set.'); - } - - - if (is_writable($this->path) === false) { - throw new Doctrine_Import_Builder_Exception('Build target directory ' . $this->path . ' is not writable.'); - } - - $options['fileName'] = $this->path . DIRECTORY_SEPARATOR . $options['className'] . $this->suffix; - } - if ($this->generateBaseClasses()) { - - // We only want to generate this one if it doesn't already exist - if ( ! file_exists($options['fileName'])) { - $optionsBak = $options; + $options['is_package'] = (isset($options['package']) && $options['package']) ? true:false; - unset($options['tableName']); - $options['inheritance']['extends'] = 'Base' . $options['className']; - $options['requires'] = array($this->baseClassesDirectory . DIRECTORY_SEPARATOR . $options['inheritance']['extends'] . $this->suffix); - $options['no_definition'] = true; + if ($options['is_package']) { + $e = explode('.', $options['package']); + $options['package_name'] = $e[0]; + unset($e[0]); + + $options['package_path'] = implode(DIRECTORY_SEPARATOR, $e); + } - $this->writeDefinition($options); + // Top level definition that extends from all the others + $topLevel = $options; + unset($topLevel['tableName']); - $options = $optionsBak; - } - - $generatedPath = $this->path . DIRECTORY_SEPARATOR . $this->baseClassesDirectory; - - if ( ! file_exists($generatedPath)) { - mkdir($generatedPath); - } - - $options['className'] = 'Base' . $options['className']; - $options['abstract'] = true; - $options['fileName'] = $generatedPath . DIRECTORY_SEPARATOR . $options['className'] . $this->suffix; - $options['override_parent'] = true; - - $this->writeDefinition($options, $columns, $relations, $indexes, $attributes, $templates, $actAs); + // If we have a package then we need to make this extend the package definition and not the base definition + // The package definition will then extends the base definition + $topLevel['inheritance']['extends'] = (isset($topLevel['package']) && $topLevel['package']) ? $this->packagePrefix . $topLevel['className']:'Base' . $topLevel['className']; + $topLevel['no_definition'] = true; + $topLevel['generate_once'] = true; + $topLevel['is_main_class'] = true; + + // Package level definition that extends from the base definition + if (isset($options['package'])) { + + $packageLevel = $options; + $packageLevel['className'] = $topLevel['inheritance']['extends']; + $packageLevel['inheritance']['extends'] = 'Base' . $topLevel['className']; + $packageLevel['no_definition'] = true; + $packageLevel['abstract'] = true; + $packageLevel['override_parent'] = true; + $packageLevel['generate_once'] = true; + $packageLevel['is_package_class'] = true; + } + + $baseClass = $options; + $baseClass['className'] = 'Base' . $baseClass['className']; + $baseClass['abstract'] = true; + $baseClass['override_parent'] = true; + $baseClass['is_base_class'] = true; + + $this->writeDefinition($baseClass, $columns, $relations, $indexes, $attributes, $templates, $actAs); + + if (!empty($packageLevel)) { + $this->writeDefinition($packageLevel); + } + + $this->writeDefinition($topLevel); } else { - $this->writeDefinition($options, $columns, $relations, $indexes, $attributes, $templates, $actAs); + $this->writeDefinition($options, $columns, $relations, $indexes, $attributes, $templates, $actAs); } } - + + /** + * writeTableDefinition + * + * @return void + */ + public function writeTableDefinition($className, $path, $options = array()) + { + $className = $className . 'Table'; + + $content = 'suffix; + + $this->written[$className] = $writePath; + + if (!file_exists($writePath)) { + file_put_contents($writePath, $content); + } + } + /** * writeDefinition * @@ -646,14 +765,64 @@ END; */ public function writeDefinition(array $options, array $columns = array(), array $relations = array(), array $indexes = array(), array $attributes = array(), array $templates = array(), array $actAs = array()) { - $content = $this->buildDefinition($options, $columns, $relations, $indexes, $attributes, $templates, $actAs); - $code = "buildDefinition($options, $columns, $relations, $indexes, $attributes, $templates, $actAs); + + $fileName = $options['className'] . $this->suffix; + + $packagesPath = $this->packagesPath ? $this->packagesPath:$this->path; + + // If this is a main class that either extends from Base or Package class + if (isset($options['is_main_class']) && $options['is_main_class']) { + // If is package then we need to put it in a package subfolder + if (isset($options['is_package']) && $options['is_package']) { + $writePath = $this->path . DIRECTORY_SEPARATOR . $options['package_name']; + + $this->writeTableDefinition($options['className'], $writePath, array('extends' => $options['inheritance']['extends'] . 'Table')); + // Otherwise lets just put it in the root of the path + } else { + $writePath = $this->path; + + $this->writeTableDefinition($options['className'], $writePath); + } + } + + // If is the package class then we need to make the path to the complete package + if (isset($options['is_package_class']) && $options['is_package_class']) { + $path = str_replace('.', DIRECTORY_SEPARATOR, $options['package']); + + $writePath = $packagesPath . DIRECTORY_SEPARATOR . $path; + + $this->writeTableDefinition($options['className'], $writePath); + } + + // If it is the base class of the doctrine record definition + if (isset($options['is_base_class']) && $options['is_base_class']) { + // If it is a part of a package then we need to put it in a package subfolder + if (isset($options['is_package']) && $options['is_package']) { + $writePath = $this->path . DIRECTORY_SEPARATOR . $options['package_name'] . DIRECTORY_SEPARATOR . $this->baseClassesDirectory; + // Otherwise lets just put it in the root generated folder + } else { + $writePath = $this->path . DIRECTORY_SEPARATOR . $this->baseClassesDirectory; + } + } + + if (isset($writePath)) { + Doctrine::makeDirectories($writePath); + + $writePath .= DIRECTORY_SEPARATOR . $fileName; + } else { + Doctrine::makeDirectories($this->path); + + $writePath = $this->path . DIRECTORY_SEPARATOR . $fileName; + } + + $code = "bindComponent('" . $options['connectionClassName'] . "', '" . $options['connection'] . "');\n"; } + + $code .= PHP_EOL . $definition; - $code .= PHP_EOL . $content; + $this->written[$options['className']] = $writePath; + + + if (isset($options['generate_once']) && $options['generate_once'] === true) { + if (!file_exists($writePath)) { + $bytes = file_put_contents($writePath, $code); + } + } else { + $bytes = file_put_contents($writePath, $code); + } - $bytes = file_put_contents($options['fileName'], $code); - - if ($bytes === false) { - throw new Doctrine_Import_Builder_Exception("Couldn't write file " . $options['fileName']); + if (isset($bytes) && $bytes === false) { + throw new Doctrine_Import_Builder_Exception("Couldn't write file " . $writePath); } } } \ No newline at end of file diff --git a/lib/Doctrine/Import/Schema.php b/lib/Doctrine/Import/Schema.php index 817762362..99f2ad1a8 100644 --- a/lib/Doctrine/Import/Schema.php +++ b/lib/Doctrine/Import/Schema.php @@ -121,7 +121,7 @@ class Doctrine_Import_Schema continue; } - $options = $this->getOptions($properties, $directory); + $options = $this->getOptions($properties); $columns = $this->getColumns($properties); $relations = $this->getRelations($properties); $indexes = $this->getIndexes($properties); @@ -136,20 +136,18 @@ class Doctrine_Import_Schema /** * getOptions * - * FIXME: Directory argument needs to be removed - * * @param string $properties Array of table properties * @param string $directory Directory we are writing the class to * @return array $options Array of options from a parse schemas properties */ - public function getOptions($properties, $directory) + public function getOptions($properties) { $options = array(); $options['className'] = $properties['className']; - $options['fileName'] = $directory.DIRECTORY_SEPARATOR.$properties['className'].'.class.php'; $options['tableName'] = isset($properties['tableName']) ? $properties['tableName']:null; $options['connection'] = isset($properties['connection']) ? $properties['connection']:null; $options['connectionClassName'] = isset($properties['connection']) ? $properties['className']:null; + $options['package'] = $properties['package']; if (isset($properties['inheritance'])) { $options['inheritance'] = $properties['inheritance']; @@ -290,6 +288,7 @@ class Doctrine_Import_Schema $build[$className]['attributes'] = isset($table['attributes']) ? $table['attributes']:array(); $build[$className]['templates'] = isset($table['templates']) ? $table['templates']:array(); $build[$className]['actAs'] = isset($table['actAs']) ? $table['actAs']:array(); + $build[$className]['package'] = isset($table['package']) ? $table['package']:null; } if (isset($table['inheritance'])) {