Doctrine 1.2.4
Doctrine_Import_Schema Class Reference

Public Member Functions

 buildSchema ($schema, $format)
 
 getOption ($name)
 
 getOptions ()
 
 importSchema ($schema, $format= 'yml', $directory=null, $models=array())
 
 parseSchema ($schema, $type)
 
 setOption ($name, $value)
 
 setOptions ($options)
 

Static Public Member Functions

static getGlobalDefinitionKeys ()
 

Protected Member Functions

 _autoCompleteOppositeRelations ()
 
 _buildRelationships ($array)
 
 _buildUniqueRelationKey ($relation)
 
 _findBaseSuperClass ($array, $class)
 
 _fixDuplicateRelations ()
 
 _processInheritance ($array)
 
 _validateSchemaElement ($name, $element, $path)
 

Detailed Description

Definition at line 35 of file Schema.php.

Member Function Documentation

Doctrine_Import_Schema::_autoCompleteOppositeRelations ( )
protected

fixRelationships

Loop through all relationships building the opposite ends of each relationship and make sure no duplicate relations exist

Returns
void

Definition at line 659 of file Schema.php.

{
foreach($this->_relations as $className => $relations) {
foreach ($relations AS $alias => $relation) {
if ((isset($relation['equal']) && $relation['equal']) || (isset($relation['autoComplete']) && $relation['autoComplete'] === false)) {
continue;
}
$newRelation = array();
$newRelation['foreign'] = $relation['local'];
$newRelation['local'] = $relation['foreign'];
$newRelation['class'] = isset($relation['foreignClass']) ? $relation['foreignClass']:$className;
$newRelation['alias'] = isset($relation['foreignAlias']) ? $relation['foreignAlias']:$className;
$newRelation['foreignAlias'] = $alias;
// this is so that we know that this relation was autogenerated and
// that we do not need to include it if it is explicitly declared in the schema by the users.
$newRelation['autogenerated'] = true;
if (isset($relation['refClass'])) {
$newRelation['refClass'] = $relation['refClass'];
$newRelation['type'] = isset($relation['foreignType']) ? $relation['foreignType']:$relation['type'];
} else {
if (isset($relation['foreignType'])) {
$newRelation['type'] = $relation['foreignType'];
} else {
$newRelation['type'] = $relation['type'] === Doctrine_Relation::ONE ? Doctrine_Relation::MANY:Doctrine_Relation::ONE;
}
}
// Make sure it doesn't already exist
if ( ! isset($this->_relations[$relation['class']][$newRelation['alias']])) {
$newRelation['key'] = $this->_buildUniqueRelationKey($newRelation);
$this->_relations[$relation['class']][$newRelation['alias']] = $newRelation;
}
}
}
}
Doctrine_Import_Schema::_buildRelationships (   $array)
protected

buildRelationships

Loop through an array of schema information and build all the necessary relationship information Will attempt to auto complete relationships and simplify the amount of information required for defining a relationship

Parameters
string$array
Returns
void

Definition at line 564 of file Schema.php.

{
// Handle auto detecting relations by the names of columns
// User.contact_id will automatically create User hasOne Contact local => contact_id, foreign => id
foreach ($array as $className => $properties) {
if (isset($properties['columns']) && ! empty($properties['columns']) && isset($properties['detect_relations']) && $properties['detect_relations']) {
foreach ($properties['columns'] as $column) {
// Check if the column we are inflecting has a _id on the end of it before trying to inflect it and find
// the class name for the column
if (strpos($column['name'], '_id')) {
$columnClassName = Doctrine_Inflector::classify(str_replace('_id', '', $column['name']));
if (isset($array[$columnClassName]) && !isset($array[$className]['relations'][$columnClassName])) {
$array[$className]['relations'][$columnClassName] = array();
// Set the detected foreign key type and length to the same as the primary key
// of the related table
$type = isset($array[$columnClassName]['columns']['id']['type']) ? $array[$columnClassName]['columns']['id']['type']:'integer';
$length = isset($array[$columnClassName]['columns']['id']['length']) ? $array[$columnClassName]['columns']['id']['length']:8;
$array[$className]['columns'][$column['name']]['type'] = $type;
$array[$className]['columns'][$column['name']]['length'] = $length;
}
}
}
}
}
foreach ($array as $name => $properties) {
if ( ! isset($properties['relations'])) {
continue;
}
$className = $properties['className'];
$relations = $properties['relations'];
foreach ($relations as $alias => $relation) {
$class = isset($relation['class']) ? $relation['class']:$alias;
if ( ! isset($array[$class])) {
continue;
}
$relation['class'] = $class;
$relation['alias'] = isset($relation['alias']) ? $relation['alias'] : $alias;
// Attempt to guess the local and foreign
if (isset($relation['refClass'])) {
$relation['local'] = isset($relation['local']) ? $relation['local']:Doctrine_Inflector::tableize($name) . '_id';
$relation['foreign'] = isset($relation['foreign']) ? $relation['foreign']:Doctrine_Inflector::tableize($class) . '_id';
} else {
$relation['local'] = isset($relation['local']) ? $relation['local']:Doctrine_Inflector::tableize($relation['class']) . '_id';
$relation['foreign'] = isset($relation['foreign']) ? $relation['foreign']:'id';
}
if (isset($relation['refClass'])) {
$relation['type'] = 'many';
}
if (isset($relation['type']) && $relation['type']) {
$relation['type'] = $relation['type'] === 'one' ? Doctrine_Relation::ONE:Doctrine_Relation::MANY;
} else {
$relation['type'] = Doctrine_Relation::ONE;
}
if (isset($relation['foreignType']) && $relation['foreignType']) {
$relation['foreignType'] = $relation['foreignType'] === 'one' ? Doctrine_Relation::ONE:Doctrine_Relation::MANY;
}
$relation['key'] = $this->_buildUniqueRelationKey($relation);
$this->_validateSchemaElement('relation', array_keys($relation), $className . '->relation->' . $relation['alias']);
$this->_relations[$className][$alias] = $relation;
}
}
// Now we auto-complete opposite ends of relationships
// Make sure we do not have any duplicate relations
// Set the full array of relationships for each class to the final array
foreach ($this->_relations as $className => $relations) {
$array[$className]['relations'] = $relations;
}
return $array;
}
Doctrine_Import_Schema::_buildUniqueRelationKey (   $relation)
protected

_buildUniqueRelationKey

Build a unique key to identify a relationship by Md5 hash of all the relationship parameters

Parameters
string$relation
Returns
void

Definition at line 737 of file Schema.php.

{
return md5($relation['local'].$relation['foreign'].$relation['class'].(isset($relation['refClass']) ? $relation['refClass']:null));
}
Doctrine_Import_Schema::_findBaseSuperClass (   $array,
  $class 
)
protected

Find the base super class for this inheritance child. We need to move all levels of children to the top most parent.

Parameters
array$arrayArray of schema information
Returns
string $class Class to get find the parent for

Definition at line 545 of file Schema.php.

{
if (isset($array[$class]['inheritance']['extends']) && isset($array[$class]['inheritance']['type']) && ($array[$class]['inheritance']['type'] == 'simple' || $array[$class]['inheritance']['type'] == 'column_aggregation')) {
return $this->_findBaseSuperClass($array, $array[$class]['inheritance']['extends']);
} else {
return $class;
}
}
Doctrine_Import_Schema::_fixDuplicateRelations ( )
protected

_fixDuplicateRelations

Ensure the relations for each class are unique and that no duplicated relations exist from the auto generated relations and the user explicitely defining the opposite end

Returns
void

Definition at line 706 of file Schema.php.

{
foreach($this->_relations as $className => $relations) {
// This is for checking for duplicates between alias-relations and a auto-generated relations to ensure the result set of unique relations
$existingRelations = array();
$uniqueRelations = array();
foreach ($relations as $relation) {
if ( ! in_array($relation['key'], $existingRelations)) {
$existingRelations[] = $relation['key'];
$uniqueRelations = array_merge($uniqueRelations, array($relation['alias'] => $relation));
} else {
// check to see if this relationship is not autogenerated, if it's not, then the user must have explicitly declared it
if ( ! isset($relation['autogenerated']) || $relation['autogenerated'] != true) {
$uniqueRelations = array_merge($uniqueRelations, array($relation['alias'] => $relation));
}
}
}
$this->_relations[$className] = $uniqueRelations;
}
}
Doctrine_Import_Schema::_processInheritance (   $array)
protected

_processInheritance

Perform some processing on inheritance. Sets the default type and sets some default values for certain types

Parameters
string$array
Returns
void

Definition at line 458 of file Schema.php.

{
// Apply default inheritance configuration
foreach ($array as $className => $definition) {
if ( ! empty($array[$className]['inheritance'])) {
$this->_validateSchemaElement('inheritance', array_keys($definition['inheritance']), $className . '->inheritance');
// Default inheritance to concrete inheritance
if ( ! isset($array[$className]['inheritance']['type'])) {
$array[$className]['inheritance']['type'] = 'concrete';
}
// Some magic for setting up the keyField and keyValue column aggregation options
// Adds keyField to the parent class automatically
if ($array[$className]['inheritance']['type'] == 'column_aggregation') {
// Set the keyField to 'type' by default
if ( ! isset($array[$className]['inheritance']['keyField'])) {
$array[$className]['inheritance']['keyField'] = 'type';
}
// Set the keyValue to the name of the child class if it does not exist
if ( ! isset($array[$className]['inheritance']['keyValue'])) {
$array[$className]['inheritance']['keyValue'] = $className;
}
$parent = $this->_findBaseSuperClass($array, $definition['className']);
// Add the keyType column to the parent if a definition does not already exist
if ( ! isset($array[$parent]['columns'][$array[$className]['inheritance']['keyField']])) {
$array[$parent]['columns'][$array[$className]['inheritance']['keyField']] = array('name' => $array[$className]['inheritance']['keyField'], 'type' => 'string', 'length' => 255);
}
}
}
}
// Array of the array keys to move to the parent, and the value to default the child definition to
// after moving it. Will also populate the subclasses array for the inheritance parent
$moves = array('columns' => array(),
'indexes' => array(),
'attributes' => array(),
'options' => array(),
'checks' => array());
foreach ($array as $className => $definition) {
// Move any definitions on the schema to the parent
if (isset($definition['inheritance']['extends']) && isset($definition['inheritance']['type']) && ($definition['inheritance']['type'] == 'simple' || $definition['inheritance']['type'] == 'column_aggregation')) {
$parent = $this->_findBaseSuperClass($array, $definition['className']);
foreach ($moves as $move => $resetValue) {
if (isset($array[$parent][$move]) && isset($definition[$move])) {
$array[$parent][$move] = Doctrine_Lib::arrayDeepMerge($array[$parent][$move], $definition[$move]);
$array[$definition['className']][$move] = $resetValue;
}
}
// Populate the parents subclasses
if ($definition['inheritance']['type'] == 'column_aggregation') {
// Fix for 2015: loop through superclasses' inheritance to the base-superclass to
// make sure we collect all keyFields needed (and not only the first)
$inheritanceFields = array($definition['inheritance']['keyField'] => $definition['inheritance']['keyValue']);
$superClass = $definition['inheritance']['extends'];
$multiInheritanceDef = $array[$superClass];
while (count($multiInheritanceDef['inheritance']) > 0 && array_key_exists('extends', $multiInheritanceDef['inheritance']) && $multiInheritanceDef['inheritance']['type'] == 'column_aggregation') {
$superClass = $multiInheritanceDef['inheritance']['extends'];
// keep original keyField with it's keyValue
if ( ! isset($inheritanceFields[$multiInheritanceDef['inheritance']['keyField']])) {
$inheritanceFields[$multiInheritanceDef['inheritance']['keyField']] = $multiInheritanceDef['inheritance']['keyValue'];
}
$multiInheritanceDef = $array[$superClass];
}
$array[$parent]['inheritance']['subclasses'][$definition['className']] = $inheritanceFields;
}
}
}
return $array;
}
Doctrine_Import_Schema::_validateSchemaElement (   $name,
  $element,
  $path 
)
protected

_validateSchemaElement

Parameters
string$name
string$value
Returns
void

Definition at line 749 of file Schema.php.

{
$element = (array) $element;
$validation = $this->_validation[$name];
// Validators are a part of the column validation
// This should be fixed, made cleaner
if ($name == 'column') {
$validators = Doctrine_Manager::getInstance()->getValidators();
$validation = array_merge($validation, $validators);
}
$validation = array_flip($validation);
foreach ($element as $key => $value) {
if ( ! isset($validation[$value])) {
sprintf('Invalid schema element named "' . $value . '" at path "' . $path . '"')
);
}
}
}
Doctrine_Import_Schema::buildSchema (   $schema,
  $format 
)

buildSchema

Loop throug directories of schema files and parse them all in to one complete array of schema information

Parameters
string$schemaArray of schema files or single schema file. Array of directories with schema files or single directory
string$formatFormat of the files we are parsing and building from
Returns
array $array

Definition at line 224 of file Schema.php.

{
$array = array();
foreach ((array) $schema AS $s) {
if (is_file($s)) {
$e = explode('.', $s);
if (end($e) === $format) {
$array = array_merge($array, $this->parseSchema($s, $format));
}
} else if (is_dir($s)) {
$it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($s),
RecursiveIteratorIterator::LEAVES_ONLY);
foreach ($it as $file) {
$e = explode('.', $file->getFileName());
if (end($e) === $format) {
$array = array_merge($array, $this->parseSchema($file->getPathName(), $format));
}
}
} else {
$array = array_merge($array, $this->parseSchema($s, $format));
}
}
$array = $this->_buildRelationships($array);
$array = $this->_processInheritance($array);
return $array;
}
static Doctrine_Import_Schema::getGlobalDefinitionKeys ( )
static

Returns an array of definition keys that can be applied at the global level.

Returns
array

Definition at line 160 of file Schema.php.

{
return self::$_globalDefinitionKeys;
}
Doctrine_Import_Schema::getOption (   $name)

getOption

Parameters
string$name
Returns
void

Definition at line 171 of file Schema.php.

{
if (isset($this->_options[$name])) {
return $this->_options[$name];
}
}
Doctrine_Import_Schema::getOptions ( )

getOptions

Returns
void

Definition at line 183 of file Schema.php.

{
return $this->_options;
}
Doctrine_Import_Schema::importSchema (   $schema,
  $format = 'yml',
  $directory = null,
  $models = array() 
)

importSchema

A method to import a Schema and translate it into a Doctrine_Record object

Parameters
string$schemaThe file containing the XML schema
string$formatFormat of the schema file
string$directoryThe directory where the Doctrine_Record class will be written
array$modelsOptional array of models to import
Returns
void

Definition at line 267 of file Schema.php.

{
$schema = (array) $schema;
$builder = new Doctrine_Import_Builder();
$builder->setTargetPath($directory);
$builder->setOptions($this->getOptions());
$array = $this->buildSchema($schema, $format);
if (count($array) == 0) {
sprintf('No ' . $format . ' schema found in ' . implode(", ", $schema))
);
}
foreach ($array as $name => $definition) {
if ( ! empty($models) && !in_array($definition['className'], $models)) {
continue;
}
$builder->buildRecord($definition);
}
}
Doctrine_Import_Schema::parseSchema (   $schema,
  $type 
)

parseSchema

A method to parse a Schema and translate it into a property array. The function returns that property array.

Parameters
string$schemaPath to the file containing the schema
string$typeFormat type of the schema we are parsing
Returns
array $build Built array of schema information

Definition at line 301 of file Schema.php.

{
$defaults = array('abstract' => false,
'className' => null,
'tableName' => null,
'connection' => null,
'relations' => array(),
'indexes' => array(),
'attributes' => array(),
'templates' => array(),
'actAs' => array(),
'options' => array(),
'package' => null,
'inheritance' => array(),
'detect_relations' => false);
$array = Doctrine_Parser::load($schema, $type);
// Loop over and build up all the global values and remove them from the array
$globals = array();
foreach ($array as $key => $value) {
if (in_array($key, self::$_globalDefinitionKeys)) {
unset($array[$key]);
$globals[$key] = $value;
}
}
// Merge the globals that aren't specifically set to each class
foreach ($array as $className => $table) {
$array[$className] = Doctrine_Lib::arrayDeepMerge($globals, $array[$className]);
}
$build = array();
foreach ($array as $className => $table) {
$table = (array) $table;
$this->_validateSchemaElement('root', array_keys($table), $className);
$columns = array();
$className = isset($table['className']) ? (string) $table['className']:(string) $className;
if (isset($table['inheritance']['keyField']) || isset($table['inheritance']['keyValue'])) {
$table['inheritance']['type'] = 'column_aggregation';
}
if (isset($table['tableName']) && $table['tableName']) {
$tableName = $table['tableName'];
} else {
if (isset($table['inheritance']['type']) && ($table['inheritance']['type'] == 'column_aggregation')) {
$tableName = null;
} else {
$tableName = Doctrine_Inflector::tableize($className);
}
}
$connection = isset($table['connection']) ? $table['connection']:'current';
$columns = isset($table['columns']) ? $table['columns']:array();
if ( ! empty($columns)) {
foreach ($columns as $columnName => $field) {
// Support short syntax: my_column: integer(4)
if ( ! is_array($field)) {
$original = $field;
$field = array();
$field['type'] = $original;
}
$colDesc = array();
if (isset($field['name'])) {
$colDesc['name'] = $field['name'];
} else {
$colDesc['name'] = $columnName;
}
$this->_validateSchemaElement('column', array_keys($field), $className . '->columns->' . $colDesc['name']);
// Support short type(length) syntax: my_column: { type: integer(4) }
$e = explode('(', $field['type']);
if (isset($e[0]) && isset($e[1])) {
$colDesc['type'] = $e[0];
$value = substr($e[1], 0, strlen($e[1]) - 1);
$e = explode(',', $value);
$colDesc['length'] = $e[0];
if (isset($e[1]) && $e[1]) {
$colDesc['scale'] = $e[1];
}
} else {
$colDesc['type'] = isset($field['type']) ? (string) $field['type']:null;
$colDesc['length'] = isset($field['length']) ? (int) $field['length']:null;
$colDesc['length'] = isset($field['size']) ? (int) $field['size']:$colDesc['length'];
}
$colDesc['fixed'] = isset($field['fixed']) ? (int) $field['fixed']:null;
$colDesc['primary'] = isset($field['primary']) ? (bool) (isset($field['primary']) && $field['primary']):null;
$colDesc['default'] = isset($field['default']) ? $field['default']:null;
$colDesc['autoincrement'] = isset($field['autoincrement']) ? (bool) (isset($field['autoincrement']) && $field['autoincrement']):null;
if (isset($field['sequence'])) {
if (true === $field['sequence']) {
$colDesc['sequence'] = $tableName;
} else {
$colDesc['sequence'] = (string) $field['sequence'];
}
} else {
$colDesc['sequence'] = null;
}
$colDesc['values'] = isset($field['values']) ? (array) $field['values']:null;
// Include all the specified and valid validators in the colDesc
$validators = Doctrine_Manager::getInstance()->getValidators();
foreach ($validators as $validator) {
if (isset($field[$validator])) {
$colDesc[$validator] = $field[$validator];
}
}
$columns[(string) $columnName] = $colDesc;
}
}
// Apply the default values
foreach ($defaults as $key => $defaultValue) {
if (isset($table[$key]) && ! isset($build[$className][$key])) {
$build[$className][$key] = $table[$key];
} else {
$build[$className][$key] = isset($build[$className][$key]) ? $build[$className][$key]:$defaultValue;
}
}
$build[$className]['className'] = $className;
$build[$className]['tableName'] = $tableName;
$build[$className]['columns'] = $columns;
// Make sure that anything else that is specified in the schema makes it to the final array
$build[$className] = Doctrine_Lib::arrayDeepMerge($table, $build[$className]);
// We need to keep track of the className for the connection
$build[$className]['connectionClassName'] = $build[$className]['className'];
}
return $build;
}
Doctrine_Import_Schema::setOption (   $name,
  $value 
)

setOption

Parameters
string$name
string$value
Returns
void

Definition at line 195 of file Schema.php.

{
if (isset($this->_options[$name])) {
$this->_options[$name] = $value;
}
}
Doctrine_Import_Schema::setOptions (   $options)

setOptions

Parameters
string$options
Returns
void

Definition at line 208 of file Schema.php.

{
if ( ! empty($options)) {
$this->_options = $options;
}
}

The documentation for this class was generated from the following file: