Development

Changeset 6973

You must first sign up to be able to contribute.

Changeset 6973

Show
Ignore:
Timestamp:
01/06/08 11:15:51 (1 year ago)
Author:
fabien
Message:

added short syntax for m2m relationships in fixtures

  • the old syntax is still supported (useful if the middle table has some specific fields)
  • new syntax example:
    Answer:
      answer_1:
        name: 2007
      answer_2:
        name: 2008
    Question:
      question_1:
        name:             What's the current year?
        question_answers: [answer_1, answer_2]
Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/1.1/lib/plugins/sfPropelPlugin/lib/propel/sfPropelData.class.php

    r6970 r6973  
    2222{ 
    2323  protected 
    24     $maps           = array(), 
    2524    $deletedClasses = array(), 
    2625    $con            = null; 
    2726 
    28   // symfony load-data (file|dir) 
    2927  /** 
    3028   * Loads data from a file or directory into a Propel data source 
     
    3836  { 
    3937    $fixture_files = $this->getFiles($directory_or_file); 
     38 
     39    // load map classes 
     40    $this->loadMapBuilders(); 
     41    $this->dbMap = Propel::getDatabaseMap($connectionName); 
    4042 
    4143    // wrap all database operations in a single transaction 
     
    8183      $peer_class = $class.'Peer'; 
    8284 
    83       // load map class 
    84       $this->loadMapBuilder($class); 
    85  
    86       $tableMap = $this->maps[$class]->getDatabaseMap()->getTable(constant($peer_class.'::TABLE_NAME')); 
     85      $tableMap = $this->dbMap->getTable(constant($peer_class.'::TABLE_NAME')); 
    8786 
    8887      $column_names = call_user_func_array(array($peer_class, 'getFieldNames'), array(BasePeer::TYPE_FIELDNAME)); 
     
    112111        foreach ($data as $name => $value) 
    113112        { 
     113          // will need to be updated for Propel 1.3 
     114          if (is_array($value) && 's' == substr($name, -1)) 
     115          { 
     116            // many to many relationship 
     117            $this->loadMany2Many($obj, substr($name, 0, -1), $value); 
     118 
     119            continue; 
     120          } 
     121 
    114122          $isARealColumn = true; 
    115123          try 
     
    127135            if ($column->isForeignKey() && !is_null($value)) 
    128136            { 
    129               $relatedTable = $this->maps[$class]->getDatabaseMap()->getTable($column->getRelatedTableName()); 
     137              $relatedTable = $this->dbMap->getTable($column->getRelatedTableName()); 
    130138              if (!isset($this->object_references[$relatedTable->getPhpName().'_'.$value])) 
    131139              { 
    132140                throw new sfException(sprintf('The object "%s" from class "%s" is not defined in your data file.', $value, $relatedTable->getPhpName())); 
    133141              } 
    134               $value = $this->object_references[$relatedTable->getPhpName().'_'.$value]
     142              $value = $this->object_references[$relatedTable->getPhpName().'_'.$value]->getPrimaryKey()
    135143            } 
    136144          } 
     
    151159        $obj->save($this->con); 
    152160 
    153         // save the id for future reference 
     161        // save the object for future reference 
    154162        if (method_exists($obj, 'getPrimaryKey')) 
    155163        { 
    156           $this->object_references[$class.'_'.$key] = $obj->getPrimaryKey(); 
    157         } 
    158       } 
     164          $this->object_references[$class.'_'.$key] = $obj; 
     165        } 
     166      } 
     167    } 
     168  } 
     169 
     170  /** 
     171   * Loads many to many objects. 
     172   * 
     173   * @param BaseObject A Propel object 
     174   * @param string     The middle table name 
     175   * @param array      An array of values 
     176   */ 
     177  protected function loadMany2Many($obj, $middleTableName, $values) 
     178  { 
     179    $middleTable = $this->dbMap->getTable($middleTableName); 
     180    $middleClass = $middleTable->getPhpName(); 
     181    foreach ($middleTable->getColumns()  as $column) 
     182    { 
     183      if ($column->isPrimaryKey() && $column->isForeignKey() && constant(get_class($obj).'Peer::TABLE_NAME') != $column->getRelatedTableName()) 
     184      { 
     185        $relatedClass = $this->dbMap->getTable($column->getRelatedTableName())->getPhpName(); 
     186        break; 
     187      } 
     188    } 
     189 
     190    if (!isset($relatedClass)) 
     191    { 
     192      throw new sfException(sprintf('Unable to find the many-to-many relationship for object "%s"', get_class($obj))); 
     193    } 
     194 
     195    $setter = 'set'.get_class($obj); 
     196    $relatedSetter = 'set'.$relatedClass; 
     197 
     198    foreach ($values as $value) 
     199    { 
     200      if (!isset($this->object_references[$relatedClass.'_'.$value])) 
     201      { 
     202        throw new sfException(sprintf('The object "%s" from class "%s" is not defined in your data file.', $value, $relatedClass)); 
     203      } 
     204 
     205      $middle = new $middleClass(); 
     206      $middle->$setter($obj); 
     207      $middle->$relatedSetter($this->object_references[$relatedClass.'_'.$value]); 
     208      $middle->save(); 
    159209    } 
    160210  } 
     
    215265 
    216266  /** 
    217    * Loads the mappings for the classes 
    218    * 
    219    * @param string The model class name 
     267   * Loads all map builders. 
    220268   * 
    221269   * @throws sfException If the class cannot be found 
    222270   */ 
    223   protected function loadMapBuilder($class) 
    224   { 
    225     $mapBuilderClass = $class.'MapBuilder'; 
    226     if (!isset($this->maps[$class])) 
    227     { 
    228       if (!$classPath = sfAutoload::getInstance()->getClassPath($mapBuilderClass)) 
    229       { 
    230         throw new sfException(sprintf('Unable to find path for class "%s".', $mapBuilderClass)); 
    231       } 
    232  
    233       require_once($classPath); 
    234       $this->maps[$class] = new $mapBuilderClass(); 
    235       $this->maps[$class]->doBuild(); 
     271  protected function loadMapBuilders() 
     272  { 
     273    $files = sfFinder::type('file')->name('*MapBuilder.php')->in(sfLoader::getModelDirs()); 
     274    foreach ($files as $file) 
     275    { 
     276      $mapBuilderClass = basename($file, '.php'); 
     277      $map = new $mapBuilderClass(); 
     278      $map->doBuild(); 
    236279    } 
    237280  } 
     
    258301    } 
    259302 
     303    $this->loadMapBuilders(); 
    260304    $this->con = Propel::getConnection($connectionName); 
     305    $this->dbMap = Propel::getDatabaseMap($connectionName); 
    261306 
    262307    // get tables 
    263308    if ('all' === $tables || is_null($tables)) 
    264309    { 
    265       // load all map builder classes 
    266       $files = sfFinder::type('file')->name('*MapBuilder.php')->in(sfLoader::getModelDirs()); 
    267       foreach ($files as $file) 
    268       { 
    269         $mapBuilderClass = basename($file, '.php'); 
    270         $map = new $mapBuilderClass(); 
    271         $map->doBuild(); 
    272       } 
    273  
    274       $dbMap = Propel::getDatabaseMap($connectionName); 
    275310      $tables = array(); 
    276       foreach ($dbMap->getTables() as $table) 
     311      foreach ($this->dbMap->getTables() as $table) 
    277312      { 
    278313        $tables[] = $table->getPhpName(); 
     
    285320 
    286321    $dumpData = array(); 
    287  
    288     // load map classes 
    289     array_walk($tables, array($this, 'loadMapBuilder')); 
    290322 
    291323    $tables = $this->fixOrderingOfForeignKeyData($tables); 
    292324    foreach ($tables as $tableName) 
    293325    { 
    294       $tableMap = $this->maps[$tableName]->getDatabaseMap()->getTable(constant($tableName.'Peer::TABLE_NAME')); 
     326      $tableMap = $this->dbMap->getTable(constant($tableName.'Peer::TABLE_NAME')); 
    295327      $hasParent = false; 
    296328      $haveParents = false; 
     
    301333        if ($column->isForeignKey()) 
    302334        { 
    303           $relatedTable = $this->maps[$tableName]->getDatabaseMap()->getTable($column->getRelatedTableName()); 
     335          $relatedTable = $this->dbMap->getTable($column->getRelatedTableName()); 
    304336          if ($tableName === $relatedTable->getPhpName()) 
    305337          { 
     
    366398            if ($column->isForeignKey()) 
    367399            { 
    368               $relatedTable = $this->maps[$tableName]->getDatabaseMap()->getTable($column->getRelatedTableName()); 
     400              $relatedTable = $this->dbMap->getTable($column->getRelatedTableName()); 
    369401              if ($isPrimaryKey) 
    370402              { 
     
    425457    { 
    426458      $class = $classes[$i]; 
    427       $tableMap = $this->maps[$class]->getDatabaseMap()->getTable(constant($class.'Peer::TABLE_NAME')); 
     459      $tableMap = $this->dbMap->getTable(constant($class.'Peer::TABLE_NAME')); 
    428460      foreach ($tableMap->getColumns() as $column) 
    429461      { 
    430462        if ($column->isForeignKey()) 
    431463        { 
    432           $relatedTable = $this->maps[$class]->getDatabaseMap()->getTable($column->getRelatedTableName()); 
     464          $relatedTable = $this->dbMap->getTable($column->getRelatedTableName()); 
    433465          $relatedTablePos = array_search($relatedTable->getPhpName(), $classes); 
    434466 

The Sensio Labs Network

Since 1998, Sensio Labs has been promoting the Open-Source software movement by providing quality web application development, training, consulting, and supporting several large Open-Source projects.