diff --git a/lib/Doctrine/Export/Schema.php b/lib/Doctrine/Export/Schema.php index bbe35b5c3..e64660696 100644 --- a/lib/Doctrine/Export/Schema.php +++ b/lib/Doctrine/Export/Schema.php @@ -57,7 +57,49 @@ abstract class Doctrine_Export_Schema * @param string $schema * @return void */ - abstract function dump($array, $schema); + public function dump($array, $schema) + { + $data = $this->build($array); + + file_put_contents($schema, $data); + } + + public function getDirectoryTables($directory) + { + $parent = new ReflectionClass('Doctrine_Record'); + + $declared = get_declared_classes(); + + if ($directory !== null) { + foreach ((array) $directory as $dir) { + $it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir), + RecursiveIteratorIterator::LEAVES_ONLY); + + foreach ($it as $file) { + $e = explode('.', $file->getFileName()); + + if (end($e) === 'php' && strpos($file->getFileName(), '.inc') === false) { + require_once $file->getPathName(); + } + } + } + + $declared = get_declared_classes(); + + $tables = array(); + foreach($declared as $name) + { + $class = new ReflectionClass($name); + + if ($class->isSubclassOf($parent) AND !$class->isAbstract()) { + $tables[$name] = $name; + } + + } + + return $tables; + } + } /** * buildSchema @@ -69,8 +111,55 @@ abstract class Doctrine_Export_Schema */ public function buildSchema($directory) { - // we need to figure out how we can build all the model information for the passed directory/directories - return array(); + $array = array('tables' => array()); + + $tables = $this->getDirectoryTables($directory); + + $parent = new ReflectionClass('Doctrine_Record'); + + $sql = array(); + $fks = array(); + + // we iterate trhough the diff of previously declared classes + // and currently declared classes + foreach ($tables as $name) { + $class = new ReflectionClass($name); + $conn = Doctrine_Manager::getInstance()->getConnectionForComponent($name); + + // check if class is an instance of Doctrine_Record and not abstract + // class must have method setTableDefinition (to avoid non-Record subclasses like symfony's sfDoctrineRecord) + // we have to recursively iterate through the class parents just to be sure that the classes using for example + // column aggregation inheritance are properly exported to database + while ($class->isAbstract() || + ! $class->isSubclassOf($parent) || + ! $class->hasMethod('setTableDefinition') || + ( $class->hasMethod('setTableDefinition') && + $class->getMethod('setTableDefinition')->getDeclaringClass()->getName() !== $class->getName())) { + + $class = $class->getParentClass(); + if ($class === false) { + break; + } + } + + if ($class === false) { + continue; + } + + $record = new $name(); + $table = $record->getTable(); + + $data = $table->getExportableFormat(); + + $table = array(); + $table['name'] = $data['tableName']; + $table['class'] = get_class($record); + $table['columns'] = $data['columns']; + + $array['tables'][$data['tableName']] = $table; + } + + return $array; } /** @@ -84,6 +173,6 @@ abstract class Doctrine_Export_Schema { $array = $this->buildSchema($directory); - $this->dump($arr, $schema); + return $this->dump($array, $schema); } } \ No newline at end of file diff --git a/lib/Doctrine/Export/Schema/Xml.php b/lib/Doctrine/Export/Schema/Xml.php index 8af837a04..343bfd83e 100644 --- a/lib/Doctrine/Export/Schema/Xml.php +++ b/lib/Doctrine/Export/Schema/Xml.php @@ -41,22 +41,6 @@ class Doctrine_Export_Schema_Xml extends Doctrine_Export_Schema */ public function build($array) { - return Doctrime_Parser::dump($array, null, 'xml'); - } - - /** - * dump - * - * Dump the array to the schema file - * - * @param string $array - * @param string $schema - * @return void - */ - public function dump($array, $schema) - { - $xml = $this->build($array); - - file_put_contents($schema, $xml); + return Doctrine_Parser::dumpXml($array, null); } } \ No newline at end of file diff --git a/lib/Doctrine/Export/Schema/Yml.php b/lib/Doctrine/Export/Schema/Yml.php index e698e4f50..6535fe9d4 100644 --- a/lib/Doctrine/Export/Schema/Yml.php +++ b/lib/Doctrine/Export/Schema/Yml.php @@ -41,22 +41,6 @@ class Doctrine_Export_Schema_Yml extends Doctrine_Export_Schema */ public function build($array) { - return Doctrime_Parser::dump($array, null, 'yml'); - } - - /** - * dump - * - * Dump the array to the schema file - * - * @param string $arr - * @param string $schema - * @return void - */ - public function dump($arr, $schema) - { - $yml = $this->build($array); - - file_put_contents($schema, $yml); + return Doctrine_Parser::dumpYml($array, null); } } \ No newline at end of file diff --git a/lib/Doctrine/Import/Schema/Xml.php b/lib/Doctrine/Import/Schema/Xml.php index 915702748..e86b9e5b1 100644 --- a/lib/Doctrine/Import/Schema/Xml.php +++ b/lib/Doctrine/Import/Schema/Xml.php @@ -52,26 +52,25 @@ class Doctrine_Import_Schema_Xml extends Doctrine_Import_Schema { $xmlObj = $this->parse($schema); - // Go through all tables... - foreach ($xmlObj->table as $table) { + foreach ($xmlObj->tables->table as $table) { $columns = array(); // Go through all columns... - foreach ($table->declaration->field as $field) { + foreach ($table->columns as $column) { $colDesc = array( - 'name' => (string) $field->name, - 'type' => (string) $field->type, - 'ptype' => (string) $field->type, - 'length' => (int) $field->length, - 'fixed' => (int) $field->fixed, - 'unsigned' => (bool) $field->unsigned, - 'primary' => (bool) (isset($field->primary) && $field->primary), - 'default' => (string) $field->default, - 'notnull' => (bool) (isset($field->notnull) && $field->notnull), - 'autoinc' => (bool) (isset($field->autoincrement) && $field->autoincrement), + 'name' => (string) $column->name, + 'type' => (string) $column->type, + 'ptype' => (string) $column->type, + 'length' => (int) $column->length, + 'fixed' => (int) $column->fixed, + 'unsigned' => (bool) $column->unsigned, + 'primary' => (bool) (isset($column->primary) && $column->primary), + 'default' => (string) $column->default, + 'notnull' => (bool) (isset($column->notnull) && $column->notnull), + 'autoinc' => (bool) (isset($column->autoincrement) && $column->autoincrement), ); - $columns[(string) $field->name] = $colDesc; + $columns[(string) $column->name] = $colDesc; } $class = $table->class ? (string) $table->class:(string) $table->name; diff --git a/lib/Doctrine/Import/Schema/Yml.php b/lib/Doctrine/Import/Schema/Yml.php index 1a4f0eca7..03e419977 100644 --- a/lib/Doctrine/Import/Schema/Yml.php +++ b/lib/Doctrine/Import/Schema/Yml.php @@ -51,12 +51,12 @@ class Doctrine_Import_Schema_Yml extends Doctrine_Import_Schema public function parseSchema($schema) { $array = $this->parse($schema); + $tables = $array['schema']['tables']; - // Go through all tables... - foreach ($array['tables'] as $table) { + foreach ($tables as $table) { $columns = array(); - foreach ($table['declaration'] as $field) { + foreach ($table['columns'] as $field) { $colDesc = array( 'name' => isset($field['name']) ? (string) $field['name']:null, 'type' => isset($field['type']) ? (string) $field['type']:null, diff --git a/lib/Doctrine/Parser/Xml.php b/lib/Doctrine/Parser/Xml.php index 82e6626aa..789a3b660 100644 --- a/lib/Doctrine/Parser/Xml.php +++ b/lib/Doctrine/Parser/Xml.php @@ -31,26 +31,27 @@ */ class Doctrine_Parser_Xml extends Doctrine_Parser { - public function arrayToXml($array) + public function arrayToXml($data, $rootNodeName = 'data', $xml = null) { - $this->text = ""; - - $this->text .= $this->arrayTransform($array); - - return $this->text; - } + if ($xml === null) { + $xml = new SimpleXmlElement("<$rootNodeName/>"); + } + + foreach($data as $key => $value) + { + if (is_array($value)) { + $node = $xml->addChild($key); + + $this->arrayToXml($value, $rootNodeName, $node); + } else { + $value = htmlentities($value); + + $xml->addChild($key, $value); + } - public function arrayTransform($array) - { - foreach ($array as $key => $value) { - if (!is_array($value)) { - $this->text .= "<$key>$value"; - } else { - $this->text.="<$key>"; - $this->arrayTransform($value); - $this->text.=""; - } - } + } + + return $xml->asXML(); } public function dumpData($array, $path = null) diff --git a/playground/index.php b/playground/index.php index 7bc9c2ca1..bf2a00bcd 100644 --- a/playground/index.php +++ b/playground/index.php @@ -1,2 +1,4 @@ $file) { - if ($file->isFile() && ! $file->isDot()) { - $e = explode('.', $file->getFileName()); - if (end($e) === 'php') { - require_once $file->getPathname(); + // include the models + $models = new DirectoryIterator($modelsPath); + foreach($models as $key => $file) { + if ($file->isFile() && ! $file->isDot()) { + $e = explode('.', $file->getFileName()); + if (end($e) === 'php') { + require_once $file->getPathname(); + } } } } @@ -25,26 +27,28 @@ $dbh = new PDO('sqlite::memory:'); $conn = Doctrine_Manager::connection($dbh); $manager = Doctrine_Manager::getInstance(); -$manager->setAttribute(Doctrine::ATTR_EXPORT, Doctrine::EXPORT_ALL); +if (constant('LOAD_MODELS')) { + $manager->setAttribute(Doctrine::ATTR_EXPORT, Doctrine::EXPORT_ALL); -$tables = array('entity', - 'entityReference', - 'email', - 'phonenumber', - 'groupuser', - 'album', - 'song', - 'element', - 'error', - 'description', - 'address', - 'account', - 'task', - 'resource', - 'assignment', - 'resourceType', - 'resourceReference'); + $tables = array('entity', + 'entityReference', + 'email', + 'phonenumber', + 'groupuser', + 'album', + 'song', + 'element', + 'error', + 'description', + 'address', + 'account', + 'task', + 'resource', + 'assignment', + 'resourceType', + 'resourceReference'); -$conn->export->exportClasses($tables); + $conn->export->exportClasses($tables); -require_once('data.php'); \ No newline at end of file + require_once('data.php'); +} \ No newline at end of file diff --git a/tests/schema.xml b/tests/schema.xml index 553510187..151bbc17a 100755 --- a/tests/schema.xml +++ b/tests/schema.xml @@ -1,40 +1,42 @@ - - - user - User - - - id - integer - true - true - - - username - string - 20 - true - - -
+ + + + user + User + + + id + integer + true + true + + + username + string + 20 + true + + +
- - group - Group - - - id - integer - true - true - - - name - string - 20 - true - - -
-
\ No newline at end of file + + group + Group + + + id + integer + true + true + + + name + string + 20 + true + + +
+
+ \ No newline at end of file diff --git a/tests/schema.yml b/tests/schema.yml index eefb5efec..6842bfe5f 100644 --- a/tests/schema.yml +++ b/tests/schema.yml @@ -1,30 +1,31 @@ --- -tables: - user: - name: user - class: User - declaration: - id: - name: id - type: integer - notnull: true - autoincrement: true - username: - name: username - type: string - length: 20 - notnull: true - group: - name: group - class: Group - declaration: - id: - name: id - type: integer - notnull: true - autoincrement: true - name: - name: name - type: string - length: 20 - notnull: true \ No newline at end of file +schema: + tables: + user: + name: user + class: User + columns: + id: + name: id + type: integer + notnull: true + autoincrement: true + username: + name: username + type: string + length: 20 + notnull: true + group: + name: group + class: Group + columns: + id: + name: id + type: integer + notnull: true + autoincrement: true + name: + name: name + type: string + length: 20 + notnull: true \ No newline at end of file