Changeset 4866 for trunk/lib/Doctrine

Show
Ignore:
Timestamp:
08/31/08 19:27:16 (4 months ago)
Author:
romanb
Message:

checkin of occasional work from the past weeks.

Location:
trunk/lib/Doctrine
Files:
15 added
35 modified

Legend:

Unmodified
Added
Removed
  • trunk/lib/Doctrine/Association.php

    r4800 r4866  
    104104     
    105105    /** 
    106      * Identifies the field on the owning side that has the mapping for the 
     106     * Identifies the field on the owning side that controls the mapping for the 
    107107     * association. This is only set on the inverse side of an association. 
    108108     * 
     
    110110     */ 
    111111    protected $_mappedByFieldName; 
     112     
     113    /** 
     114     * Identifies the field on the inverse side of a bidirectional association. 
     115     * This is only set on the owning side of an association. 
     116     * 
     117     * @var string 
     118     */ 
     119    //protected $_inverseSideFieldName; 
    112120     
    113121    /** 
     
    128136    public function __construct(array $mapping) 
    129137    { 
    130         /*$this->_mapping = array( 
     138        //$this->_initMappingArray(); 
     139        //$mapping = $this->_validateAndCompleteMapping($mapping); 
     140        //$this->_mapping = array_merge($this->_mapping, $mapping);*/ 
     141         
     142        $this->_validateAndCompleteMapping($mapping); 
     143    } 
     144     
     145    protected function _initMappingArray() 
     146    { 
     147        $this->_mapping = array( 
    131148            'fieldName' => null, 
    132149            'sourceEntity' => null, 
     
    138155            'mutator' => null, 
    139156            'optional' => true, 
    140             'cascade' => array() 
     157            'cascades' => array() 
    141158        ); 
    142         $this->_mapping = array_merge($this->_mapping, $mapping);*/ 
    143         $this->_validateAndCompleteMapping($mapping); 
    144159    } 
    145160     
     
    343358    } 
    344359     
     360    /*public function getInverseSideFieldName() 
     361    { 
     362        return $this->_inverseSideFieldName; 
     363    }*/ 
     364    /** 
     365     * Marks the association as bidirectional, specifying the field name of 
     366     * the inverse side. 
     367     * This is called on the owning side, when an inverse side is discovered. 
     368     * This does only make sense to call on the owning side. 
     369     * 
     370     * @param string $inverseSideFieldName 
     371     */ 
     372    /*public function setBidirectional($inverseSideFieldName) 
     373    { 
     374        if ( ! $this->_isOwningSide) { 
     375            return; //TODO: exception? 
     376        } 
     377        $this->_inverseSideFieldName = $inverseSideFieldName; 
     378    }*/ 
     379     
     380    /** 
     381     * Whether the association is bidirectional. 
     382     * 
     383     * @return boolean 
     384     */ 
     385    /*public function isBidirectional() 
     386    { 
     387        return $this->_mappedByFieldName || $this->_inverseSideFieldName; 
     388    }*/ 
     389     
    345390    /** 
    346391     * Whether the source field of the association has a custom accessor. 
  • trunk/lib/Doctrine/Association/OneToOne.php

    r4800 r4866  
    6464    { 
    6565        parent::__construct($mapping); 
     66    } 
     67     
     68    protected function _initMappingArray() 
     69    { 
     70        parent::_initMappingArray(); 
     71        $this->_mapping['deleteOrphans'] = false; 
    6672    } 
    6773     
  • trunk/lib/Doctrine/Builder/Record.php

    r4364 r4866  
    667667    public function buildRecord(array $definition) 
    668668    { 
    669         if ( !isset($definition['className'])) { 
     669        if ( ! isset($definition['className'])) { 
    670670            throw new Doctrine_Builder_Exception('Missing class name.'); 
    671671        } 
  • trunk/lib/Doctrine/ClassMetadata.php

    r4789 r4866  
    178178     * The name of the field in the Entity.  
    179179     *  
    180      * - <b>type</b> (string) 
    181      * The database type of the column. Can be one of Doctrine's portable types. 
     180     * - <b>type</b> (object Doctrine::DBAL::Types::* or custom type) 
     181     * The database type of the column. Can be one of Doctrine's portable types 
     182     * or a custom type. 
    182183     *  
    183184     * - <b>columnName</b> (string, optional) 
     
    185186     *  
    186187     * - <b>length</b> (integer, optional) 
    187      * The database length of the column. Optional. Defaults to Doctrine's  
    188      * default values for the portable types. 
     188     * The database length of the column. Optional. Default value taken from 
     189     * the type. 
    189190     *  
    190191     * - <b>id</b> (boolean, optional) 
     
    201202     * Whether the column is nullable. Defaults to TRUE. 
    202203     *  
    203      * - <b>columnDefinition</b> (string, optional) 
     204     * - <b>columnDefinition</b> (string, optional, schema-only) 
    204205     * The SQL fragment that is used when generating the DDL for the column. 
    205206     *  
    206      * - <b>precision</b> (integer, optional) 
     207     * - <b>precision</b> (integer, optional, schema-only) 
    207208     * The precision of a decimal column. Only valid if the column type is decimal. 
    208209     *  
    209      * - <b>scale</b> (integer, optional) 
     210     * - <b>scale</b> (integer, optional, schema-only) 
    210211     * The scale of a decimal column. Only valid if the column type is decimal. 
     212     *  
     213     * - <b>index (string, optional, schema-only)</b> 
     214     * Whether an index should be generated for the column. 
     215     * The value specifies the name of the index. To create a multi-column index, 
     216     * just use the same name for several mappings. 
     217     *  
     218     * - <b>unique (string, optional, schema-only)</b> 
     219     * Whether a unique constraint should be generated for the column. 
     220     * The value specifies the name of the unique constraint. To create a multi-column  
     221     * unique constraint, just use the same name for several mappings. 
     222     *  
     223     * - <b>foreignKey (string, optional, schema-only)</b> 
    211224     * 
    212225     * @var array 
     
    276289     *      -- charset                      character set 
    277290     * 
    278      *      -- checks                       the check constraints of this table, eg. 'price > dicounted_price' 
    279      * 
    280      *      -- collation                    collation attribute 
    281      * 
    282      *      -- indexes                      the index definitions of this table 
    283      * 
    284      *      -- sequenceName                 Some databases need sequences instead of auto incrementation primary keys, 
    285      *                                      you can set specific sequence for your table by calling setOption('sequenceName', $seqName) 
    286      *                                      where $seqName is the name of the desired sequence 
     291     *      -- collate                    collation attribute 
    287292     */ 
    288293    protected $_tableOptions = array( 
    289             'tableName'      => null, 
    290             'sequenceName'   => null, 
    291             'type'           => null, 
    292             'charset'        => null, 
    293             'collation'      => null, 
    294             'collate'        => null, 
    295             'indexes'        => array(), 
    296             'checks'         => array() 
     294            'tableName' => null, 
     295            'type' => null, 
     296            'charset' => null, 
     297            'collate' => null 
    297298    ); 
    298299     
     
    320321     
    321322    /** 
    322      * The association mappings. 
     323     * The association mappings. All mappings, inverse and owning side. 
    323324     * 
    324325     * @var array 
    325326     */ 
    326327    protected $_associationMappings = array(); 
     328     
     329    /** 
     330     * List of inverse association mappings, indexed by mappedBy field name. 
     331     * 
     332     * @var array 
     333     */ 
     334    protected $_inverseMappings = array(); 
    327335     
    328336    /** 
     
    552560         
    553561        return $this->_associationMappings[$fieldName]; 
     562    } 
     563     
     564    /** 
     565     * Gets the inverse association mapping for the given fieldname. 
     566     * 
     567     * @param string $mappedByFieldName 
     568     * @return Doctrine::ORM::Mapping::AssociationMapping The mapping. 
     569     */ 
     570    public function getInverseAssociationMapping($mappedByFieldName) 
     571    { 
     572        if ( ! isset($this->_associationMappings[$fieldName])) { 
     573            throw Doctrine_MappingException::mappingNotFound($fieldName); 
     574        } 
     575         
     576        return $this->_inverseMappings[$mappedByFieldName]; 
     577    } 
     578     
     579    /** 
     580     * Whether the class has an inverse association mapping on the given fieldname. 
     581     * 
     582     * @param string $mappedByFieldName 
     583     * @return boolean 
     584     */ 
     585    public function hasInverseAssociationMapping($mappedByFieldName) 
     586    { 
     587        return isset($this->_inverseMappings[$mappedByFieldName]); 
    554588    } 
    555589     
     
    719753                $this->_isIdentifierComposite = true; 
    720754            } 
    721              
    722755        } 
    723756         
     
    12731306            // Remove inherited, non-pk fields. They're not in the table of this class 
    12741307            foreach ($allColumns as $name => $definition) { 
    1275                 if (isset($definition['primary']) && $definition['primary'] === true) { 
     1308                if (isset($definition['id']) && $definition['id'] === true) { 
    12761309                    if ($this->getParentClasses() && isset($definition['autoincrement'])) { 
    12771310                        unset($allColumns[$name]['autoincrement']); 
     
    12871320            if ($this->getParentClasses()) { 
    12881321                foreach ($allColumns as $name => $definition) { 
    1289                     if (isset($definition['primary']) && $definition['primary'] === true) { 
     1322                    if (isset($definition['id']) && $definition['id'] === true) { 
    12901323                        if (isset($definition['autoincrement'])) { 
    12911324                            unset($allColumns[$name]['autoincrement']); 
     
    13121345            $columns[$name] = $definition; 
    13131346 
    1314             if (isset($definition['primary']) && $definition['primary']) { 
     1347            if (isset($definition['id']) && $definition['id']) { 
    13151348                $primary[] = $name; 
    13161349            } 
     
    14941527        $mapping = $this->_completeAssociationMapping($mapping); 
    14951528        $oneToOneMapping = new Doctrine_Association_OneToOne($mapping); 
    1496         $sourceFieldName = $oneToOneMapping->getSourceFieldName(); 
     1529        $this->_storeAssociationMapping($oneToOneMapping); 
     1530         
     1531        /*if ($oneToOneMapping->isInverseSide()) { 
     1532            //FIXME: infinite recursion possible? 
     1533            // Alternative: Store inverse side mappings indexed by mappedBy fieldname 
     1534            // ($this->_inverseMappings). Then look it up.             
     1535            $owningClass = $this->_em->getClassMetadata($oneToOneMapping->getTargetEntityName()); 
     1536            $owningClass->getAssociationMapping($oneToOneMapping->getMappedByFieldName()) 
     1537                    ->setBidirectional($oneToOneMapping->getSourceFieldName()); 
     1538        }*/ 
     1539    } 
     1540     
     1541    private function _registerMappingIfInverse(Doctrine_Association $assoc) 
     1542    { 
     1543        if ($assoc->isInverseSide()) { 
     1544            $this->_inverseMappings[$assoc->getMappedByFieldName()] = $assoc; 
     1545        } 
     1546    } 
     1547 
     1548    /** 
     1549     * Adds a one-to-many mapping. 
     1550     *  
     1551     * @param array $mapping The mapping. 
     1552     */ 
     1553    public function mapOneToMany(array $mapping) 
     1554    { 
     1555        $mapping = $this->_completeAssociationMapping($mapping); 
     1556        $oneToManyMapping = new Doctrine_Association_OneToMany($mapping); 
     1557        $this->_storeAssociationMapping($oneToManyMapping); 
     1558    } 
     1559 
     1560    /** 
     1561     * Adds a many-to-one mapping. 
     1562     *  
     1563     * @param array $mapping The mapping. 
     1564     */ 
     1565    public function mapManyToOne(array $mapping) 
     1566    { 
     1567        // A many-to-one mapping is simply a one-one backreference 
     1568        $this->mapOneToOne($mapping); 
     1569    } 
     1570 
     1571    /** 
     1572     * Adds a many-to-many mapping. 
     1573     *  
     1574     * @param array $mapping The mapping. 
     1575     */ 
     1576    public function mapManyToMany(array $mapping) 
     1577    { 
     1578        $mapping = $this->_completeAssociationMapping($mapping); 
     1579        $manyToManyMapping = new Doctrine_Association_ManyToManyMapping($mapping); 
     1580        $this->_storeAssociationMapping($manyToManyMapping); 
     1581    } 
     1582     
     1583    /** 
     1584     * Stores the association mapping. 
     1585     * 
     1586     * @param Doctrine_Association $assocMapping 
     1587     */ 
     1588    private function _storeAssociationMapping(Doctrine_Association $assocMapping) 
     1589    { 
     1590        $sourceFieldName = $assocMapping->getSourceFieldName(); 
    14971591        if (isset($this->_associationMappings[$sourceFieldName])) { 
    14981592            throw Doctrine_MappingException::duplicateFieldMapping(); 
    14991593        } 
    1500         $this->_associationMappings[$sourceFieldName] = $oneToOneMapping; 
    1501         $this->_registerCustomAssociationAccessors($oneToOneMapping, $sourceFieldName); 
    1502     } 
    1503  
    1504     /** 
    1505      * Adds a one-to-many mapping. 
    1506      *  
    1507      * @param array $mapping The mapping. 
    1508      */ 
    1509     public function mapOneToMany(array $mapping) 
    1510     { 
    1511         $mapping = $this->_completeAssociationMapping($mapping); 
    1512         $oneToManyMapping = new Doctrine_Association_OneToMany($mapping); 
    1513         $sourceFieldName = $oneToManyMapping->getSourceFieldName(); 
    1514         if (isset($this->_associationMappings[$sourceFieldName])) { 
    1515             throw Doctrine_MappingException::duplicateFieldMapping(); 
    1516         } 
    1517         $this->_associationMappings[$sourceFieldName] = $oneToManyMapping; 
    1518         $this->_registerCustomAssociationAccessors($oneToManyMapping, $sourceFieldName); 
    1519     } 
    1520  
    1521     /** 
    1522      * Adds a many-to-one mapping. 
    1523      *  
    1524      * @param array $mapping The mapping. 
    1525      */ 
    1526     public function mapManyToOne(array $mapping) 
    1527     { 
    1528         // A many-to-one mapping is simply a one-one backreference 
    1529         $this->mapOneToOne($mapping); 
    1530     } 
    1531  
    1532     /** 
    1533      * @todo Implementation. 
    1534      */ 
    1535     public function mapManyToMany(array $mapping) 
    1536     { 
    1537  
     1594        $this->_associationMappings[$sourceFieldName] = $assocMapping; 
     1595        $this->_registerCustomAssociationAccessors($assocMapping, $sourceFieldName); 
     1596        $this->_registerMappingIfInverse($assocMapping); 
    15381597    } 
    15391598     
  • trunk/lib/Doctrine/Collection.php

    r4789 r4866  
    3232 * A collection of entities represents only the associations (links) to those entities. 
    3333 * That means, if the collection is part of a many-many mapping and you remove 
    34  * entities from the collection, only the links in the xref table are removed. 
     34 * entities from the collection, only the links in the xref table are removed (on flush). 
    3535 * Similarly, if you remove entities from a collection that is part of a one-many 
    36  * mapping this will only result in the nulling out of the foreign keys 
     36 * mapping this will only result in the nulling out of the foreign keys on flush 
    3737 * (or removal of the links in the xref table if the one-many is mapped through an 
    3838 * xref table). If you want entities in a one-many collection to be removed when 
     
    4545 * @author    Konsta Vesterinen <kvesteri@cc.hut.fi> 
    4646 * @author    Roman Borschel <roman@code-factory.org> 
     47 * @todo Add more typical Collection methods. 
    4748 */ 
    4849class Doctrine_Collection implements Countable, IteratorAggregate, Serializable, ArrayAccess 
     
    8788 
    8889    /** 
    89      * The name of the column that is used for collection key mapping. 
     90     * The name of the field that is used for collection key mapping. 
    9091     * 
    9192     * @var string 
     
    101102     
    102103    /** 
    103      * The EntityManager. 
    104      * 
    105      * @var EntityManager 
     104     * The EntityManager that manages the persistence of the collection. 
     105     * 
     106     * @var Doctrine::ORM::EntityManager 
    106107     */ 
    107108    protected $_em; 
     109     
     110    /** 
     111     * The name of the field on the target entities that points to the owner 
     112     * of the collection. This is only set if the association is bidirectional. 
     113     * 
     114     * @var string 
     115     */ 
     116    protected $_backRefFieldName; 
     117     
     118    /** 
     119     * Hydration flag. 
     120     * 
     121     * @var boolean 
     122     * @see _setHydrationFlag() 
     123     */ 
     124    protected $_hydrationFlag; 
    108125 
    109126    /** 
    110127     * Constructor. 
     128     * Creates a new persistent collection. 
    111129     */ 
    112130    public function __construct($entityBaseType, $keyField = null) 
     
    127145     * 
    128146     * @param array $data 
     147     * @todo Remove? 
    129148     */ 
    130149    public function setData(array $data)  
     
    134153 
    135154    /** 
    136      * Serializes the collection. 
    137      * This method is automatically called when the Collection is serialized. 
    138      * 
    139      * Part of the implementation of the Serializable interface. 
    140      * 
    141      * @return array 
    142      */ 
    143     public function serialize() 
    144     { 
    145         $vars = get_object_vars($this); 
    146  
    147         unset($vars['reference']); 
    148         unset($vars['relation']); 
    149         unset($vars['expandable']); 
    150         unset($vars['expanded']); 
    151         unset($vars['generator']); 
    152  
    153         return serialize($vars); 
    154     } 
    155  
    156     /** 
    157      * Reconstitutes the collection object from it's serialized form. 
    158      * This method is automatically called everytime the Collection object is unserialized. 
    159      * 
    160      * Part of the implementation of the Serializable interface. 
    161      * 
    162      * @param string $serialized The serialized data 
    163      * 
    164      * @return void 
    165      */ 
    166     public function unserialize($serialized) 
    167     { 
    168         $manager = Doctrine_EntityManagerFactory::getManager(); 
    169         $connection = $manager->getConnection(); 
    170          
    171         $array = unserialize($serialized); 
    172  
    173         foreach ($array as $name => $values) { 
    174             $this->$name = $values; 
    175         } 
    176  
    177         $keyColumn = isset($array['keyField']) ? $array['keyField'] : null; 
    178  
    179         if ($keyColumn !== null) { 
    180             $this->_keyField = $keyColumn; 
    181         } 
    182     } 
    183  
    184     /** 
    185      * Sets the key column for this collection 
     155     * INTERNAL: Sets the key column for this collection 
    186156     * 
    187157     * @param string $column 
     
    195165 
    196166    /** 
    197      * returns the name of the key column 
     167     * INTERNAL: returns the name of the key column 
    198168     * 
    199169     * @return string 
     
    209179     * @return array 
    210180     */ 
    211     public function getData() 
     181    public function unwrap() 
    212182    { 
    213183        return $this->_data; 
     
    256226    /** 
    257227     * INTERNAL: 
    258      * sets a reference pointer 
     228     * Sets the collection owner. Used (only?) during hydration. 
    259229     * 
    260230     * @return void 
    261231     */ 
    262     public function setReference(Doctrine_Entity $entity, Doctrine_Association $relation) 
     232    public function _setOwner(Doctrine_Entity $entity, Doctrine_Association $relation) 
    263233    { 
    264234        $this->_owner = $entity; 
    265235        $this->_association = $relation; 
    266  
    267         /*if ($relation instanceof Doctrine_Relation_ForeignKey ||  
    268                 $relation instanceof Doctrine_Relation_LocalKey) { 
    269             $this->referenceField = $relation->getForeignFieldName(); 
    270             $value = $entity->get($relation->getLocalFieldName()); 
    271             foreach ($this->_data as $entity) { 
    272                 if ($value !== null) { 
    273                     $entity->set($this->referenceField, $value, false); 
    274                 } else { 
    275                     $entity->set($this->referenceField, $this->_owner, false); 
    276                 } 
    277             } 
    278         } else if ($relation instanceof Doctrine_Relation_Association) { 
    279  
    280         }*/ 
     236        if ($relation->isInverseSide()) { 
     237            // for sure bidirectional 
     238            $this->_backRefFieldName = $relation->getMappedByFieldName(); 
     239        } else { 
     240            $targetClass = $this->_em->getClassMetadata($relation->getTargetEntityName()); 
     241            if ($targetClass->hasInverseAssociationMapping($relation->getSourceFieldName())) { 
     242                // bidirectional 
     243                $this->_backRefFieldName = $targetClass->getInverseAssociationMapping( 
     244                        $relation->getSourceFieldName())->getSourceFieldName(); 
     245            } 
     246        } 
    281247    } 
    282248 
     
    287253     * @return mixed 
    288254     */ 
    289     public function getReference() 
     255    public function _getOwner() 
    290256    { 
    291257        return $this->_owner;