Example #1
0
 /**
  * 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
  *
  * @param  string $array 
  * @return void
  */
 protected function _buildRelationships($array)
 {
     // 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();
                     }
                 }
             }
         }
     }
     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;
             $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::tableize($name) . '_id';
                 $relation['foreign'] = isset($relation['foreign']) ? $relation['foreign'] : Doctrine::tableize($class) . '_id';
             } else {
                 $relation['local'] = isset($relation['local']) ? $relation['local'] : Doctrine::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));
             $this->_relations[$className][$alias] = $relation;
         }
     }
     // Now we auto-complete opposite ends of relationships
     $this->_autoCompleteOppositeRelations();
     // Make sure we do not have any duplicate relations
     $this->_fixDuplicateRelations();
     // 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;
 }
Example #2
0
 /**
  * printTasks
  *
  * Prints an index of all the available tasks in the CLI instance
  * 
  * @return void
  */
 public function printTasks($task = null, $full = false)
 {
     $task = Doctrine::classify(str_replace('-', '_', $task));
     $tasks = $this->getLoadedTasks();
     echo $this->_formatter->format("Doctrine Command Line Interface", 'HEADER') . "\n\n";
     foreach ($tasks as $taskName) {
         if ($task != null && strtolower($task) != strtolower($taskName)) {
             continue;
         }
         $className = 'Doctrine_Task_' . $taskName;
         $taskInstance = new $className();
         $taskInstance->taskName = str_replace('_', '-', Doctrine::tableize($taskName));
         $syntax = $this->_scriptName . ' ' . $taskInstance->getTaskName();
         echo $this->_formatter->format($syntax, 'INFO');
         if ($full) {
             echo " - " . $taskInstance->getDescription() . "\n";
             $args = null;
             $requiredArguments = $taskInstance->getRequiredArgumentsDescriptions();
             if (!empty($requiredArguments)) {
                 foreach ($requiredArguments as $name => $description) {
                     $args .= $this->_formatter->format($name, "ERROR");
                     if (isset($this->_config[$name])) {
                         $args .= " - " . $this->_formatter->format($this->_config[$name], 'COMMENT');
                     } else {
                         $args .= " - " . $description;
                     }
                     $args .= "\n";
                 }
             }
             $optionalArguments = $taskInstance->getOptionalArgumentsDescriptions();
             if (!empty($optionalArguments)) {
                 foreach ($optionalArguments as $name => $description) {
                     $args .= $name . ' - ' . $description . "\n";
                 }
             }
             if ($args) {
                 echo "\n" . $this->_formatter->format('Arguments:', 'HEADER') . "\n" . $args;
             }
         }
         echo "\n";
     }
 }
Example #3
0
 /**
  * __construct
  *
  * Since this is an abstract classes that extend this must follow a patter of Doctrine_Task_{TASK_NAME}
  * This is what determines the task name for executing it.
  *
  * @return void
  */
 public function __construct($dispatcher = null)
 {
     $this->dispatcher = $dispatcher;
     $this->taskName = str_replace('_', '-', Doctrine::tableize(str_replace('Doctrine_Task_', '', get_class($this))));
 }
Example #4
0
 /**
  * __call
  *
  * Adds support for magic finders.
  * findByColumnName, findByRelationAlias
  * findById, findByContactId, etc.
  *
  * @return void
  */
 public function __call($method, $arguments)
 {
     if (substr($method, 0, 6) == 'findBy') {
         $by = substr($method, 6, strlen($method));
         $method = 'findBy';
     } else {
         if (substr($method, 0, 9) == 'findOneBy') {
             $by = substr($method, 9, strlen($method));
             $method = 'findOneBy';
         }
     }
     if (isset($by)) {
         if (!isset($arguments[0])) {
             throw new Doctrine_Table_Exception('You must specify the value to findBy');
         }
         $fieldName = Doctrine::tableize($by);
         $hydrationMode = isset($arguments[1]) ? $arguments[1] : null;
         if ($this->hasColumn($fieldName)) {
             return $this->{$method}($fieldName, $arguments[0], $hydrationMode);
         } else {
             if ($this->hasRelation($by)) {
                 $relation = $this->getRelation($by);
                 if ($relation['type'] === Doctrine_Relation::MANY) {
                     throw new Doctrine_Table_Exception('Cannot findBy many relationship.');
                 }
                 return $this->{$method}($relation['local'], $arguments[0], $hydrationMode);
             } else {
                 throw new Doctrine_Table_Exception('Cannot find by: ' . $by . '. Invalid column or relationship alias.');
             }
         }
     }
 }
Example #5
0
 /**
  * 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
  *
  * @param  string $array 
  * @return void
  */
 protected function _buildRelationships($array)
 {
     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;
             // Attempt to guess the local and foreign
             if (isset($relation['refClass'])) {
                 $relation['local'] = isset($relation['local']) ? $relation['local'] : Doctrine::tableize($name) . '_id';
                 $relation['foreign'] = isset($relation['foreign']) ? $relation['foreign'] : Doctrine::tableize($class) . '_id';
             } else {
                 $relation['local'] = isset($relation['local']) ? $relation['local'] : Doctrine::tableize($class) . '_id';
                 $relation['foreign'] = isset($relation['foreign']) ? $relation['foreign'] : 'id';
             }
             $relation['alias'] = isset($relation['alias']) ? $relation['alias'] : $alias;
             $relation['class'] = $class;
             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->_relations[$className][$alias] = $relation;
         }
     }
     // Now we fix all the relationships and auto-complete opposite ends of relationships
     $this->_fixRelationships();
 }
Example #6
0
 /**
  * the constructor
  * @throws Doctrine_Connection_Exception    if there are no opened connections
  * @throws Doctrine_Table_Exception         if there is already an instance of this table
  * @return void
  */
 public function __construct($name, Doctrine_Connection $conn)
 {
     $this->conn = $conn;
     $this->setParent($this->conn);
     $this->options['name'] = $name;
     $this->_parser = new Doctrine_Relation_Parser($this);
     if (!class_exists($name) || empty($name)) {
         throw new Doctrine_Exception("Couldn't find class " . $name);
     }
     $record = new $name($this);
     $names = array();
     $class = $name;
     // get parent classes
     do {
         if ($class == "Doctrine_Record") {
             break;
         }
         $name = $class;
         $names[] = $name;
     } while ($class = get_parent_class($class));
     // reverse names
     $names = array_reverse($names);
     // save parents
     array_pop($names);
     $this->options['parents'] = $names;
     // create database table
     if (method_exists($record, 'setTableDefinition')) {
         $record->setTableDefinition();
         // set the table definition for the given tree implementation
         if ($this->isTree()) {
             $this->getTree()->setTableDefinition();
         }
         $this->columnCount = count($this->columns);
         if (isset($this->columns)) {
             // get the declaring class of setTableDefinition method
             $method = new ReflectionMethod($this->options['name'], 'setTableDefinition');
             $class = $method->getDeclaringClass();
             $this->options['declaringClass'] = $class;
             if (!isset($this->options['tableName'])) {
                 $this->options['tableName'] = Doctrine::tableize($class->getName());
             }
             switch (count($this->primaryKeys)) {
                 case 0:
                     $this->columns = array_merge(array('id' => array('type' => 'integer', 'length' => 20, 'autoincrement' => true, 'primary' => true)), $this->columns);
                     $this->primaryKeys[] = 'id';
                     $this->identifier = 'id';
                     $this->identifierType = Doctrine::IDENTIFIER_AUTOINC;
                     $this->columnCount++;
                     break;
                 default:
                     if (count($this->primaryKeys) > 1) {
                         $this->identifier = $this->primaryKeys;
                         $this->identifierType = Doctrine::IDENTIFIER_COMPOSITE;
                     } else {
                         foreach ($this->primaryKeys as $pk) {
                             $e = $this->columns[$pk];
                             $found = false;
                             foreach ($e as $option => $value) {
                                 if ($found) {
                                     break;
                                 }
                                 $e2 = explode(':', $option);
                                 switch (strtolower($e2[0])) {
                                     case 'autoincrement':
                                     case 'autoinc':
                                         $this->identifierType = Doctrine::IDENTIFIER_AUTOINC;
                                         $found = true;
                                         break;
                                     case 'seq':
                                     case 'sequence':
                                         $this->identifierType = Doctrine::IDENTIFIER_SEQUENCE;
                                         $found = true;
                                         if ($value) {
                                             $this->options['sequenceName'] = $value;
                                         } else {
                                             if (($sequence = $this->getAttribute(Doctrine::ATTR_DEFAULT_SEQUENCE)) !== null) {
                                                 $this->options['sequenceName'] = $sequence;
                                             } else {
                                                 $this->options['sequenceName'] = $this->conn->getSequenceName($this->options['tableName']);
                                             }
                                         }
                                         break;
                                 }
                             }
                             if (!isset($this->identifierType)) {
                                 $this->identifierType = Doctrine::IDENTIFIER_NATURAL;
                             }
                             $this->identifier = $pk;
                         }
                     }
             }
         }
     } else {
         throw new Doctrine_Table_Exception("Class '{$name}' has no table definition.");
     }
     $record->setUp();
     // if tree, set up tree
     if ($this->isTree()) {
         $this->getTree()->setUp();
     }
     $this->repository = new Doctrine_Table_Repository($this);
 }
Example #7
0
 /**
  * generateMigrationClass
  *
  * @return void
  */
 public function generateMigrationClass($className, $options = array(), $up = null, $down = null, $return = false)
 {
     $className = Doctrine_Inflector::urlize($className);
     $className = str_replace('-', '_', $className);
     $className = Doctrine_Inflector::classify($className);
     if ($return || !$this->getMigrationsPath()) {
         return $this->buildMigrationClass($className, null, $options, $up, $down);
     } else {
         if (!$this->getMigrationsPath()) {
             throw new Doctrine_Migration_Exception('You must specify the path to your migrations.');
         }
         $next = (string) $this->migration->getNextVersion();
         $fileName = str_repeat('0', 3 - strlen($next)) . $next . '_' . Doctrine::tableize($className) . $this->suffix;
         $class = $this->buildMigrationClass($className, $fileName, $options, $up, $down);
         $path = $this->getMigrationsPath() . DIRECTORY_SEPARATOR . $fileName;
         if (class_exists($className) || file_exists($path)) {
             return false;
         }
         file_put_contents($path, $class);
         return true;
     }
 }