continued refactorings.
This commit is contained in:
parent
3e20fc6aba
commit
d8b76a54d0
@ -34,8 +34,7 @@
|
||||
* @since 1.0
|
||||
* @version $Revision$
|
||||
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||
* @todo Consider making Collection & Entity implement ArrayAccess directly.
|
||||
* This base class is not really a huge benefit.
|
||||
* @todo Remove.
|
||||
*/
|
||||
abstract class Doctrine_Access implements ArrayAccess
|
||||
{
|
||||
|
@ -24,8 +24,8 @@
|
||||
/**
|
||||
* Base class for association mappings.
|
||||
*
|
||||
* @since 2.0
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
* @since 2.0
|
||||
* @todo Rename to AssociationMapping.
|
||||
*/
|
||||
class Doctrine_Association implements Serializable
|
||||
@ -52,6 +52,9 @@ class Doctrine_Association implements Serializable
|
||||
protected $_isCascadeSave;
|
||||
protected $_isCascadeRefresh;
|
||||
|
||||
protected $_customAccessor;
|
||||
protected $_customMutator;
|
||||
|
||||
/**
|
||||
* The fetch mode used for the association.
|
||||
*
|
||||
@ -67,6 +70,14 @@ class Doctrine_Association implements Serializable
|
||||
*/
|
||||
protected $_isOwningSide = true;
|
||||
|
||||
/**
|
||||
* Whether the association is optional (0..X) or not (1..X).
|
||||
* By default all associations are optional.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
protected $_isOptional = true;
|
||||
|
||||
/**
|
||||
* The name of the source Entity (the Entity that defines this mapping).
|
||||
*
|
||||
@ -84,7 +95,8 @@ class Doctrine_Association implements Serializable
|
||||
|
||||
/**
|
||||
* Identifies the field on the source class (the class this AssociationMapping
|
||||
* belongs to) that represents the association.
|
||||
* belongs to) that represents the association and stores the reference to the
|
||||
* other entity/entities.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
@ -106,12 +118,13 @@ class Doctrine_Association implements Serializable
|
||||
*/
|
||||
public function __construct(array $mapping)
|
||||
{
|
||||
$this->_validateMapping($mapping);
|
||||
if ($this->_isOwningSide) {
|
||||
$this->_sourceEntityName = $mapping['sourceEntity'];
|
||||
$this->_targetEntityName = $mapping['targetEntity'];
|
||||
$this->_sourceFieldName = $mapping['fieldName'];
|
||||
} else {
|
||||
$this->_validateAndCompleteMapping($mapping);
|
||||
|
||||
$this->_sourceEntityName = $mapping['sourceEntity'];
|
||||
$this->_targetEntityName = $mapping['targetEntity'];
|
||||
$this->_sourceFieldName = $mapping['fieldName'];
|
||||
|
||||
if ( ! $this->_isOwningSide) {
|
||||
$this->_mappedByFieldName = $mapping['mappedBy'];
|
||||
}
|
||||
}
|
||||
@ -122,23 +135,50 @@ class Doctrine_Association implements Serializable
|
||||
* @param array $mapping
|
||||
* @return array The validated & completed mapping.
|
||||
*/
|
||||
protected function _validateMapping(array $mapping)
|
||||
protected function _validateAndCompleteMapping(array $mapping)
|
||||
{
|
||||
if (isset($mapping['mappedBy'])) {
|
||||
// Inverse side, mapping can be found on the owning side.
|
||||
$this->_isOwningSide = false;
|
||||
} else {
|
||||
// Owning side
|
||||
}
|
||||
|
||||
if ($this->_isOwningSide) {
|
||||
if ( ! isset($mapping['targetEntity'])) {
|
||||
throw Doctrine_MappingException::missingTargetEntity();
|
||||
} else if ( ! isset($mapping['fieldName'])) {
|
||||
throw Doctrine_MappingException::missingFieldName();
|
||||
}
|
||||
// Mandatory attributes
|
||||
if ( ! isset($mapping['fieldName'])) {
|
||||
throw Doctrine_MappingException::missingFieldName();
|
||||
}
|
||||
if ( ! isset($mapping['sourceEntity'])) {
|
||||
throw Doctrine_MappingException::missingSourceEntity($mapping['fieldName']);
|
||||
}
|
||||
if ( ! isset($mapping['targetEntity'])) {
|
||||
throw Doctrine_MappingException::missingTargetEntity($mapping['fieldName']);
|
||||
}
|
||||
|
||||
// Optional attributes
|
||||
$this->_customAccessor = isset($mapping['accessor']) ? $mapping['accessor'] : null;
|
||||
$this->_customMutator = isset($mapping['mutator']) ? $mapping['mutator'] : null;
|
||||
$this->_isOptional = isset($mapping['isOptional']) ? (bool)$mapping['isOptional'] : true;
|
||||
|
||||
return $mapping;
|
||||
}
|
||||
|
||||
protected function _validateAndCompleteInverseSideMapping()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected function _validateAndCompleteOwningSideMapping()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the association cascades delete() operations from the source entity
|
||||
* to the target entity/entities.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isCascadeDelete()
|
||||
{
|
||||
if (is_null($this->_isCascadeDelete)) {
|
||||
@ -147,6 +187,12 @@ class Doctrine_Association implements Serializable
|
||||
return $this->_isCascadeDelete;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the association cascades save() operations from the source entity
|
||||
* to the target entity/entities.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isCascadeSave()
|
||||
{
|
||||
if (is_null($this->_isCascadeSave)) {
|
||||
@ -155,6 +201,12 @@ class Doctrine_Association implements Serializable
|
||||
return $this->_isCascadeSave;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the association cascades refresh() operations from the source entity
|
||||
* to the target entity/entities.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isCascadeRefresh()
|
||||
{
|
||||
if (is_null($this->_isCascadeRefresh)) {
|
||||
@ -163,36 +215,81 @@ class Doctrine_Association implements Serializable
|
||||
return $this->_isCascadeRefresh;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the target entity/entities of the association are eagerly fetched.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isEagerlyFetched()
|
||||
{
|
||||
return $this->_fetchMode == self::FETCH_EAGER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the target entity/entities of the association are lazily fetched.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isLazilyFetched()
|
||||
{
|
||||
return $this->_fetchMode == self::FETCH_LAZY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the target entity/entities of the association are manually fetched.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isManuallyFetched()
|
||||
{
|
||||
return $this->_fetchMode == self::FETCH_MANUAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the source entity of this association represents the owning side.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isOwningSide()
|
||||
{
|
||||
return $this->_isOwningSide;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the source entity of this association represents the inverse side.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isInverseSide()
|
||||
{
|
||||
return ! $this->_isOwningSide;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the association is optional (0..X), or not (1..X).
|
||||
*
|
||||
* @return boolean TRUE if the association is optional, FALSE otherwise.
|
||||
*/
|
||||
public function isOptional()
|
||||
{
|
||||
return $this->_isOptional;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the source entity class.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSourceEntityName()
|
||||
{
|
||||
return $this->_sourceEntityName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the target entity class.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getTargetEntityName()
|
||||
{
|
||||
return $this->_targetEntityName;
|
||||
@ -201,17 +298,80 @@ class Doctrine_Association implements Serializable
|
||||
/**
|
||||
* Get the name of the field the association is mapped into.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSourceFieldName()
|
||||
{
|
||||
return $this->_sourceFieldName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the field name of the owning side in a bi-directional association.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getMappedByFieldName()
|
||||
{
|
||||
return $this->_mappedByFieldName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the source field of the association has a custom accessor.
|
||||
*
|
||||
* @return boolean TRUE if the source field of the association has a custom accessor,
|
||||
* FALSE otherwise.
|
||||
*/
|
||||
public function hasCustomAccessor()
|
||||
{
|
||||
return isset($this->_customAccessor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the custom accessor method of the source field.
|
||||
*
|
||||
* @return string The name of the accessor method or NULL.
|
||||
*/
|
||||
public function getCustomAccessor()
|
||||
{
|
||||
return $this->_customAccessor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the source field of the association has a custom mutator.
|
||||
*
|
||||
* @return boolean TRUE if the source field of the association has a custom mutator,
|
||||
* FALSE otherwise.
|
||||
*/
|
||||
public function hasCustomMutator()
|
||||
{
|
||||
return isset($this->_customMutator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the custom mutator method of the source field.
|
||||
*
|
||||
* @return string The name of the mutator method or NULL.
|
||||
*/
|
||||
public function getCustomMutator()
|
||||
{
|
||||
return $this->_customMutator;
|
||||
}
|
||||
|
||||
public function isOneToOne()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function isOneToMany()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function isManyToMany()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Serializable implementation */
|
||||
|
||||
public function serialize()
|
||||
|
@ -105,6 +105,17 @@ class Doctrine_Association_OneToOne extends Doctrine_Association
|
||||
return $this->_targetToSourceKeyColumns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the association is one-to-one.
|
||||
*
|
||||
* @return boolean
|
||||
* @override
|
||||
*/
|
||||
public function isOneToOne()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazy-loads the associated entity for a given entity.
|
||||
*
|
||||
|
@ -48,12 +48,18 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable
|
||||
const GENERATOR_TYPE_NONE = 'none';
|
||||
|
||||
/* The Entity types */
|
||||
// A regular entity is assumed to have persistent state that Doctrine should manage.
|
||||
/**
|
||||
* A regular entity is assumed to have persistent state that Doctrine should manage.
|
||||
*/
|
||||
const ENTITY_TYPE_REGULAR = 'regular';
|
||||
// A transient entity is ignored by Doctrine.
|
||||
/**
|
||||
* A transient entity is ignored by Doctrine.
|
||||
*/
|
||||
const ENTITY_TYPE_TRANSIENT = 'transient';
|
||||
// A mapped superclass entity is itself not persisted by Doctrine but it's
|
||||
// field & association mappings are inherited by subclasses.
|
||||
/**
|
||||
* A mapped superclass entity is itself not persisted by Doctrine but it's
|
||||
* field & association mappings are inherited by subclasses.
|
||||
*/
|
||||
const ENTITY_TYPE_MAPPED_SUPERCLASS = 'mappedSuperclass';
|
||||
|
||||
/**
|
||||
@ -123,15 +129,6 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable
|
||||
*/
|
||||
protected $_generatorType = self::GENERATOR_TYPE_NONE;
|
||||
|
||||
/**
|
||||
* An array containing all behaviors attached to the class.
|
||||
*
|
||||
* @see Doctrine_Template
|
||||
* @var array $_templates
|
||||
* @todo Unify under 'Behaviors'.
|
||||
*/
|
||||
//protected $_behaviors = array();
|
||||
|
||||
/**
|
||||
* The field mappings of the class.
|
||||
* Keys are field names and values are mapping definitions.
|
||||
@ -219,13 +216,6 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable
|
||||
*/
|
||||
protected $_lcColumnToFieldNames = array();
|
||||
|
||||
/**
|
||||
* Enter description here...
|
||||
*
|
||||
* @var unknown_type
|
||||
*/
|
||||
//protected $_subclassFieldNames = array();
|
||||
|
||||
/**
|
||||
* Relation parser object. Manages the relations for the class.
|
||||
*
|
||||
@ -311,10 +301,14 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable
|
||||
*/
|
||||
protected $_isIdentifierComposite = false;
|
||||
|
||||
protected $_customAssociationAccessors = array();
|
||||
protected $_customAssociationMutators = array();
|
||||
|
||||
/**
|
||||
* Constructs a new ClassMetadata instance.
|
||||
*
|
||||
* @param string $entityName Name of the entity class the metadata info is used for.
|
||||
* @param Doctrine::ORM::Entitymanager $em
|
||||
*/
|
||||
public function __construct($entityName, Doctrine_EntityManager $em)
|
||||
{
|
||||
@ -326,13 +320,10 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* Gets the EntityManager that holds this ClassMetadata.
|
||||
*
|
||||
* @return Doctrine::ORM::EntityManager
|
||||
*/
|
||||
public function getConnection()
|
||||
{
|
||||
return $this->_em;
|
||||
}
|
||||
|
||||
public function getEntityManager()
|
||||
{
|
||||
return $this->_em;
|
||||
@ -360,14 +351,6 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable
|
||||
return $this->_rootEntityName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
public function getComponentName()
|
||||
{
|
||||
return $this->getClassName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a field is part of the identifier/primary key field(s).
|
||||
*
|
||||
@ -429,8 +412,6 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable
|
||||
}
|
||||
|
||||
/**
|
||||
* addIndex
|
||||
*
|
||||
* adds an index to this table
|
||||
*
|
||||
* @return void
|
||||
@ -458,22 +439,6 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* setOption
|
||||
* sets an option and returns this object in order to
|
||||
* allow flexible method chaining
|
||||
*
|
||||
* @see Doctrine_Table::$_options for available options
|
||||
* @param string $name the name of the option to set
|
||||
* @param mixed $value the value of the option
|
||||
* @return Doctrine_Table this object
|
||||
* @deprecated
|
||||
*/
|
||||
public function setOption($name, $value)
|
||||
{
|
||||
$this->_options[$name] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a table option.
|
||||
*/
|
||||
@ -497,43 +462,6 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable
|
||||
return $this->_tableOptions[$name];
|
||||
}
|
||||
|
||||
/*public function getBehaviorForMethod($method)
|
||||
{
|
||||
return (isset($this->_invokedMethods[$method])) ?
|
||||
$this->_invokedMethods[$method] : false;
|
||||
}
|
||||
public function addBehaviorMethod($method, $behavior)
|
||||
{
|
||||
$this->_invokedMethods[$method] = $class;
|
||||
}*/
|
||||
|
||||
/**
|
||||
* returns the value of given option
|
||||
*
|
||||
* @param string $name the name of the option
|
||||
* @return mixed the value of given option
|
||||
*/
|
||||
public function getOption($name)
|
||||
{
|
||||
if (isset($this->_options[$name])) {
|
||||
return $this->_options[$name];
|
||||
} else if (isset($this->_tableOptions[$name])) {
|
||||
return $this->_tableOptions[$name];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* getOptions
|
||||
* returns all options of this table and the associated values
|
||||
*
|
||||
* @return array all options and their values
|
||||
*/
|
||||
public function getOptions()
|
||||
{
|
||||
return $this->_options;
|
||||
}
|
||||
|
||||
/**
|
||||
* getTableOptions
|
||||
* returns all table options.
|
||||
@ -703,8 +631,8 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable
|
||||
/**
|
||||
* Validates & completes the field mapping. Default values are applied here.
|
||||
*
|
||||
* @param array $mapping
|
||||
* @return array
|
||||
* @param array $mapping The field mapping to validated & complete.
|
||||
* @return array The validated and completed field mapping.
|
||||
*/
|
||||
private function _validateAndCompleteFieldMapping(array $mapping)
|
||||
{
|
||||
@ -800,18 +728,6 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable
|
||||
//...
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the names of all validators that are applied on a field.
|
||||
*
|
||||
* @param string The field name.
|
||||
* @return array The names of all validators that are applied on the specified field.
|
||||
*/
|
||||
/*public function getFieldValidators($fieldName)
|
||||
{
|
||||
return isset($this->_fieldMappings[$fieldName]['validators']) ?
|
||||
$this->_fieldMappings[$fieldName]['validators'] : array();
|
||||
}*/
|
||||
|
||||
/**
|
||||
* Gets the identifier (primary key) field names of the class.
|
||||
*
|
||||
@ -871,8 +787,12 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable
|
||||
*/
|
||||
public function getCustomAccessor($fieldName)
|
||||
{
|
||||
return isset($this->_fieldMappings[$fieldName]['accessor']) ?
|
||||
$this->_fieldMappings[$fieldName]['accessor'] : null;
|
||||
if (isset($this->_fieldMappings[$fieldName]['accessor'])) {
|
||||
return $this->_fieldMappings[$fieldName]['accessor'];
|
||||
} else if (isset($this->_customAssociationAccessors[$fieldName])) {
|
||||
return $this->_customAssociationAccessors[$fieldName];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -883,8 +803,12 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable
|
||||
*/
|
||||
public function getCustomMutator($fieldName)
|
||||
{
|
||||
return isset($this->_fieldMappings[$fieldName]['mutator']) ?
|
||||
$this->_fieldMappings[$fieldName]['mutator'] : null;
|
||||
if (isset($this->_fieldMappings[$fieldName]['mutator'])) {
|
||||
return $this->_fieldMappings[$fieldName]['mutator'];
|
||||
} else if (isset($this->_customAssociationMutators[$fieldName])) {
|
||||
return $this->_customAssociationMutators[$fieldName];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1053,18 +977,6 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable
|
||||
//...
|
||||
}
|
||||
|
||||
/**
|
||||
* getBehaviors
|
||||
* returns all behaviors attached to the class.
|
||||
*
|
||||
* @return array an array containing all templates
|
||||
* @todo Unify under 'Behaviors'
|
||||
*/
|
||||
/*public function getBehaviors()
|
||||
{
|
||||
return $this->_behaviors;
|
||||
}*/
|
||||
|
||||
/**
|
||||
* Gets the inheritance type used by the class.
|
||||
*
|
||||
@ -1156,8 +1068,8 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable
|
||||
throw Doctrine_MappingException::invalidInheritanceType($type);
|
||||
}
|
||||
|
||||
if ($type == Doctrine::INHERITANCE_TYPE_SINGLE_TABLE ||
|
||||
$type == Doctrine::INHERITANCE_TYPE_JOINED) {
|
||||
if ($type == self::INHERITANCE_TYPE_SINGLE_TABLE ||
|
||||
$type == self::INHERITANCE_TYPE_JOINED) {
|
||||
$this->_checkRequiredDiscriminatorOptions($options);
|
||||
}
|
||||
|
||||
@ -1240,25 +1152,25 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable
|
||||
}
|
||||
|
||||
/**
|
||||
* export
|
||||
* exports this class to the database based on its mapping.
|
||||
*
|
||||
* @throws Doctrine_Connection_Exception If some error other than Doctrine::ERR_ALREADY_EXISTS
|
||||
* occurred during the create table operation.
|
||||
* @return boolean Whether or not the export operation was successful
|
||||
* false if table already existed in the database.
|
||||
* @todo Reimpl. & Placement.
|
||||
*/
|
||||
public function export()
|
||||
{
|
||||
$this->_em->export->exportTable($this);
|
||||
//$this->_em->export->exportTable($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* getExportableFormat
|
||||
* Returns an array with all the information needed to create the main database table
|
||||
* for the class.
|
||||
*
|
||||
* @return array
|
||||
* @todo Reimpl. & placement.
|
||||
*/
|
||||
public function getExportableFormat($parseForeignKeys = true)
|
||||
{
|
||||
@ -1268,7 +1180,7 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable
|
||||
|
||||
// If the class is part of a Single Table Inheritance hierarchy, collect the fields
|
||||
// of all classes in the hierarchy.
|
||||
if ($this->_inheritanceType == Doctrine::INHERITANCE_TYPE_SINGLE_TABLE) {
|
||||
if ($this->_inheritanceType == self::INHERITANCE_TYPE_SINGLE_TABLE) {
|
||||
$parents = $this->getParentClasses();
|
||||
if ($parents) {
|
||||
$rootClass = $this->_em->getClassMetadata(array_pop($parents));
|
||||
@ -1280,7 +1192,7 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable
|
||||
$subClassMetadata = $this->_em->getClassMetadata($subClass);
|
||||
$allColumns = array_merge($allColumns, $subClassMetadata->getColumns());
|
||||
}
|
||||
} else if ($this->_inheritanceType == Doctrine::INHERITANCE_TYPE_JOINED) {
|
||||
} else if ($this->_inheritanceType == self::INHERITANCE_TYPE_JOINED) {
|
||||
// Remove inherited, non-pk fields. They're not in the table of this class
|
||||
foreach ($allColumns as $name => $definition) {
|
||||
if (isset($definition['primary']) && $definition['primary'] === true) {
|
||||
@ -1293,7 +1205,7 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable
|
||||
unset($allColumns[$name]);
|
||||
}
|
||||
}
|
||||
} else if ($this->_inheritanceType == Doctrine::INHERITANCE_TYPE_TABLE_PER_CLASS) {
|
||||
} else if ($this->_inheritanceType == self::INHERITANCE_TYPE_TABLE_PER_CLASS) {
|
||||
// If this is a subclass, just remove existing autoincrement options on the pk
|
||||
if ($this->getParentClasses()) {
|
||||
foreach ($allColumns as $name => $definition) {
|
||||
@ -1423,7 +1335,7 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given name identifies an entity type.
|
||||
* Checks whether the given type identifies an entity type.
|
||||
*
|
||||
* @param string $type
|
||||
* @return boolean
|
||||
@ -1436,7 +1348,7 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given name identifies an inheritance type.
|
||||
* Checks whether the given type identifies an inheritance type.
|
||||
*
|
||||
* @param string $type
|
||||
* @return boolean
|
||||
@ -1450,7 +1362,7 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given name identifies an id generator type.
|
||||
* Checks whether the given type identifies an id generator type.
|
||||
*
|
||||
* @param string $type
|
||||
* @return boolean
|
||||
@ -1464,6 +1376,37 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable
|
||||
$type == self::GENERATOR_TYPE_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes some automatic additions to the association mapping to make the life
|
||||
* easier for the user.
|
||||
*
|
||||
* @param array $mapping
|
||||
* @return unknown
|
||||
* @todo Pass param by ref?
|
||||
*/
|
||||
private function _completeAssociationMapping(array $mapping)
|
||||
{
|
||||
$mapping['sourceEntity'] = $this->_entityName;
|
||||
return $mapping;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers any custom accessors/mutators in the given association mapping in
|
||||
* an internal cache for fast lookup.
|
||||
*
|
||||
* @param Doctrine_Association $assoc
|
||||
* @param unknown_type $fieldName
|
||||
*/
|
||||
private function _registerCustomAssociationAccessors(Doctrine_Association $assoc, $fieldName)
|
||||
{
|
||||
if ($acc = $assoc->getCustomAccessor()) {
|
||||
$this->_customAssociationAccessors[$fieldName] = $acc;
|
||||
}
|
||||
if ($mut = $assoc->getCustomMutator()) {
|
||||
$this->_customAssociationMutators[$fieldName] = $mut;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a one-to-one association mapping.
|
||||
*
|
||||
@ -1471,11 +1414,14 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable
|
||||
*/
|
||||
public function mapOneToOne(array $mapping)
|
||||
{
|
||||
$mapping = $this->_completeAssociationMapping($mapping);
|
||||
$oneToOneMapping = new Doctrine_Association_OneToOne($mapping);
|
||||
if (isset($this->_associationMappings[$oneToOneMapping->getSourceFieldName()])) {
|
||||
$sourceFieldName = $oneToOneMapping->getSourceFieldName();
|
||||
if (isset($this->_associationMappings[$sourceFieldName])) {
|
||||
throw Doctrine_MappingException::duplicateFieldMapping();
|
||||
}
|
||||
$this->_associationMappings[$oneToOneMapping->getSourceFieldName()] = $oneToOneMapping;
|
||||
$this->_associationMappings[$sourceFieldName] = $oneToOneMapping;
|
||||
$this->_registerCustomAssociationAccessors($oneToOneMapping, $sourceFieldName);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1483,7 +1429,14 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable
|
||||
*/
|
||||
public function mapOneToMany(array $mapping)
|
||||
{
|
||||
|
||||
$mapping = $this->_completeAssociationMapping($mapping);
|
||||
$oneToManyMapping = new Doctrine_Association_OneToMany($mapping);
|
||||
$sourceFieldName = $oneToManyMapping->getSourceFieldName();
|
||||
if (isset($this->_associationMappings[$sourceFieldName])) {
|
||||
throw Doctrine_MappingException::duplicateFieldMapping();
|
||||
}
|
||||
$this->_associationMappings[$sourceFieldName] = $oneToManyMapping;
|
||||
$this->_registerCustomAssociationAccessors($oneToManyMapping, $sourceFieldName);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1502,79 +1455,10 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* actAs
|
||||
* loads the given plugin
|
||||
*
|
||||
* @param mixed $tpl
|
||||
* @param array $options
|
||||
* @todo Unify under 'Behaviors'.
|
||||
*/
|
||||
/*public function actAs($tpl, array $options = array())
|
||||
{
|
||||
if ( ! is_object($tpl)) {
|
||||
if (class_exists($tpl, true)) {
|
||||
$tpl = new $tpl($options);
|
||||
} else {
|
||||
$className = 'Doctrine_Template_' . $tpl;
|
||||
if ( ! class_exists($className, true)) {
|
||||
throw new Doctrine_Record_Exception("Couldn't load plugin.");
|
||||
}
|
||||
$tpl = new $className($options);
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! ($tpl instanceof Doctrine_Template)) {
|
||||
throw new Doctrine_Record_Exception('Loaded plugin class is not an instance of Doctrine_Template.');
|
||||
}
|
||||
|
||||
$className = get_class($tpl);
|
||||
|
||||
$this->addBehavior($className, $tpl);
|
||||
|
||||
$tpl->setTable($this);
|
||||
$tpl->setUp();
|
||||
$tpl->setTableDefinition();
|
||||
|
||||
return $this;
|
||||
}*/
|
||||
|
||||
/**
|
||||
* check
|
||||
* adds a check constraint
|
||||
*
|
||||
* @param mixed $constraint either a SQL constraint portion or an array of CHECK constraints
|
||||
* @param string $name optional constraint name
|
||||
* @return Doctrine_Entity this object
|
||||
* @todo Should be done through $_tableOptions
|
||||
* @deprecated
|
||||
*/
|
||||
/*public function check($constraint, $name = null)
|
||||
{
|
||||
if (is_array($constraint)) {
|
||||
foreach ($constraint as $name => $def) {
|
||||
$this->_addCheckConstraint($def, $name);
|
||||
}
|
||||
} else {
|
||||
$this->_addCheckConstraint($constraint, $name);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
protected function _addCheckConstraint($definition, $name)
|
||||
{
|
||||
if (is_string($name)) {
|
||||
$this->_tableOptions['checks'][$name] = $definition;
|
||||
} else {
|
||||
$this->_tableOptions['checks'][] = $definition;
|
||||
}
|
||||
}*/
|
||||
|
||||
/**
|
||||
* Registers a custom mapper for the entity class.
|
||||
*
|
||||
* @param string $mapperClassName The class name of the custom mapper.
|
||||
* @deprecated
|
||||
*/
|
||||
public function setCustomRepositoryClass($repositoryClassName)
|
||||
{
|
||||
@ -1607,7 +1491,7 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable
|
||||
}
|
||||
|
||||
/**
|
||||
* Binds the entity instance of this class to a specific EntityManager.
|
||||
* Binds the entity instances of this class to a specific EntityManager.
|
||||
*
|
||||
* @todo Implementation. Replaces the bindComponent() methods on the old Doctrine_Manager.
|
||||
* Binding an Entity to a specific EntityManager in 2.0 is the same as binding
|
||||
@ -1698,6 +1582,24 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Completes the identifier mapping of the class.
|
||||
* NOTE: Should only be called by the ClassMetadataFactory!
|
||||
*/
|
||||
public function completeIdentifierMapping()
|
||||
{
|
||||
if ($this->getIdGeneratorType() == self::GENERATOR_TYPE_AUTO) {
|
||||
$platform = $this->_em->getConnection()->getDatabasePlatform();
|
||||
if ($platform->prefersSequences()) {
|
||||
$this->_generatorType = self::GENERATOR_TYPE_SEQUENCE;
|
||||
} else if ($platform->prefersIdentityColumns()) {
|
||||
$this->_generatorType = self::GENERATOR_TYPE_IDENTITY;
|
||||
} else {
|
||||
$this->_generatorType = self::GENERATOR_TYPE_TABLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Implementation. Immutable entities can not be updated or deleted once
|
||||
* they are created. This means the entity can only be modified as long as it's
|
||||
@ -1713,38 +1615,6 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable
|
||||
return $columnName === $this->_inheritanceOptions['discriminatorColumn'];
|
||||
}
|
||||
|
||||
/**
|
||||
* hasOne
|
||||
* binds One-to-One aggregate relation
|
||||
*
|
||||
* @param string $componentName the name of the related component
|
||||
* @param string $options relation options
|
||||
* @see Doctrine_Relation::_$definition
|
||||
* @return Doctrine_Entity this object
|
||||
*/
|
||||
public function hasOne()
|
||||
{
|
||||
$this->bind(func_get_args(), Doctrine_Relation::ONE_AGGREGATE);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* hasMany
|
||||
* binds One-to-Many / Many-to-Many aggregate relation
|
||||
*
|
||||
* @param string $componentName the name of the related component
|
||||
* @param string $options relation options
|
||||
* @see Doctrine_Relation::_$definition
|
||||
* @return Doctrine_Entity this object
|
||||
*/
|
||||
public function hasMany()
|
||||
{
|
||||
$this->bind(func_get_args(), Doctrine_Relation::MANY_AGGREGATE);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function hasAttribute($name)
|
||||
{
|
||||
return isset($this->_attributes[$name]);
|
||||
@ -1766,6 +1636,43 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable
|
||||
|
||||
/* The following stuff needs to be touched for the association mapping rewrite */
|
||||
|
||||
/**
|
||||
* hasOne
|
||||
* binds One-to-One aggregate relation
|
||||
*
|
||||
* @param string $componentName the name of the related component
|
||||
* @param string $options relation options
|
||||
* @see Doctrine_Relation::_$definition
|
||||
* @return Doctrine_Entity this object
|
||||
* @deprecated
|
||||
*/
|
||||
public function hasOne()
|
||||
{
|
||||
$this->bind(func_get_args(), Doctrine_Relation::ONE_AGGREGATE);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* hasMany
|
||||
* binds One-to-Many / Many-to-Many aggregate relation
|
||||
*
|
||||
* @param string $componentName the name of the related component
|
||||
* @param string $options relation options
|
||||
* @see Doctrine_Relation::_$definition
|
||||
* @return Doctrine_Entity this object
|
||||
* @deprecated
|
||||
*/
|
||||
public function hasMany()
|
||||
{
|
||||
$this->bind(func_get_args(), Doctrine_Relation::MANY_AGGREGATE);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
public function bindRelation($args, $type)
|
||||
{
|
||||
return $this->bind($args, $type);
|
||||
@ -1773,6 +1680,7 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable
|
||||
|
||||
/**
|
||||
* @todo Relation mapping rewrite.
|
||||
* @deprecated
|
||||
*/
|
||||
public function bind($args, $type)
|
||||
{
|
||||
@ -1798,22 +1706,32 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable
|
||||
*
|
||||
* @param string $alias the relation to check if exists
|
||||
* @return boolean true if the relation exists otherwise false
|
||||
* @deprecated
|
||||
*/
|
||||
public function hasRelation($alias)
|
||||
{
|
||||
return $this->_parser->hasRelation($alias);
|
||||
}
|
||||
|
||||
public function hasAssociation($fieldName)
|
||||
{
|
||||
return isset($this->_associationMappings[$fieldName]);
|
||||
}
|
||||
|
||||
/**
|
||||
* getRelation
|
||||
*
|
||||
* @param string $alias relation alias
|
||||
* @deprecated
|
||||
*/
|
||||
public function getRelation($alias, $recursive = true)
|
||||
{
|
||||
return $this->_parser->getRelation($alias, $recursive);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
public function getRelationParser()
|
||||
{
|
||||
return $this->_parser;
|
||||
@ -1824,34 +1742,13 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable
|
||||
* returns an array containing all relation objects
|
||||
*
|
||||
* @return array an array of Doctrine_Relation objects
|
||||
* @deprecated
|
||||
*/
|
||||
public function getRelations()
|
||||
{
|
||||
return $this->_parser->getRelations();
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Set by the factory if type is AUTO. Not pretty. Find sth. better.
|
||||
*/
|
||||
public function setIdGeneratorType($type)
|
||||
{
|
||||
$this->_generatorType = $type;
|
||||
}
|
||||
|
||||
public function completeIdentifierMapping()
|
||||
{
|
||||
if ($this->getIdGeneratorType() == self::GENERATOR_TYPE_AUTO) {
|
||||
$platform = $this->_em->getConnection()->getDatabasePlatform();
|
||||
if ($platform->prefersSequences()) {
|
||||
$this->_generatorType = self::GENERATOR_TYPE_SEQUENCE;
|
||||
} else if ($platform->prefersIdentityColumns()) {
|
||||
$this->_generatorType = self::GENERATOR_TYPE_IDENTITY;
|
||||
} else {
|
||||
$this->_generatorType = self::GENERATOR_TYPE_TABLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
/**
|
||||
* The metadata factory is used to create ClassMetadata objects that contain all the
|
||||
* metadata of a class.
|
||||
* metadata mapping informations of a class.
|
||||
*
|
||||
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
@ -45,7 +45,7 @@ class Doctrine_ClassMetadata_Factory
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* Creates a new factory instance that uses the given connection and metadata driver
|
||||
* Creates a new factory instance that uses the given EntityManager and metadata driver
|
||||
* implementations.
|
||||
*
|
||||
* @param $conn The connection to use.
|
||||
@ -129,6 +129,12 @@ class Doctrine_ClassMetadata_Factory
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds inherited fields to the subclass mapping.
|
||||
*
|
||||
* @param unknown_type $subClass
|
||||
* @param unknown_type $parentClass
|
||||
*/
|
||||
protected function _addInheritedFields($subClass, $parentClass)
|
||||
{
|
||||
foreach ($parentClass->getFieldMappings() as $fieldName => $mapping) {
|
||||
@ -138,6 +144,12 @@ class Doctrine_ClassMetadata_Factory
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds inherited associations to the subclass mapping.
|
||||
*
|
||||
* @param unknown_type $subClass
|
||||
* @param unknown_type $parentClass
|
||||
*/
|
||||
protected function _addInheritedRelations($subClass, $parentClass)
|
||||
{
|
||||
foreach ($parentClass->getRelationParser()->getRelationDefinitions() as $name => $definition) {
|
||||
@ -177,7 +189,7 @@ class Doctrine_ClassMetadata_Factory
|
||||
// save parents
|
||||
$class->setParentClasses($names);
|
||||
|
||||
// load further metadata
|
||||
// load user-specified mapping metadata through the driver
|
||||
$this->_driver->loadMetadataForClass($name, $class);
|
||||
|
||||
// set default table name, if necessary
|
||||
|
@ -23,24 +23,40 @@
|
||||
|
||||
/**
|
||||
* A persistent collection of entities.
|
||||
* A collection object is strongly typed in the sense that it can only contain
|
||||
* entities of a specific type or one it's subtypes.
|
||||
*
|
||||
* @package Doctrine
|
||||
* @subpackage Collection
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.phpdoctrine.org
|
||||
* @since 1.0
|
||||
* @version $Revision$
|
||||
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||
* A collection object is strongly typed in the sense that it can only contain
|
||||
* entities of a specific type or one of it's subtypes. A collection object is
|
||||
* basically a wrapper around an ordinary php array and just like a php array
|
||||
* it can have List or Map semantics.
|
||||
*
|
||||
* A collection of entities represents only the associations (links) to those entities.
|
||||
* That means, if the collection is part of a many-many mapping and you remove
|
||||
* entities from the collection, only the links in the xref table are removed.
|
||||
* Similarly, if you remove entities from a collection that is part of a one-many
|
||||
* mapping this will only result in the nulling out of the foreign keys
|
||||
* (or removal of the links in the xref table if the one-many is mapped through an
|
||||
* xref table). If you want entities in a one-many collection to be removed when
|
||||
* they're removed from the collection, use deleteOrphans => true on the one-many
|
||||
* mapping.
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @since 1.0
|
||||
* @version $Revision$
|
||||
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
*/
|
||||
class Doctrine_Collection extends Doctrine_Access implements Countable, IteratorAggregate, Serializable
|
||||
class Doctrine_Collection implements Countable, IteratorAggregate, Serializable, ArrayAccess
|
||||
{
|
||||
|
||||
/**
|
||||
* The base type of the collection.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $_entityBaseType;
|
||||
|
||||
/**
|
||||
* An array containing the records of this collection.
|
||||
* An array containing the entries of this collection.
|
||||
* This is the wrapped php array.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
@ -83,20 +99,17 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
|
||||
*/
|
||||
//protected static $null;
|
||||
|
||||
protected $_mapping;
|
||||
|
||||
/**
|
||||
* The EntityManager.
|
||||
*
|
||||
* @var EntityManager
|
||||
*/
|
||||
protected $_em;
|
||||
protected $_isDirty = false;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param Doctrine_Mapper|string $mapper The mapper used by the collection.
|
||||
* @param string $keyColumn The field name that will be used as the key
|
||||
* in the collection.
|
||||
*/
|
||||
public function __construct($entityBaseType, $keyField = null)
|
||||
{
|
||||
@ -115,7 +128,6 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
|
||||
* setData
|
||||
*
|
||||
* @param array $data
|
||||
* @return Doctrine_Collection
|
||||
*/
|
||||
public function setData(array $data)
|
||||
{
|
||||
@ -124,7 +136,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
|
||||
|
||||
/**
|
||||
* Serializes the collection.
|
||||
* This method is automatically called when this Doctrine_Collection is serialized.
|
||||
* This method is automatically called when the Collection is serialized.
|
||||
*
|
||||
* Part of the implementation of the Serializable interface.
|
||||
*
|
||||
@ -145,7 +157,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
|
||||
|
||||
/**
|
||||
* Reconstitutes the collection object from it's serialized form.
|
||||
* This method is automatically called everytime a Doctrine_Collection object is unserialized.
|
||||
* This method is automatically called everytime the Collection object is unserialized.
|
||||
*
|
||||
* Part of the implementation of the Serializable interface.
|
||||
*
|
||||
@ -172,8 +184,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* setKeyField
|
||||
* sets the key column for this collection
|
||||
* Sets the key column for this collection
|
||||
*
|
||||
* @param string $column
|
||||
* @return Doctrine_Collection
|
||||
@ -185,7 +196,6 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* getKeyField
|
||||
* returns the name of the key column
|
||||
*
|
||||
* @return string
|
||||
@ -196,7 +206,6 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* getData
|
||||
* returns all the records as an array
|
||||
*
|
||||
* @return array
|
||||
@ -207,7 +216,6 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* getFirst
|
||||
* returns the first record in the collection
|
||||
*
|
||||
* @return mixed
|
||||
@ -218,7 +226,6 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* getLast
|
||||
* returns the last record in the collection
|
||||
*
|
||||
* @return mixed
|
||||
@ -254,7 +261,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setReference(Doctrine_Entity $entity, Doctrine_Relation $relation)
|
||||
public function setReference(Doctrine_Entity $entity, $relation)
|
||||
{
|
||||
$this->_owner = $entity;
|
||||
//$this->relation = $relation;
|
||||
@ -296,21 +303,122 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
|
||||
{
|
||||
$removed = $this->_data[$key];
|
||||
unset($this->_data[$key]);
|
||||
//TODO: Register collection as dirty with the UoW if necessary
|
||||
return $removed;
|
||||
}
|
||||
|
||||
/**
|
||||
* __isset()
|
||||
*
|
||||
* @param string $name
|
||||
* @return boolean whether or not this object contains $name
|
||||
*/
|
||||
public function __isset($key)
|
||||
{
|
||||
return $this->containsKey($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* __unset()
|
||||
*
|
||||
* @param string $name
|
||||
* @since 1.0
|
||||
* @return void
|
||||
*/
|
||||
public function __unset($key)
|
||||
{
|
||||
return $this->remove($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an offsetExists.
|
||||
*
|
||||
* Part of the ArrayAccess implementation.
|
||||
*
|
||||
* @param mixed $offset
|
||||
* @return boolean whether or not this object contains $offset
|
||||
*/
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
return $this->containsKey($offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* offsetGet an alias of get()
|
||||
*
|
||||
* Part of the ArrayAccess implementation.
|
||||
*
|
||||
* @see get, __get
|
||||
* @param mixed $offset
|
||||
* @return mixed
|
||||
*/
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
return $this->get($offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Part of the ArrayAccess implementation.
|
||||
*
|
||||
* sets $offset to $value
|
||||
* @see set, __set
|
||||
* @param mixed $offset
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
*/
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
if ( ! isset($offset)) {
|
||||
return $this->add($value);
|
||||
}
|
||||
return $this->set($offset, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Part of the ArrayAccess implementation.
|
||||
*
|
||||
* unset a given offset
|
||||
* @see set, offsetSet, __set
|
||||
* @param mixed $offset
|
||||
*/
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
return $this->remove($offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the collection contains an entity.
|
||||
*
|
||||
* @param mixed $key the key of the element
|
||||
* @return boolean
|
||||
* @todo Rename to containsKey().
|
||||
*/
|
||||
public function contains($key)
|
||||
public function containsKey($key)
|
||||
{
|
||||
return isset($this->_data[$key]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enter description here...
|
||||
*
|
||||
* @param unknown_type $entity
|
||||
* @return unknown
|
||||
*/
|
||||
public function contains($entity)
|
||||
{
|
||||
return in_array($entity, $this->_data, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enter description here...
|
||||
*
|
||||
* @param unknown_type $otherColl
|
||||
* @todo Impl
|
||||
*/
|
||||
public function containsAll($otherColl)
|
||||
{
|
||||
//...
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@ -336,44 +444,9 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the primary keys of all records in the collection.
|
||||
* Gets all keys.
|
||||
* (Map method)
|
||||
*
|
||||
* @return array An array containing all primary keys.
|
||||
* @todo Rename.
|
||||
*/
|
||||
public function getPrimaryKeys()
|
||||
{
|
||||
$list = array();
|
||||
$idFieldNames = (array)$this->_mapper->getClassMetadata()->getIdentifier();
|
||||
|
||||
foreach ($this->_data as $record) {
|
||||
if (is_array($record)) {
|
||||
if (count($idFieldNames) > 1) {
|
||||
$id = array();
|
||||
foreach ($idFieldNames as $fieldName) {
|
||||
if (isset($record[$fieldName])) {
|
||||
$id[] = $record[$fieldName];
|
||||
}
|
||||
}
|
||||
$list[] = $id;
|
||||
} else {
|
||||
$idField = $idFieldNames[0];
|
||||
if (isset($record[$idField])) {
|
||||
$list[] = $record[$idField];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// @todo does not take composite keys into account
|
||||
$ids = $record->identifier();
|
||||
$list[] = count($ids) > 0 ? array_pop($ids) : null;
|
||||
}
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns all keys
|
||||
* @return array
|
||||
*/
|
||||
public function getKeys()
|
||||
@ -381,6 +454,17 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
|
||||
return array_keys($this->_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all values.
|
||||
* (Map method)
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getValues()
|
||||
{
|
||||
return array_values($this->_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of records in this collection.
|
||||
*
|
||||
@ -394,45 +478,39 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* set
|
||||
* When the collection is a Map this is like put(key,value)/add(key,value).
|
||||
* When the collection is a List this is like add(position,value).
|
||||
*
|
||||
* @param integer $key
|
||||
* @param Doctrine_Entity $record
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
* @internal Can't type-hint the second parameter to Doctrine_Entity because we need
|
||||
* to adhere to the Doctrine_Access::set() signature.
|
||||
*/
|
||||
public function set($key, $value)
|
||||
{
|
||||
if ( ! $value instanceof Doctrine_Entity) {
|
||||
throw new Doctrine_Collection_Exception('Value variable in set is not an instance of Doctrine_Entity');
|
||||
}
|
||||
|
||||
$this->_data[$key] = $value;
|
||||
//TODO: Register collection as dirty with the UoW if necessary
|
||||
$this->_changed();
|
||||
}
|
||||
|
||||
/**
|
||||
* adds a record to collection
|
||||
* Adds an entry to the collection.
|
||||
*
|
||||
* @param Doctrine_Entity $record record to be added
|
||||
* @param string $key optional key for the record
|
||||
* @param mixed $value
|
||||
* @param string $key
|
||||
* @return boolean
|
||||
*/
|
||||
public function add($value, $key = null)
|
||||
{
|
||||
/** @TODO Use raw getters/setters */
|
||||
if ( ! $value instanceof Doctrine_Entity) {
|
||||
throw new Doctrine_Record_Exception('Value variable in set is not an instance of Doctrine_Entity.');
|
||||
}
|
||||
|
||||
/*
|
||||
* for some weird reason in_array cannot be used here (php bug ?)
|
||||
*
|
||||
* if used it results in fatal error : [ nesting level too deep ]
|
||||
*/
|
||||
foreach ($this->_data as $val) {
|
||||
if ($val === $value) {
|
||||
return false;
|
||||
}
|
||||
// Neither Maps nor Lists allow duplicates, both are Sets
|
||||
if (in_array($value, $this->_data, true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isset($key)) {
|
||||
@ -440,20 +518,36 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
|
||||
return false;
|
||||
}
|
||||
$this->_data[$key] = $value;
|
||||
return true;
|
||||
} else {
|
||||
$this->_data[] = $value;
|
||||
}
|
||||
|
||||
$this->_data[] = $value;
|
||||
//TODO: Register collection as dirty with the UoW if necessary
|
||||
$this->_changed();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds all entities of the other collection to this collection.
|
||||
*
|
||||
* @param unknown_type $otherCollection
|
||||
* @todo Impl
|
||||
*/
|
||||
public function addAll($otherCollection)
|
||||
{
|
||||
//...
|
||||
//TODO: Register collection as dirty with the UoW if necessary
|
||||
//$this->_changed();
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNAL:
|
||||
* loadRelated
|
||||
*
|
||||
* @param mixed $name
|
||||
* @return boolean
|
||||
* @todo New implementation & maybe move elsewhere.
|
||||
*/
|
||||
public function loadRelated($name = null)
|
||||
{
|
||||
@ -506,8 +600,9 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
|
||||
* @param string $name
|
||||
* @param Doctrine_Collection $coll
|
||||
* @return void
|
||||
* @todo New implementation & maybe move elsewhere.
|
||||
*/
|
||||
public function populateRelated($name, Doctrine_Collection $coll)
|
||||
protected function populateRelated($name, Doctrine_Collection $coll)
|
||||
{
|
||||
$rel = $this->_mapper->getTable()->getRelation($name);
|
||||
$table = $rel->getTable();
|
||||
@ -562,38 +657,23 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* getNormalIterator
|
||||
* returns normal iterator - an iterator that will not expand this collection
|
||||
* INTERNAL: Takes a snapshot from this collection.
|
||||
*
|
||||
* @return Doctrine_Iterator_Normal
|
||||
*/
|
||||
public function getNormalIterator()
|
||||
{
|
||||
return new Doctrine_Collection_Iterator_Normal($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* takeSnapshot
|
||||
* takes a snapshot from this collection
|
||||
*
|
||||
* snapshots are used for diff processing, for example
|
||||
* Snapshots are used for diff processing, for example
|
||||
* when a fetched collection has three elements, then two of those
|
||||
* are being removed the diff would contain one element
|
||||
* are being removed the diff would contain one element.
|
||||
*
|
||||
* Doctrine_Collection::save() attaches the diff with the help of last
|
||||
* snapshot.
|
||||
* Collection::save() attaches the diff with the help of last snapshot.
|
||||
*
|
||||
* @return Doctrine_Collection
|
||||
* @return void
|
||||
*/
|
||||
public function takeSnapshot()
|
||||
{
|
||||
$this->_snapshot = $this->_data;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* getSnapshot
|
||||
* returns the data of the last snapshot
|
||||
* INTERNAL: Returns the data of the last snapshot.
|
||||
*
|
||||
* @return array returns the data in last snapshot
|
||||
*/
|
||||
@ -603,8 +683,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* processDiff
|
||||
* processes the difference of the last snapshot and the current data
|
||||
* Processes the difference of the last snapshot and the current data.
|
||||
*
|
||||
* an example:
|
||||
* Snapshot with the objects 1, 2 and 4
|
||||
@ -623,7 +702,6 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* toArray
|
||||
* Mimics the result of a $query->execute(array(), Doctrine::FETCH_ARRAY);
|
||||
*
|
||||
* @param boolean $deep
|
||||
@ -639,15 +717,18 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the collection is empty.
|
||||
*
|
||||
* @return boolean TRUE if the collection is empty, FALSE otherwise.
|
||||
*/
|
||||
public function isEmpty()
|
||||
{
|
||||
return $this->count() == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* fromArray
|
||||
*
|
||||
* Populate a Doctrine_Collection from an array of data
|
||||
* Populate a Doctrine_Collection from an array of data.
|
||||
*
|
||||
* @param string $array
|
||||
* @return void
|
||||
@ -661,8 +742,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* synchronizeFromArray
|
||||
* synchronizes a Doctrine_Collection with data from an array
|
||||
* Synchronizes a Doctrine_Collection with data from an array.
|
||||
*
|
||||
* it expects an array representation of a Doctrine_Collection similar to the return
|
||||
* value of the toArray() method. It will create Dectrine_Records that don't exist
|
||||
@ -689,8 +769,6 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* exportTo
|
||||
*
|
||||
* Export a Doctrine_Collection to one of the supported Doctrine_Parser formats
|
||||
*
|
||||
* @param string $type
|
||||
@ -698,18 +776,16 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
|
||||
* @return void
|
||||
* @todo Move elsewhere.
|
||||
*/
|
||||
public function exportTo($type, $deep = false)
|
||||
/*public function exportTo($type, $deep = false)
|
||||
{
|
||||
if ($type == 'array') {
|
||||
return $this->toArray($deep);
|
||||
} else {
|
||||
return Doctrine_Parser::dump($this->toArray($deep, true), $type);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
/**
|
||||
* importFrom
|
||||
*
|
||||
* Import data to a Doctrine_Collection from one of the supported Doctrine_Parser formats
|
||||
*
|
||||
* @param string $type
|
||||
@ -717,19 +793,19 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
|
||||
* @return void
|
||||
* @todo Move elsewhere.
|
||||
*/
|
||||
public function importFrom($type, $data)
|
||||
/*public function importFrom($type, $data)
|
||||
{
|
||||
if ($type == 'array') {
|
||||
return $this->fromArray($data);
|
||||
} else {
|
||||
return $this->fromArray(Doctrine_Parser::load($data, $type));
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
/**
|
||||
* getDeleteDiff
|
||||
* INTERNAL: getDeleteDiff
|
||||
*
|
||||
* @return void
|
||||
* @return array
|
||||
*/
|
||||
public function getDeleteDiff()
|
||||
{
|
||||
@ -737,9 +813,9 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* getInsertDiff
|
||||
* INTERNAL getInsertDiff
|
||||
*
|
||||
* @return void
|
||||
* @return array
|
||||
*/
|
||||
public function getInsertDiff()
|
||||
{
|
||||
@ -747,8 +823,9 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* _compareRecords
|
||||
* Compares two records. To be used on _snapshot diffs using array_udiff.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
protected function _compareRecords($a, $b)
|
||||
{
|
||||
@ -766,7 +843,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
|
||||
* @param Doctrine_Connection $conn optional connection parameter
|
||||
* @return Doctrine_Collection
|
||||
*/
|
||||
public function save()
|
||||
/*public function save()
|
||||
{
|
||||
$conn = $this->_mapper->getConnection();
|
||||
|
||||
@ -786,14 +863,15 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
}*/
|
||||
|
||||
/**
|
||||
* Deletes all records from the collection.
|
||||
* Shorthand for calling delete() for all entities in the collection.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function delete($clearColl = false)
|
||||
/*public function delete()
|
||||
{
|
||||
$conn = $this->_mapper->getConnection();
|
||||
|
||||
@ -811,10 +889,8 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
|
||||
throw $e;
|
||||
}
|
||||
|
||||
if ($clearColl) {
|
||||
$this->clear();
|
||||
}
|
||||
}
|
||||
$this->clear();
|
||||
}*/
|
||||
|
||||
|
||||
public function free($deep = false)
|
||||
@ -853,16 +929,54 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the relation object
|
||||
* @return object Doctrine_Relation
|
||||
* Gets the association mapping of the collection.
|
||||
*
|
||||
* @return Doctrine::ORM::Mapping::AssociationMapping
|
||||
*/
|
||||
public function getRelation()
|
||||
public function getMapping()
|
||||
{
|
||||
return $this->relation;
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Experiment. Waiting for 5.3 closures.
|
||||
* Example usage:
|
||||
*
|
||||
* $map = $coll->mapElements(function($key, $entity) {
|
||||
* return array($entity->id, $entity->name);
|
||||
* });
|
||||
*
|
||||
* or:
|
||||
*
|
||||
* $map = $coll->mapElements(function($key, $entity) {
|
||||
* return array($entity->name, strtoupper($entity->name));
|
||||
* });
|
||||
*
|
||||
*/
|
||||
public function mapElements($lambda) {
|
||||
$result = array();
|
||||
foreach ($this->_data as $key => $entity) {
|
||||
list($key, $value) = $lambda($key, $entity);
|
||||
$result[$key] = $value;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the collection.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
$this->_data = array();
|
||||
//TODO: Register collection as dirty with the UoW if necessary
|
||||
}
|
||||
|
||||
private function _changed()
|
||||
{
|
||||
/*if ( ! $this->_em->getUnitOfWork()->isCollectionScheduledForUpdate($this)) {
|
||||
$this->_em->getUnitOfWork()->scheduleCollectionUpdate($this);
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
48
lib/Doctrine/CollectionPersister/Abstract.php
Normal file
48
lib/Doctrine/CollectionPersister/Abstract.php
Normal file
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
class Doctrine_CollectionPersister_Abstract
|
||||
{
|
||||
|
||||
public function recreate(Doctrine_Collection $coll)
|
||||
{
|
||||
if ($coll->getRelation()->isInverseSide()) {
|
||||
return;
|
||||
}
|
||||
|
||||
//...
|
||||
}
|
||||
|
||||
public function delete(Doctrine_Collection $coll)
|
||||
{
|
||||
if ($coll->getRelation()->isInverseSide()) {
|
||||
return;
|
||||
}
|
||||
|
||||
//...
|
||||
if ($coll->getRelation() instanceof Doctrine_Association_OneToManyMapping) {
|
||||
//...
|
||||
} else if ($coll->getRelation() instanceof Doctrine_Association_ManyToManyMapping) {
|
||||
//...
|
||||
}
|
||||
}
|
||||
|
||||
/* collection update actions */
|
||||
|
||||
public function deleteRows()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function updateRows()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function insertRows()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
10
lib/Doctrine/CollectionPersister/OneToManyPersister.php
Normal file
10
lib/Doctrine/CollectionPersister/OneToManyPersister.php
Normal file
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
class Doctrine_CollectionPersister_OneToManyPersister extends Doctrine_CollectionPersister_Abstract
|
||||
{
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
?>
|
@ -78,6 +78,27 @@ class Doctrine_Connection_UnitOfWork
|
||||
*/
|
||||
protected $_deletedEntities = array();
|
||||
|
||||
/**
|
||||
* All collection deletions.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_collectionDeletions = array();
|
||||
|
||||
/**
|
||||
* All collection creations.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_collectionCreations = array();
|
||||
|
||||
/**
|
||||
* All collection updates.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_collectionUpdates = array();
|
||||
|
||||
/**
|
||||
* The EntityManager the UnitOfWork belongs to.
|
||||
*
|
||||
@ -115,16 +136,16 @@ class Doctrine_Connection_UnitOfWork
|
||||
public function commit()
|
||||
{
|
||||
// Detect changes in managed entities (mark dirty)
|
||||
//TODO: Consider using registerDirty() in Entity#set() instead if its
|
||||
// more performant.
|
||||
foreach ($this->_identityMap as $entities) {
|
||||
//TODO: Consider using registerDirty() in Entity#_set() instead if its
|
||||
// more performant (SEE THERE).
|
||||
/*foreach ($this->_identityMap as $entities) {
|
||||
foreach ($entities as $entity) {
|
||||
if ($entity->_state() == Doctrine_Entity::STATE_MANAGED
|
||||
&& $entity->isModified()) {
|
||||
$this->registerDirty($entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
if (empty($this->_newEntities) &&
|
||||
empty($this->_deletedEntities) &&
|
||||
@ -142,7 +163,11 @@ class Doctrine_Connection_UnitOfWork
|
||||
$this->_executeUpdates($class);
|
||||
}
|
||||
|
||||
// Deletions come last and need to be in reverse commit order
|
||||
//TODO: collection deletions
|
||||
//TODO: collection updates (deleteRows, updateRows, insertRows)
|
||||
//TODO: collection recreations
|
||||
|
||||
// Entity deletions come last and need to be in reverse commit order
|
||||
for ($count = count($commitOrder), $i = $count - 1; $i >= 0; $i--) {
|
||||
$this->_executeDeletions($commitOrder[$i]);
|
||||
}
|
||||
@ -232,7 +257,7 @@ class Doctrine_Connection_UnitOfWork
|
||||
foreach ($node->getClass()->getAssociationMappings() as $assocMapping) {
|
||||
//TODO: should skip target classes that are not in the changeset.
|
||||
if ($assocMapping->isOwningSide()) {
|
||||
$targetClass = $assocMapping->getTargetClass();
|
||||
$targetClass = $this->_em->getClassMetadata($assocMapping->getTargetEntityName());
|
||||
$targetClassName = $targetClass->getClassName();
|
||||
// if the target class does not yet have a node, create it
|
||||
if ( ! $this->_commitOrderCalculator->hasNodeWithKey($targetClassName)) {
|
||||
@ -711,6 +736,38 @@ class Doctrine_Connection_UnitOfWork
|
||||
$this->_commitOrderCalculator->clear();
|
||||
}
|
||||
|
||||
public function scheduleCollectionUpdate(Doctrine_Collection $coll)
|
||||
{
|
||||
$this->_collectionUpdates[] = $coll;
|
||||
}
|
||||
|
||||
public function isCollectionScheduledForUpdate(Doctrine_Collection $coll)
|
||||
{
|
||||
//...
|
||||
}
|
||||
|
||||
public function scheduleCollectionDeletion(Doctrine_Collection $coll)
|
||||
{
|
||||
//TODO: if $coll is already scheduled for recreation ... what to do?
|
||||
// Just remove $coll from the scheduled recreations?
|
||||
$this->_collectionDeletions[] = $coll;
|
||||
}
|
||||
|
||||
public function isCollectionScheduledForDeletion(Doctrine_Collection $coll)
|
||||
{
|
||||
//...
|
||||
}
|
||||
|
||||
public function scheduleCollectionRecreation(Doctrine_Collection $coll)
|
||||
{
|
||||
$this->_collectionRecreations[] = $coll;
|
||||
}
|
||||
|
||||
public function isCollectionScheduledForRecreation(Doctrine_Collection $coll)
|
||||
{
|
||||
//...
|
||||
}
|
||||
|
||||
|
||||
// Stuff from 0.11/1.0 that we will need later (need to modify it though)
|
||||
|
||||
|
@ -1,4 +1,23 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* <http://www.phpdoctrine.org>.
|
||||
*/
|
||||
|
||||
#namespace Doctrine::DBAL::Platforms;
|
||||
|
||||
@ -9,6 +28,7 @@
|
||||
*
|
||||
* @since 2.0
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
* @author Lukas Smith <smith@pooteeweet.org> (PEAR MDB2 library)
|
||||
*/
|
||||
abstract class Doctrine_DatabasePlatform
|
||||
{
|
||||
|
@ -1,4 +1,23 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* <http://www.phpdoctrine.org>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The MySqlPlatform provides the behavior, features and SQL dialect of the
|
||||
|
@ -1,5 +1,33 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* <http://www.phpdoctrine.org>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base class for all DatabasePlatforms. The DatabasePlatforms are the central
|
||||
* point of abstraction of platform-specific behaviors, features and SQL dialects.
|
||||
* They are a passive source of information.
|
||||
*
|
||||
* @since 2.0
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
* @author Lukas Smith <smith@pooteeweet.org> (PEAR MDB2 library)
|
||||
*/
|
||||
class Doctrine_DatabasePlatform_OraclePlatform extends Doctrine_DatabasePlatform
|
||||
{
|
||||
/**
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
/**
|
||||
* Base class for all Entities (objects with persistent state in a RDBMS that are
|
||||
* managed by Doctrine).
|
||||
* managed by Doctrine). Kind of a Layer Suptertype.
|
||||
*
|
||||
* NOTE: Methods that are intended for internal use only but must be public
|
||||
* are marked INTERNAL: and begin with an underscore "_" to indicate that they
|
||||
@ -40,7 +40,7 @@
|
||||
* @since 2.0
|
||||
* @version $Revision: 4342 $
|
||||
*/
|
||||
abstract class Doctrine_Entity extends Doctrine_Access implements Serializable
|
||||
abstract class Doctrine_Entity implements ArrayAccess, Serializable
|
||||
{
|
||||
/**
|
||||
* MANAGED
|
||||
@ -145,23 +145,37 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Serializable
|
||||
private $_state;
|
||||
|
||||
/**
|
||||
* The names of fields that have been modified but not yet persisted.
|
||||
* The changes that happened to fields of the entity.
|
||||
* Keys are field names, values oldValue => newValue tuples.
|
||||
*
|
||||
* @var array
|
||||
* @todo Rename to $_changeSet
|
||||
*/
|
||||
private $_modified = array();
|
||||
private $_dataChangeSet = array();
|
||||
|
||||
/**
|
||||
* The changes that happened to references of the entity to other entities.
|
||||
* Keys are field names, values oldReference => newReference tuples.
|
||||
*
|
||||
* With one-one associations, a reference change means the reference has been
|
||||
* swapped out / replaced by another one.
|
||||
*
|
||||
* With one-many, many-many associations, a reference change means the complete
|
||||
* collection has been sweapped out / replaced by another one.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $_referenceChangeSet = array();
|
||||
|
||||
/**
|
||||
* The references for all associations of the entity to other entities.
|
||||
* Keys are field names, values object references.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $_references = array();
|
||||
|
||||
/**
|
||||
* The EntityManager that is responsible for the persistence of the entity.
|
||||
* The EntityManager that is responsible for the persistent state of the entity.
|
||||
*
|
||||
* @var Doctrine::ORM::EntityManager
|
||||
*/
|
||||
@ -175,6 +189,14 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Serializable
|
||||
*/
|
||||
private $_oid;
|
||||
|
||||
/**
|
||||
* Flag that indicates whether the entity is dirty.
|
||||
* (which means it has local changes)
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
//private $_isDirty = false;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* Creates a new Entity instance.
|
||||
@ -238,7 +260,7 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Serializable
|
||||
*
|
||||
* Part of the implementation of the Serializable interface.
|
||||
*
|
||||
* @return array
|
||||
* @return string
|
||||
*/
|
||||
public function serialize()
|
||||
{
|
||||
@ -347,19 +369,7 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Serializable
|
||||
if ($state == null) {
|
||||
return $this->_state;
|
||||
}
|
||||
|
||||
/* TODO: Do we really need this check? This is only for internal use after all. */
|
||||
switch ($state) {
|
||||
case self::STATE_MANAGED:
|
||||
case self::STATE_DELETED:
|
||||
case self::STATE_DETACHED:
|
||||
case self::STATE_NEW:
|
||||
case self::STATE_LOCKED:
|
||||
$this->_state = $state;
|
||||
break;
|
||||
default:
|
||||
throw Doctrine_Entity_Exception::invalidState($state);
|
||||
}
|
||||
$this->_state = $state;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -374,39 +384,83 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Serializable
|
||||
|
||||
/**
|
||||
* Gets the value of a field (regular field or reference).
|
||||
* If the field is not yet loaded this method does NOT load it.
|
||||
*
|
||||
* @param $name name of the property
|
||||
* @throws Doctrine_Entity_Exception if trying to get an unknown field
|
||||
* @return mixed
|
||||
* @param $name Name of the field.
|
||||
* @return mixed Value of the field.
|
||||
* @throws Doctrine::ORM::Exceptions::EntityException If trying to get an unknown field.
|
||||
*/
|
||||
final protected function _get($fieldName)
|
||||
{
|
||||
$nullObj = Doctrine_Null::$INSTANCE;
|
||||
if (isset($this->_data[$fieldName])) {
|
||||
return $this->_internalGetField($fieldName);
|
||||
return $this->_data[$fieldName] !== $nullObj ?
|
||||
$this->_data[$fieldName] : null;
|
||||
} else if (isset($this->_references[$fieldName])) {
|
||||
return $this->_internalGetReference($fieldName);
|
||||
return $this->_references[$fieldName] !== $nullObj ?
|
||||
$this->_references[$fieldName] : null;
|
||||
} else {
|
||||
throw Doctrine_Entity_Exception::unknownField($fieldName);
|
||||
if ($this->_class->hasField($fieldName)) {
|
||||
return null;
|
||||
} else if ($this->_class->hasAssociation($fieldName)) {
|
||||
$rel = $this->_class->getAssociationMapping($fieldName);
|
||||
if ($rel->isLazilyFetched()) {
|
||||
$this->_references[$fieldName] = $rel->lazyLoadFor($this);
|
||||
return $this->_references[$fieldName] !== $nullObj ?
|
||||
$this->_references[$fieldName] : null;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
throw Doctrine_Entity_Exception::invalidField($fieldName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of a field (regular field or reference).
|
||||
* If the field is not yet loaded this method does NOT load it.
|
||||
*
|
||||
* @param $name name of the field
|
||||
* @throws Doctrine_Entity_Exception if trying to get an unknown field
|
||||
* @return mixed
|
||||
* @param $fieldName The name of the field.
|
||||
* @param $value The value of the field.
|
||||
* @return void
|
||||
* @throws Doctrine::ORM::Exceptions::EntityException
|
||||
*/
|
||||
final protected function _set($fieldName, $value)
|
||||
{
|
||||
if ($this->_class->hasField($fieldName)) {
|
||||
return $this->_internalSetField($fieldName, $value);
|
||||
} else if ($this->_class->hasRelation($fieldName)) {
|
||||
return $this->_internalSetReference($fieldName, $value);
|
||||
$old = isset($this->_data[$fieldName]) ? $this->_data[$fieldName] : null;
|
||||
// NOTE: Common case: $old != $value. Special case: null == 0 (TRUE), which
|
||||
// is addressed by the type comparison.
|
||||
if ($old != $value || gettype($old) != gettype($value)) {
|
||||
$this->_data[$fieldName] = $value;
|
||||
$this->_dataChangeSet[$fieldName] = array($old => $value);
|
||||
if ($this->isNew() && $this->_class->isIdentifier($fieldName)) {
|
||||
$this->_id[$fieldName] = $value;
|
||||
}
|
||||
$this->_registerDirty();
|
||||
}
|
||||
} else if ($this->_class->hasAssociation($fieldName)) {
|
||||
$old = isset($this->_references[$fieldName]) ? $this->_references[$fieldName] : null;
|
||||
if ($old !== $value) {
|
||||
$this->_internalSetReference($fieldName, $value);
|
||||
$this->_referenceChangeSet[$fieldName] = array($old => $value);
|
||||
$this->_registerDirty();
|
||||
if ($old instanceof Doctrine_Collection) {
|
||||
$this->_em->getUnitOfWork()->scheduleCollectionDeletion($old);
|
||||
}
|
||||
if ($value instanceof Doctrine_Collection) {
|
||||
$this->_em->getUnitOfWork()->scheduleCollectionRecreation($value);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw Doctrine_Entity_Exception::unknownField($fieldName);
|
||||
throw Doctrine_Entity_Exception::invalidField($fieldName);
|
||||
}
|
||||
}
|
||||
|
||||
private function _registerDirty()
|
||||
{
|
||||
if ($this->_state == self::STATE_MANAGED &&
|
||||
! $this->_em->getUnitOfWork()->isRegisteredDirty($this)) {
|
||||
$this->_em->getUnitOfWork()->registerDirty($this);
|
||||
}
|
||||
}
|
||||
|
||||
@ -420,7 +474,6 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Serializable
|
||||
*
|
||||
* @param string $fieldName
|
||||
* @return mixed
|
||||
* @todo Rename to _unsafeGetField()
|
||||
*/
|
||||
final public function _internalGetField($fieldName)
|
||||
{
|
||||
@ -447,6 +500,7 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Serializable
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNAL:
|
||||
* Gets a reference to another Entity.
|
||||
*
|
||||
* NOTE: Use of this method in userland code is strongly discouraged.
|
||||
@ -464,16 +518,15 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Serializable
|
||||
|
||||
/**
|
||||
* INTERNAL:
|
||||
* Sets a reference to another Entity.
|
||||
* Sets a reference to another entity or a collection of entities.
|
||||
*
|
||||
* NOTE: Use of this method in userland code is strongly discouraged.
|
||||
*
|
||||
* @param string $fieldName
|
||||
* @param mixed $value
|
||||
* @todo Refactor. What about composite keys?
|
||||
* @todo Rename to _unsafeSetReference()
|
||||
* @todo Refactor.
|
||||
*/
|
||||
final public function _internalSetReference($name, $value)
|
||||
final public function _internalSetReference_OLD($name, $value)
|
||||
{
|
||||
if ($value === Doctrine_Null::$INSTANCE) {
|
||||
$this->_references[$name] = $value;
|
||||
@ -486,7 +539,7 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Serializable
|
||||
if ($rel instanceof Doctrine_Relation_ForeignKey ||
|
||||
$rel instanceof Doctrine_Relation_LocalKey) {
|
||||
if ( ! $rel->isOneToOne()) {
|
||||
// one-to-many relation found
|
||||
// one-to-many relation
|
||||
if ( ! $value instanceof Doctrine_Collection) {
|
||||
throw Doctrine_Entity_Exception::invalidValueForOneToManyReference();
|
||||
}
|
||||
@ -524,42 +577,69 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Serializable
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic getter for all persistent fields.
|
||||
* INTERNAL:
|
||||
* Sets a reference to another entity or a collection of entities.
|
||||
*
|
||||
* NOTE: Use of this method in userland code is strongly discouraged.
|
||||
*
|
||||
* @param string $fieldName
|
||||
* @param mixed $value
|
||||
* @todo Refactor.
|
||||
*/
|
||||
final public function _internalSetReference($name, $value)
|
||||
{
|
||||
if ($value === Doctrine_Null::$INSTANCE) {
|
||||
$this->_references[$name] = $value;
|
||||
return;
|
||||
}
|
||||
|
||||
$rel = $this->_class->getAssociationMapping($name);
|
||||
|
||||
// one-to-many or one-to-one relation
|
||||
if ($rel->isOneToOne() || $rel->isOneToMany()) {
|
||||
if ( ! $rel->isOneToOne()) {
|
||||
// one-to-many relation
|
||||
if ( ! $value instanceof Doctrine_Collection) {
|
||||
throw Doctrine_Entity_Exception::invalidValueForOneToManyReference();
|
||||
}
|
||||
if (isset($this->_references[$name])) {
|
||||
$this->_references[$name]->setData($value->getData());
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
$relatedClass = $value->getClass();
|
||||
//$foreignFieldName = $rel->getForeignFieldName();
|
||||
//$localFieldName = $rel->getLocalFieldName();
|
||||
|
||||
// one-to-one relation found
|
||||
if ( ! ($value instanceof Doctrine_Entity)) {
|
||||
throw Doctrine_Entity_Exception::invalidValueForOneToOneReference();
|
||||
}
|
||||
}
|
||||
} else if ($rel instanceof Doctrine_Relation_Association) {
|
||||
if ( ! ($value instanceof Doctrine_Collection)) {
|
||||
throw Doctrine_Entity_Exception::invalidValueForManyToManyReference();
|
||||
}
|
||||
}
|
||||
|
||||
$this->_references[$name] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic getter for all (persistent) fields of the entity.
|
||||
*
|
||||
* Invoked by Doctrine::ORM::Access#__get().
|
||||
*
|
||||
* @param string $fieldName Name of the field.
|
||||
* @return mixed
|
||||
* @override
|
||||
*/
|
||||
final public function get($fieldName)
|
||||
{
|
||||
if ($getter = $this->_getCustomAccessor($fieldName)) {
|
||||
return $this->$getter();
|
||||
}
|
||||
|
||||
// Use built-in accessor functionality
|
||||
$nullObj = Doctrine_Null::$INSTANCE;
|
||||
if (isset($this->_data[$fieldName])) {
|
||||
return $this->_data[$fieldName] !== $nullObj ?
|
||||
$this->_data[$fieldName] : null;
|
||||
} else if (isset($this->_references[$fieldName])) {
|
||||
return $this->_references[$fieldName] !== $nullObj ?
|
||||
$this->_references[$fieldName] : null;
|
||||
} else {
|
||||
$class = $this->_class;
|
||||
if ($class->hasField($fieldName)) {
|
||||
return null;
|
||||
} else if ($class->hasRelation($fieldName)) {
|
||||
$rel = $class->getRelation($fieldName);
|
||||
if ($rel->isLazilyLoaded()) {
|
||||
$this->_references[$fieldName] = $rel->lazyLoadFor($this);
|
||||
return $this->_references[$fieldName] !== $nullObj ?
|
||||
$this->_references[$fieldName] : null;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
throw Doctrine_Entity_Exception::invalidField($fieldName);
|
||||
}
|
||||
}
|
||||
return $this->_get($fieldName);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -630,42 +710,20 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Serializable
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic setter for persistent fields.
|
||||
* Generic setter for (persistent) fields of the entity.
|
||||
*
|
||||
* Invoked by Doctrine::ORM::Access#__set().
|
||||
*
|
||||
* @param string $name The name of the field to set.
|
||||
* @param mixed $value The value of the field.
|
||||
* @override
|
||||
*/
|
||||
final public function set($fieldName, $value)
|
||||
{
|
||||
if ($setter = $this->_getCustomMutator($fieldName)) {
|
||||
return $this->$setter($value);
|
||||
}
|
||||
|
||||
if ($this->_class->hasField($fieldName)) {
|
||||
/*if ($value instanceof Doctrine_Entity) {
|
||||
$type = $class->getTypeOf($fieldName);
|
||||
// FIXME: composite key support
|
||||
$ids = $value->identifier();
|
||||
$id = count($ids) > 0 ? array_pop($ids) : null;
|
||||
if ($id !== null && $type !== 'object') {
|
||||
$value = $id;
|
||||
}
|
||||
}*/
|
||||
|
||||
$old = isset($this->_data[$fieldName]) ? $this->_data[$fieldName] : null;
|
||||
//FIXME: null == 0 => true
|
||||
if ($old != $value) {
|
||||
$this->_data[$fieldName] = $value;
|
||||
$this->_modified[$fieldName] = array($old => $value);
|
||||
if ($this->isNew() && $this->_class->isIdentifier($fieldName)) {
|
||||
$this->_id[$fieldName] = $value;
|
||||
}
|
||||
}
|
||||
} else if ($this->_class->hasRelation($fieldName)) {
|
||||
$this->_internalSetReference($fieldName, $value);
|
||||
} else {
|
||||
throw Doctrine_Entity_Exception::invalidField($fieldName);
|
||||
}
|
||||
$this->_set($fieldName, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -697,7 +755,7 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Serializable
|
||||
/**
|
||||
* Clears the value of a field.
|
||||
*
|
||||
* NOTE: Invoked by Doctrine::ORM::Access#__unset().
|
||||
* Invoked by Doctrine::ORM::Access#__unset().
|
||||
*
|
||||
* @param string $name
|
||||
* @return void
|
||||
@ -708,7 +766,7 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Serializable
|
||||
$this->_data[$fieldName] = array();
|
||||
} else if (isset($this->_references[$fieldName])) {
|
||||
if ($this->_references[$fieldName] instanceof Doctrine_Entity) {
|
||||
// todo: delete related record when saving $this
|
||||
// todo: delete related record when saving $this (ONLY WITH deleteOrphans!)
|
||||
$this->_references[$fieldName] = Doctrine_Null::$INSTANCE;
|
||||
} else if ($this->_references[$fieldName] instanceof Doctrine_Collection) {
|
||||
$this->_references[$fieldName]->setData(array());
|
||||
@ -722,72 +780,14 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Serializable
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
final public function _getChangeSet()
|
||||
final public function _getDataChangeSet()
|
||||
{
|
||||
//return $this->_changeSet;
|
||||
return $this->_dataChangeSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of modified fields and values with data preparation
|
||||
* adds column aggregation inheritance and converts Records into primary key values
|
||||
*
|
||||
* @param array $array
|
||||
* @return array
|
||||
* @todo What about a little bit more expressive name? getPreparedData?
|
||||
* @todo Does not look like the best place here ...
|
||||
* @todo Prop: Move to EntityPersister. There call _getChangeSet() and apply this logic.
|
||||
*/
|
||||
final public function getPrepared(array $array = array())
|
||||
final public function _getReferenceChangeSet()
|
||||
{
|
||||
$dataSet = array();
|
||||
|
||||
if (empty($array)) {
|
||||
$modifiedFields = $this->_modified;
|
||||
}
|
||||
|
||||
foreach ($modifiedFields as $field) {
|
||||
$type = $this->_class->getTypeOfField($field);
|
||||
|
||||
if ($this->_data[$field] === Doctrine_Null::$INSTANCE) {
|
||||
$dataSet[$field] = null;
|
||||
continue;
|
||||
}
|
||||
|
||||
switch ($type) {
|
||||
case 'array':
|
||||
case 'object':
|
||||
$dataSet[$field] = serialize($this->_data[$field]);
|
||||
break;
|
||||
case 'gzip':
|
||||
$dataSet[$field] = gzcompress($this->_data[$field],5);
|
||||
break;
|
||||
case 'boolean':
|
||||
$dataSet[$field] = $this->_em->getConnection()
|
||||
->convertBooleans($this->_data[$field]);
|
||||
break;
|
||||
case 'enum':
|
||||
$dataSet[$field] = $this->_class->enumIndex($field, $this->_data[$field]);
|
||||
break;
|
||||
default:
|
||||
$dataSet[$field] = $this->_data[$field];
|
||||
}
|
||||
}
|
||||
|
||||
// @todo cleanup
|
||||
// populates the discriminator field in Single & Class Table Inheritance
|
||||
if ($this->_class->getInheritanceType() == Doctrine::INHERITANCE_TYPE_JOINED ||
|
||||
$this->_class->getInheritanceType() == Doctrine::INHERITANCE_TYPE_SINGLE_TABLE) {
|
||||
$discCol = $this->_class->getInheritanceOption('discriminatorColumn');
|
||||
$discMap = $this->_class->getInheritanceOption('discriminatorMap');
|
||||
$old = $this->get($discCol, false);
|
||||
$discValue = array_search($this->_entityName, $discMap);
|
||||
if ((string) $old !== (string) $discValue || $old === null) {
|
||||
$dataSet[$discCol] = $discValue;
|
||||
$this->_data[$discCol] = $discValue;
|
||||
}
|
||||
}
|
||||
|
||||
return $dataSet;
|
||||
return $this->_referenceChangeSet;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -808,7 +808,7 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Serializable
|
||||
*/
|
||||
final public function isModified()
|
||||
{
|
||||
return count($this->_modified) > 0;
|
||||
return count($this->_fieldChangeSet) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -830,7 +830,7 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Serializable
|
||||
$this->_id[$name] = $id;
|
||||
$this->_data[$name] = $id;
|
||||
}
|
||||
$this->_modified = array();
|
||||
$this->_dataChangeSet = array();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -948,6 +948,8 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Serializable
|
||||
* from the instance pool.
|
||||
* Note: The entity is no longer useable after free() has been called. Any operations
|
||||
* done with the entity afterwards can lead to unpredictable results.
|
||||
*
|
||||
* @param boolean $deep Whether to cascade the free() call to (loaded) associated entities.
|
||||
*/
|
||||
public function free($deep = false)
|
||||
{
|
||||
@ -967,4 +969,107 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Serializable
|
||||
$this->_references = array();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an offsetExists.
|
||||
*
|
||||
* Part of the ArrayAccess implementation.
|
||||
*
|
||||
* @param mixed $offset
|
||||
* @return boolean whether or not this object contains $offset
|
||||
*/
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
return $this->contains($offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* offsetGet an alias of get()
|
||||
*
|
||||
* Part of the ArrayAccess implementation.
|
||||
*
|
||||
* @see get, __get
|
||||
* @param mixed $offset
|
||||
* @return mixed
|
||||
*/
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
return $this->get($offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Part of the ArrayAccess implementation.
|
||||
*
|
||||
* sets $offset to $value
|
||||
* @see set, __set
|
||||
* @param mixed $offset
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
*/
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
return $this->set($offset, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Part of the ArrayAccess implementation.
|
||||
*
|
||||
* unset a given offset
|
||||
* @see set, offsetSet, __set
|
||||
* @param mixed $offset
|
||||
*/
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
return $this->remove($offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* __set
|
||||
*
|
||||
* @see set, offsetSet
|
||||
* @param $name
|
||||
* @param $value
|
||||
* @since 1.0
|
||||
* @return void
|
||||
*/
|
||||
public function __set($name, $value)
|
||||
{
|
||||
$this->set($name, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* __get
|
||||
*
|
||||
* @see get, offsetGet
|
||||
* @param mixed $name
|
||||
* @return mixed
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
return $this->get($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* __isset()
|
||||
*
|
||||
* @param string $name
|
||||
* @since 1.0
|
||||
* @return boolean whether or not this object contains $name
|
||||
*/
|
||||
public function __isset($name)
|
||||
{
|
||||
return $this->contains($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* __unset()
|
||||
*
|
||||
* @param string $name
|
||||
* @since 1.0
|
||||
* @return void
|
||||
*/
|
||||
public function __unset($name)
|
||||
{
|
||||
return $this->remove($name);
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +29,6 @@
|
||||
#use Doctrine::ORM::Internal::UnitOfWork;
|
||||
#use Doctrine::ORM::Mapping::ClassMetadata;
|
||||
|
||||
|
||||
/**
|
||||
* The EntityManager is the central access point to ORM functionality.
|
||||
*
|
||||
@ -38,12 +37,28 @@
|
||||
* @since 2.0
|
||||
* @version $Revision$
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
* @todo package:orm
|
||||
*/
|
||||
class Doctrine_EntityManager
|
||||
{
|
||||
/**
|
||||
* IMMEDIATE: Flush occurs automatically after each operation that issues database
|
||||
* queries. No operations are queued.
|
||||
*/
|
||||
const FLUSHMODE_IMMEDIATE = 'immediated';
|
||||
/**
|
||||
* AUTO: Flush occurs automatically in the following situations:
|
||||
* - Before any query executions (to prevent getting stale data)
|
||||
* - On EntityManager#commit()
|
||||
*/
|
||||
const FLUSHMODE_AUTO = 'auto';
|
||||
/**
|
||||
* COMMIT: Flush occurs automatically only on EntityManager#commit().
|
||||
*/
|
||||
const FLUSHMODE_COMMIT = 'commit';
|
||||
/**
|
||||
* MANUAL: Flush occurs never automatically. The only way to flush is
|
||||
* through EntityManager#flush().
|
||||
*/
|
||||
const FLUSHMODE_MANUAL = 'manual';
|
||||
|
||||
/**
|
||||
@ -68,19 +83,6 @@ class Doctrine_EntityManager
|
||||
*/
|
||||
private $_conn;
|
||||
|
||||
/**
|
||||
* Flush modes enumeration.
|
||||
*/
|
||||
private static $_flushModes = array(
|
||||
// auto: Flush occurs automatically after each operation that issues database
|
||||
// queries. No operations are queued.
|
||||
self::FLUSHMODE_AUTO,
|
||||
// commit: Flush occurs automatically at transaction commit.
|
||||
self::FLUSHMODE_COMMIT,
|
||||
// manual: Flush occurs never automatically.
|
||||
self::FLUSHMODE_MANUAL
|
||||
);
|
||||
|
||||
/**
|
||||
* The metadata factory, used to retrieve the metadata of entity classes.
|
||||
*
|
||||
@ -160,7 +162,6 @@ class Doctrine_EntityManager
|
||||
* Gets the metadata for a class. Alias for getClassMetadata().
|
||||
*
|
||||
* @return Doctrine_Metadata
|
||||
* @todo package:orm
|
||||
*/
|
||||
public function getMetadata($className)
|
||||
{
|
||||
@ -324,12 +325,20 @@ class Doctrine_EntityManager
|
||||
*/
|
||||
public function setFlushMode($flushMode)
|
||||
{
|
||||
if ( ! in_array($flushMode, self::$_flushModes)) {
|
||||
if ( ! $this->_isFlushMode($flushMode)) {
|
||||
throw Doctrine_EntityManager_Exception::invalidFlushMode();
|
||||
}
|
||||
$this->_flushMode = $flushMode;
|
||||
}
|
||||
|
||||
private function _isFlushMode($value)
|
||||
{
|
||||
return $value == self::FLUSHMODE_AUTO ||
|
||||
$value == self::FLUSHMODE_COMMIT ||
|
||||
$value == self::FLUSHMODE_IMMEDIATE ||
|
||||
$value == self::FLUSHMODE_MANUAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the currently used flush mode.
|
||||
*
|
||||
@ -365,10 +374,9 @@ class Doctrine_EntityManager
|
||||
}
|
||||
|
||||
/**
|
||||
* getResultCacheDriver
|
||||
* Gets the result cache driver used by the EntityManager.
|
||||
*
|
||||
* @return Doctrine_Cache_Interface
|
||||
* @todo package:orm
|
||||
* @return Doctrine::ORM::Cache::CacheDriver The cache driver.
|
||||
*/
|
||||
public function getResultCacheDriver()
|
||||
{
|
||||
@ -383,7 +391,6 @@ class Doctrine_EntityManager
|
||||
* getQueryCacheDriver
|
||||
*
|
||||
* @return Doctrine_Cache_Interface
|
||||
* @todo package:orm
|
||||
*/
|
||||
public function getQueryCacheDriver()
|
||||
{
|
||||
@ -396,31 +403,45 @@ class Doctrine_EntityManager
|
||||
|
||||
/**
|
||||
* Saves the given entity, persisting it's state.
|
||||
*
|
||||
* @param Doctrine::ORM::Entity $entity
|
||||
* @return void
|
||||
*/
|
||||
public function save(Doctrine_Entity $entity)
|
||||
{
|
||||
$this->_unitOfWork->save($entity);
|
||||
if ($this->_flushMode == self::FLUSHMODE_AUTO) {
|
||||
if ($this->_flushMode == self::FLUSHMODE_IMMEDIATE) {
|
||||
$this->flush();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the given entity from the persistent store.
|
||||
*
|
||||
* @param Doctrine::ORM::Entity $entity
|
||||
* @return void
|
||||
*/
|
||||
public function delete(Doctrine_Entity $entity)
|
||||
{
|
||||
$this->_unitOfWork->delete($entity);
|
||||
if ($this->_flushMode == self::FLUSHMODE_IMMEDIATE) {
|
||||
$this->flush();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Refreshes the persistent state of the entity from the database.
|
||||
* Refreshes the persistent state of the entity from the database,
|
||||
* overriding any local changes that have not yet been persisted.
|
||||
*
|
||||
* @param Doctrine_Entity $entity
|
||||
* @param Doctrine::ORM::Entity $entity
|
||||
* @return void
|
||||
* @todo FIX Impl
|
||||
*/
|
||||
public function refresh(Doctrine_Entity $entity)
|
||||
{
|
||||
//...
|
||||
$this->_mergeData($entity, $entity->getRepository()->find(
|
||||
$entity->identifier(), Doctrine_Query::HYDRATE_ARRAY),
|
||||
true);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -463,7 +484,7 @@ class Doctrine_EntityManager
|
||||
*
|
||||
* @param string $className The name of the entity class.
|
||||
* @param array $data The data for the entity.
|
||||
* @return Doctrine_Entity
|
||||
* @return Doctrine::ORM::Entity
|
||||
*/
|
||||
public function createEntity($className, array $data)
|
||||
{
|
||||
@ -488,6 +509,7 @@ class Doctrine_EntityManager
|
||||
$idHash = $this->_unitOfWork->getIdentifierHash($id);
|
||||
if ($entity = $this->_unitOfWork->tryGetByIdHash($idHash,
|
||||
$classMetadata->getRootClassName())) {
|
||||
$this->_mergeData($entity, $data);
|
||||
return $entity;
|
||||
} else {
|
||||
$entity = new $className;
|
||||
@ -501,10 +523,35 @@ class Doctrine_EntityManager
|
||||
return $entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges the given data into the given entity, optionally overriding
|
||||
* local changes.
|
||||
*
|
||||
* @param Doctrine::ORM::Entity $entity
|
||||
* @param array $data
|
||||
* @param boolean $overrideLocalChanges
|
||||
* @return void
|
||||
*/
|
||||
private function _mergeData(Doctrine_Entity $entity, array $data, $overrideLocalChanges = false) {
|
||||
if ($overrideLocalChanges) {
|
||||
foreach ($data as $field => $value) {
|
||||
$entity->_internalSetField($field, $value);
|
||||
}
|
||||
} else {
|
||||
foreach ($data as $field => $value) {
|
||||
if ( ! $entity->contains($field) || $entity->_internalGetField($field) === null) {
|
||||
$entity->_internalSetField($field, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the instance is managed by the EntityManager.
|
||||
*
|
||||
* @return boolean
|
||||
* @param Doctrine::ORM::Entity $entity
|
||||
* @return boolean TRUE if this EntityManager currently manages the given entity
|
||||
* (and has it in the identity map), FALSE otherwise.
|
||||
*/
|
||||
public function contains(Doctrine_Entity $entity)
|
||||
{
|
||||
@ -513,8 +560,11 @@ class Doctrine_EntityManager
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNAL:
|
||||
* For internal hydration purposes only.
|
||||
* INTERNAL: For internal hydration purposes only.
|
||||
*
|
||||
* Gets the temporarily stored entity data.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function _getTmpEntityData()
|
||||
{
|
||||
@ -528,6 +578,8 @@ class Doctrine_EntityManager
|
||||
* class to instantiate. If no discriminator column is found, the given
|
||||
* classname will be returned.
|
||||
*
|
||||
* @param array $data
|
||||
* @param string $className
|
||||
* @return string The name of the class to instantiate.
|
||||
*/
|
||||
private function _inferCorrectClassName(array $data, $className)
|
||||
@ -562,6 +614,7 @@ class Doctrine_EntityManager
|
||||
* Sets the EventManager used by the EntityManager.
|
||||
*
|
||||
* @param Doctrine::Common::EventManager $eventManager
|
||||
* @return void
|
||||
*/
|
||||
public function setEventManager(Doctrine_EventManager $eventManager)
|
||||
{
|
||||
@ -572,6 +625,7 @@ class Doctrine_EntityManager
|
||||
* Sets the Configuration used by the EntityManager.
|
||||
*
|
||||
* @param Doctrine::Common::Configuration $config
|
||||
* @return void
|
||||
*/
|
||||
public function setConfiguration(Doctrine_Configuration $config)
|
||||
{
|
||||
|
@ -55,7 +55,7 @@ abstract class Doctrine_EntityPersister_Abstract
|
||||
/**
|
||||
* The Doctrine_Connection object that the database connection of this mapper.
|
||||
*
|
||||
* @var Doctrine_Connection $conn
|
||||
* @var Doctrine::DBAL::Connection $conn
|
||||
*/
|
||||
protected $_conn;
|
||||
|
||||
@ -85,17 +85,58 @@ abstract class Doctrine_EntityPersister_Abstract
|
||||
|
||||
public function insert(Doctrine_Entity $entity)
|
||||
{
|
||||
//...
|
||||
$insertData = array();
|
||||
$dataChangeSet = $entity->_getDataChangeSet();
|
||||
$referenceChangeSet = $entity->_getReferenceChangeSet();
|
||||
|
||||
foreach ($referenceChangeSet as $field => $change) {
|
||||
list($old, $new) = each($change);
|
||||
$assocMapping = $entity->getClass()->getAssociationMapping($field);
|
||||
if ($assocMapping->isOneToOne()) {
|
||||
if ($assocMapping->isInverseSide()) {
|
||||
//echo "INVERSE!";
|
||||
continue; // ignore inverse side
|
||||
}
|
||||
foreach ($assocMapping->getSourceToTargetKeyColumns() as $localColumn => $foreignColumn) {
|
||||
//echo "$localColumn -- $foreignColumn<br/>";
|
||||
//$insertData[$localColumn] = 1; //FIX
|
||||
}
|
||||
// ... set the foreign key column to the id of the related entity ($new)
|
||||
}
|
||||
//...
|
||||
}
|
||||
|
||||
foreach ($dataChangeSet as $field => $change) {
|
||||
$insertData[$entity->getClass()->getColumnName($field)] = current($change);
|
||||
}
|
||||
|
||||
//TODO: perform insert
|
||||
$this->_conn->insert($entity->getClass()->getTableName(), $insertData);
|
||||
}
|
||||
|
||||
public function update(Doctrine_Entity $entity)
|
||||
{
|
||||
//...
|
||||
$dataChangeSet = $entity->_getDataChangeSet();
|
||||
$referenceChangeSet = $entity->_getReferenceChangeSet();
|
||||
|
||||
foreach ($referenceChangeSet as $field => $change) {
|
||||
$assocMapping = $entity->getClass()->getAssociationMapping($field);
|
||||
if ($assocMapping instanceof Doctrine_Association_OneToOneMapping) {
|
||||
if ($assocMapping->isInverseSide()) {
|
||||
continue; // ignore inverse side
|
||||
}
|
||||
// ... null out the foreign key
|
||||
|
||||
}
|
||||
//...
|
||||
}
|
||||
|
||||
//TODO: perform update
|
||||
}
|
||||
|
||||
public function delete(Doctrine_Entity $entity)
|
||||
{
|
||||
|
||||
//TODO: perform delete
|
||||
}
|
||||
|
||||
/**
|
||||
@ -182,6 +223,64 @@ abstract class Doctrine_EntityPersister_Abstract
|
||||
return $converted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of modified fields and values with data preparation
|
||||
* adds column aggregation inheritance and converts Records into primary key values
|
||||
*
|
||||
* @param array $array
|
||||
* @return array
|
||||
* @todo Move to EntityPersister. There call _getChangeSet() and apply this logic.
|
||||
*/
|
||||
public function prepareData(array $data = array())
|
||||
{
|
||||
$dataSet = array();
|
||||
|
||||
$modifiedFields = $fields;
|
||||
|
||||
foreach ($data as $field => $value) {
|
||||
$type = $this->_classMetadata->getTypeOfField($field);
|
||||
|
||||
if ($value === Doctrine_Null::$INSTANCE) {
|
||||
$dataSet[$field] = null;
|
||||
continue;
|
||||
}
|
||||
|
||||
switch ($type) {
|
||||
case 'array':
|
||||
case 'object':
|
||||
$dataSet[$field] = serialize($value);
|
||||
break;
|
||||
case 'gzip':
|
||||
$dataSet[$field] = gzcompress($value, 5);
|
||||
break;
|
||||
case 'boolean':
|
||||
$dataSet[$field] = $this->_em->getConnection()
|
||||
->convertBooleans($value);
|
||||
break;
|
||||
case 'enum':
|
||||
$dataSet[$field] = $this->_class->enumIndex($field, $value);
|
||||
break;
|
||||
default:
|
||||
$dataSet[$field] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
// @todo cleanup
|
||||
// populates the discriminator field in Single & Class Table Inheritance
|
||||
if ($this->_classMetadata->getInheritanceType() == Doctrine_ClassMetadata::INHERITANCE_TYPE_JOINED ||
|
||||
$this->_class->getInheritanceType() == Doctrine_ClassMetadata::INHERITANCE_TYPE_SINGLE_TABLE) {
|
||||
$discCol = $this->_classMetadata->getInheritanceOption('discriminatorColumn');
|
||||
$discMap = $this->_classMetadata->getInheritanceOption('discriminatorMap');
|
||||
$old = $this->get($discCol, false);
|
||||
$discValue = array_search($this->_entityName, $discMap);
|
||||
if ((string) $old !== (string) $discValue || $old === null) {
|
||||
$dataSet[$discCol] = $discValue;
|
||||
//$this->_data[$discCol] = $discValue;
|
||||
}
|
||||
}
|
||||
|
||||
return $dataSet;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -226,75 +325,6 @@ abstract class Doctrine_EntityPersister_Abstract
|
||||
return $this->_em;
|
||||
}
|
||||
|
||||
/**
|
||||
* prepareValue
|
||||
* this method performs special data preparation depending on
|
||||
* the type of the given column
|
||||
*
|
||||
* 1. It unserializes array and object typed columns
|
||||
* 2. Uncompresses gzip typed columns
|
||||
* 3. Gets the appropriate enum values for enum typed columns
|
||||
* 4. Initializes special null object pointer for null values (for fast column existence checking purposes)
|
||||
*
|
||||
* example:
|
||||
* <code type='php'>
|
||||
* $field = 'name';
|
||||
* $value = null;
|
||||
* $table->prepareValue($field, $value); // Doctrine_Null
|
||||
* </code>
|
||||
*
|
||||
* @throws Doctrine_Table_Exception if unserialization of array/object typed column fails or
|
||||
* @throws Doctrine_Table_Exception if uncompression of gzip typed column fails *
|
||||
* @param string $field the name of the field
|
||||
* @param string $value field value
|
||||
* @param string $typeHint A hint on the type of the value. If provided, the type lookup
|
||||
* for the field can be skipped. Used i.e. during hydration to
|
||||
* improve performance on large and/or complex results.
|
||||
* @return mixed prepared value
|
||||
* @todo To EntityManager. Make private and use in createEntity().
|
||||
* .. Or, maybe better: Move to hydrator for performance reasons.
|
||||
*/
|
||||
/*public function prepareValue($fieldName, $value, $typeHint = null)
|
||||
{
|
||||
if ($value === $this->_nullObject) {
|
||||
return $this->_nullObject;
|
||||
} else if ($value === null) {
|
||||
return null;
|
||||
} else {
|
||||
$type = is_null($typeHint) ? $this->_classMetadata->getTypeOf($fieldName) : $typeHint;
|
||||
switch ($type) {
|
||||
case 'integer':
|
||||
case 'string';
|
||||
// don't do any casting here PHP INT_MAX is smaller than what the databases support
|
||||
break;
|
||||
case 'enum':
|
||||
return $this->_classMetadata->enumValue($fieldName, $value);
|
||||
break;
|
||||
case 'boolean':
|
||||
return (boolean) $value;
|
||||
break;
|
||||
case 'array':
|
||||
case 'object':
|
||||
if (is_string($value)) {
|
||||
$value = unserialize($value);
|
||||
if ($value === false) {
|
||||
throw new Doctrine_Mapper_Exception('Unserialization of ' . $fieldName . ' failed.');
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
break;
|
||||
case 'gzip':
|
||||
$value = gzuncompress($value);
|
||||
if ($value === false) {
|
||||
throw new Doctrine_Mapper_Exception('Uncompressing of ' . $fieldName . ' failed.');
|
||||
}
|
||||
return $value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $value;
|
||||
}*/
|
||||
|
||||
/**
|
||||
* getComponentName
|
||||
*
|
||||
|
@ -24,8 +24,6 @@
|
||||
* as is the case in Single Table Inheritance & Concrete Table Inheritance.
|
||||
*
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
* @package Doctrine
|
||||
* @subpackage Abstract
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @version $Revision$
|
||||
* @link www.phpdoctrine.org
|
||||
@ -72,7 +70,6 @@ class Doctrine_EntityPersister_Standard extends Doctrine_EntityPersister_Abstrac
|
||||
return false;
|
||||
}
|
||||
|
||||
//$class = $record->getClassMetadata();
|
||||
$class = $this->_classMetadata;
|
||||
$identifier = $class->getIdentifier();
|
||||
$fields = $this->_convertFieldToColumnNames($fields, $class);
|
||||
|
@ -19,11 +19,11 @@
|
||||
* <http://www.phpdoctrine.org>.
|
||||
*/
|
||||
|
||||
#namespace Doctrine::Common;
|
||||
#namespace Doctrine::Common::Event;
|
||||
|
||||
/**
|
||||
* The EventManager is the central point of Doctrine's event listener system.
|
||||
* Listeners are registered on the manager and events are dispatch through the
|
||||
* Listeners are registered on the manager and events are dispatched through the
|
||||
* manager.
|
||||
*
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
@ -100,6 +100,17 @@ class Doctrine_EventManager
|
||||
$this->_listeners[$event] = $listener;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an EventSubscriber. The subscriber is asked for all the events he is
|
||||
* interested in and added as a listener for these events.
|
||||
*
|
||||
* @param Doctrine::Common::Event::EventSubscriber $subscriber The subscriber.
|
||||
*/
|
||||
public function addEventSubscriber(Doctrine_EventSubscriber $subscriber)
|
||||
{
|
||||
$this->addEventListener($subscriber->getSubscribedEvents(), $subscriber);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -49,7 +49,7 @@ class Doctrine_Exception extends Exception
|
||||
return $this->_innerException;
|
||||
}
|
||||
|
||||
public static function notImplemented($method, $class)
|
||||
public static function notYetImplemented($method, $class)
|
||||
{
|
||||
return new self("The method '$method' is not implemented in the class '$class'.");
|
||||
}
|
||||
|
@ -70,8 +70,8 @@ class Doctrine_Hydrator_RecordDriver
|
||||
public function initRelatedCollection(Doctrine_Entity $entity, $name)
|
||||
{
|
||||
if ( ! isset($this->_initializedRelations[$entity->getOid()][$name])) {
|
||||
$relation = $entity->getClass()->getRelation($name);
|
||||
$relatedClass = $relation->getTable();
|
||||
$relation = $entity->getClass()->getAssociationMapping($name);
|
||||
$relatedClass = $this->_em->getClassMetadata($relation->getTargetEntityName());
|
||||
$coll = $this->getElementCollection($relatedClass->getClassName());
|
||||
$coll->setReference($entity, $relation);
|
||||
$entity->_internalSetReference($name, $coll);
|
||||
|
@ -49,8 +49,6 @@
|
||||
* That's why the performance of the _gatherRowData() methods which are responsible
|
||||
* for the "numRowsInResult * numColumnsInResult" part is crucial to fast hydration.
|
||||
*
|
||||
* @package Doctrine
|
||||
* @subpackage Hydrator
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.phpdoctrine.org
|
||||
* @since 1.0
|
||||
@ -212,7 +210,7 @@ class Doctrine_HydratorNew extends Doctrine_Hydrator_Abstract
|
||||
$entityName = $map['metadata']->getClassName();
|
||||
$parent = $map['parent'];
|
||||
$relation = $map['relation'];
|
||||
$relationAlias = $relation->getAlias();
|
||||
$relationAlias = $relation->getSourceFieldName();//$relation->getAlias();
|
||||
$path = $parent . '.' . $dqlAlias;
|
||||
|
||||
// pick the right element that will get the associated element attached
|
||||
|
@ -9,8 +9,8 @@ class Doctrine_MappingException extends Doctrine_Exception
|
||||
{
|
||||
public static function identifierRequired($entityName)
|
||||
{
|
||||
return new self("No identifier specified for Entity '$entityName'."
|
||||
. " Every Entity must have an identifier.");
|
||||
return new self("No identifier/primary key specified for Entity '$entityName'."
|
||||
. " Every Entity must have an identifier/primary key.");
|
||||
}
|
||||
|
||||
public static function invalidInheritanceType($type)
|
||||
@ -28,6 +28,25 @@ class Doctrine_MappingException extends Doctrine_Exception
|
||||
return new self("Id generators can't be used with a composite id.");
|
||||
}
|
||||
|
||||
public static function missingFieldName()
|
||||
{
|
||||
return new self("The association mapping misses the 'fieldName' attribute.");
|
||||
}
|
||||
|
||||
public static function missingTargetEntity($fieldName)
|
||||
{
|
||||
return new self("The association mapping '$fieldName' misses the 'targetEntity' attribute.");
|
||||
}
|
||||
|
||||
public static function missingSourceEntity($fieldName)
|
||||
{
|
||||
return new self("The association mapping '$fieldName' misses the 'sourceEntity' attribute.");
|
||||
}
|
||||
|
||||
public static function mappingNotFound($fieldName)
|
||||
{
|
||||
return new self("No mapping found for field '$fieldName'.");
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -20,10 +20,6 @@
|
||||
* <http://www.phpdoctrine.org>.
|
||||
*/
|
||||
|
||||
Doctrine::autoload('Doctrine_Query_AbstractResult');
|
||||
Doctrine::autoload('Doctrine_Query_ParserResult');
|
||||
Doctrine::autoload('Doctrine_Query_QueryResult');
|
||||
|
||||
/**
|
||||
* Doctrine_Query_CacheHandler
|
||||
*
|
||||
@ -136,8 +132,8 @@ abstract class Doctrine_Query_CacheHandler
|
||||
$queryComponents[$alias]['table'] = $queryComponents[$alias]['mapper']->getTable();
|
||||
} else {
|
||||
$queryComponents[$alias]['parent'] = $e[0];
|
||||
$queryComponents[$alias]['relation'] = $queryComponents[$e[0]]['table']->getRelation($e[1]);
|
||||
$queryComponents[$alias]['mapper'] = $query->getConnection()->getMapper($queryComponents[$alias]['relation']->getForeignComponentName());
|
||||
$queryComponents[$alias]['relation'] = $queryComponents[$e[0]]['table']->getAssociation($e[1]);
|
||||
$queryComponents[$alias]['mapper'] = $query->getConnection()->getMapper($queryComponents[$alias]['relation']->getTargetEntityName());
|
||||
$queryComponents[$alias]['table'] = $queryComponents[$alias]['mapper']->getTable();
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,7 @@ class Doctrine_Query_Production_Join extends Doctrine_Query_Production
|
||||
$this->_parser->match(Doctrine_Query_Token::T_LEFT);
|
||||
|
||||
$this->_joinType = 'LEFT';
|
||||
} elseif ($this->_isNextToken(Doctrine_Query_Token::T_INNER)) {
|
||||
} else if ($this->_isNextToken(Doctrine_Query_Token::T_INNER)) {
|
||||
$this->_parser->match(Doctrine_Query_Token::T_INNER);
|
||||
}
|
||||
|
||||
@ -64,7 +64,7 @@ class Doctrine_Query_Production_Join extends Doctrine_Query_Production
|
||||
$this->_whereType = 'ON';
|
||||
|
||||
$this->_conditionalExpression = $this->AST('ConditionalExpression', $paramHolder);
|
||||
} elseif ($this->_isNextToken(Doctrine_Query_Token::T_WITH)) {
|
||||
} else if ($this->_isNextToken(Doctrine_Query_Token::T_WITH)) {
|
||||
$this->_parser->match(Doctrine_Query_Token::T_WITH);
|
||||
|
||||
$this->_conditionalExpression = $this->AST('ConditionalExpression', $paramHolder);
|
||||
|
@ -93,7 +93,7 @@ class Doctrine_Query_Production_PathExpression extends Doctrine_Query_Production
|
||||
$relationName = $this->_identifiers[$i];
|
||||
$path .= '.' . $relationName;
|
||||
|
||||
if ( ! $classMetadata->hasRelation($relationName)) {
|
||||
if ( ! $classMetadata->hasAssociation($relationName)) {
|
||||
$className = $classMetadata->getClassName();
|
||||
|
||||
$this->_parser->semanticalError(
|
||||
|
@ -73,7 +73,7 @@ class Doctrine_Query_Production_PathExpressionEndingWithAsterisk extends Doctrin
|
||||
$relationName = $this->_identifiers[$i];
|
||||
$path .= '.' . $relationName;
|
||||
|
||||
if ( ! $classMetadata->hasRelation($relationName)) {
|
||||
if ( ! $classMetadata->hasAssociation($relationName)) {
|
||||
$className = $classMetadata->getClassName();
|
||||
|
||||
$this->_parser->semanticalError(
|
||||
|
@ -191,7 +191,7 @@ class Doctrine_Query_Production_RangeVariableDeclaration extends Doctrine_Query_
|
||||
}
|
||||
} else {
|
||||
// We don't have the query component yet
|
||||
if ( ! $classMetadata->hasRelation($relationName)) {
|
||||
if ( ! $classMetadata->hasAssociation($relationName)) {
|
||||
$className = $classMetadata->getClassName();
|
||||
|
||||
$this->_parser->semanticalError("Relation '{$relationName}' does not exist in component '{$className}'");
|
||||
@ -199,13 +199,13 @@ class Doctrine_Query_Production_RangeVariableDeclaration extends Doctrine_Query_
|
||||
return;
|
||||
}
|
||||
|
||||
// Retrieving ClassMetadata and Mapper
|
||||
// Retrieving ClassMetadata
|
||||
try {
|
||||
$relation = $classMetadata->getRelation($relationName);
|
||||
$classMetadata = $relation->getClassMetadata();
|
||||
$relation = $classMetadata->getAssociationMapping($relationName);
|
||||
$targetClassMetadata = $this->_em->getClassMetadata($relation->getTargetEntityName());
|
||||
|
||||
$queryComponent = array(
|
||||
'metadata' => $classMetadata,
|
||||
'metadata' => $targetClassMetadata,
|
||||
'parent' => $parent,
|
||||
'relation' => $relation,
|
||||
'map' => null,
|
||||
@ -226,7 +226,7 @@ class Doctrine_Query_Production_RangeVariableDeclaration extends Doctrine_Query_
|
||||
$this->_identificationVariable = $path;
|
||||
}
|
||||
|
||||
$tableAlias = $parserResult->generateTableAlias($classMetadata->getClassName());
|
||||
$tableAlias = $parserResult->generateTableAlias($targetClassMetadata->getClassName());
|
||||
|
||||
//echo "Table alias: " . $tableAlias . "\n";
|
||||
|
||||
|
@ -154,7 +154,7 @@ abstract class Doctrine_Relation implements ArrayAccess
|
||||
}
|
||||
}
|
||||
$this->definition = $def;
|
||||
$this->_foreignMapper = $this->getTable()->getConnection()->getEntityPersister($def['class']);
|
||||
$this->_foreignMapper = $this->getTable()->getEntityManager()->getEntityPersister($def['class']);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -410,7 +410,7 @@ class Doctrine_Relation_Parser
|
||||
*/
|
||||
public function completeDefinition($def)
|
||||
{
|
||||
$conn = $this->_table->getConnection();
|
||||
$conn = $this->_table->getEntityManager();
|
||||
$def['table'] = $this->getImpl($def, 'class');
|
||||
$def['localTable'] = $this->_table;
|
||||
|
||||
|
@ -187,7 +187,7 @@ class Doctrine_Schema_MsSqlSchemaManager extends Doctrine_Schema_SchemaManager
|
||||
if ($query) {
|
||||
$query .= ', ';
|
||||
}
|
||||
$query .= 'ADD ' . $this->conn->getDeclaration($fieldName, $field);
|
||||
$query .= 'ADD ' . $this->getDeclaration($fieldName, $field);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,8 @@ require_once 'Orm/Entity/AllTests.php';
|
||||
// Tests
|
||||
require_once 'Orm/UnitOfWorkTest.php';
|
||||
require_once 'Orm/EntityManagerFactoryTest.php';
|
||||
require_once 'Orm/EntityManagerTest.php';
|
||||
require_once 'Orm/EntityPersisterTest.php';
|
||||
|
||||
class Orm_AllTests
|
||||
{
|
||||
@ -29,7 +31,8 @@ class Orm_AllTests
|
||||
|
||||
$suite->addTestSuite('Orm_UnitOfWorkTest');
|
||||
$suite->addTestSuite('Orm_EntityManagerFactoryTest');
|
||||
//$suite->addTestSuite('Orm_ConfigurableTestCase');
|
||||
$suite->addTestSuite('Orm_EntityManagerTest');
|
||||
$suite->addTestSuite('Orm_EntityPersisterTest');
|
||||
|
||||
$suite->addTest(Orm_Component_AllTests::suite());
|
||||
$suite->addTest(Orm_Query_AllTests::suite());
|
||||
|
@ -9,7 +9,7 @@ class Orm_Associations_OneToOneMappingTest extends Doctrine_OrmTestCase
|
||||
'fieldName' => 'address',
|
||||
'targetEntity' => 'Address',
|
||||
'joinColumns' => array('address_id' => 'id'),
|
||||
'sourceEntity' => 'Person' // This is normally filled by ClassMetadata
|
||||
'sourceEntity' => 'Person', // This is normally filled by ClassMetadata
|
||||
);
|
||||
|
||||
$oneToOneMapping = new Doctrine_Association_OneToOne($owningSideMapping);
|
||||
@ -23,11 +23,16 @@ class Orm_Associations_OneToOneMappingTest extends Doctrine_OrmTestCase
|
||||
|
||||
|
||||
$inverseSideMapping = array(
|
||||
'fieldName' => 'person',
|
||||
'sourceEntity' => 'Address',
|
||||
'targetEntity' => 'Person',
|
||||
'mappedBy' => 'address'
|
||||
);
|
||||
|
||||
$oneToOneMapping = new Doctrine_Association_OneToOne($inverseSideMapping);
|
||||
$this->assertEquals('address', $oneToOneMapping->getMappedByFieldName());
|
||||
$this->assertEquals('Address', $oneToOneMapping->getSourceEntityName());
|
||||
$this->assertEquals('Person', $oneToOneMapping->getTargetEntityName());
|
||||
$this->assertTrue($oneToOneMapping->isInverseSide());
|
||||
|
||||
}
|
||||
|
@ -26,7 +26,7 @@
|
||||
* @author Bjarte Stien Karlsen <doctrine@bjartek.org>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.phpdoctrine.org
|
||||
* @since 1.0
|
||||
* @since 2.0
|
||||
* @version $Revision: 3754 $
|
||||
*/
|
||||
require_once 'lib/DoctrineTestInit.php';
|
||||
@ -95,23 +95,6 @@ class Orm_Component_AccessTest extends Doctrine_OrmTestCase
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldSetArrayOfValusInRecord()
|
||||
{
|
||||
$this->user->setArray(array(
|
||||
'username' => 'meus',
|
||||
'id' => 22));
|
||||
|
||||
$this->assertEquals('meus', $this->user->username);
|
||||
$this->assertEquals('meus', $this->user['username']);
|
||||
|
||||
$this->assertEquals(22, $this->user->id);
|
||||
$this->assertEquals(22, $this->user['id']);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @expectedException Doctrine_Entity_Exception
|
||||
@ -130,17 +113,6 @@ class Orm_Component_AccessTest extends Doctrine_OrmTestCase
|
||||
$this->user['rat'] = 'meus';
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @expectedException Doctrine_Entity_Exception
|
||||
*/
|
||||
public function shouldNotBeAbleToSetNonExistantFieldAsPartInSetArray()
|
||||
{
|
||||
$this->user->setArray(array(
|
||||
'rat' => 'meus',
|
||||
'id' => 22));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @test
|
||||
@ -176,18 +148,6 @@ class Orm_Component_AccessTest extends Doctrine_OrmTestCase
|
||||
$this->assertFalse(isset($col->test));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @test
|
||||
* @expectedException Doctrine_Exception
|
||||
*/
|
||||
public function shouldNotBeAbleToSetNullFieldInRecord()
|
||||
{
|
||||
$this->user->offsetSet(null, 'test');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @expectedException Doctrine_Exception
|
||||
|
20
tests/Orm/EntityManagerTest.php
Normal file
20
tests/Orm/EntityManagerTest.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
require_once 'lib/DoctrineTestInit.php';
|
||||
|
||||
#namespace Doctrine::Tests::ORM;
|
||||
|
||||
/**
|
||||
* EntityManager tests.
|
||||
*/
|
||||
class Orm_EntityManagerTest extends Doctrine_OrmTestCase
|
||||
{
|
||||
public function testSettingInvalidFlushModeThrowsException()
|
||||
{
|
||||
$prev = $this->_em->getFlushMode();
|
||||
try {
|
||||
$this->_em->setFlushMode('foobar');
|
||||
$this->fail("Setting invalid flushmode did not trigger exception.");
|
||||
} catch (Doctrine_EntityManager_Exception $expected) {}
|
||||
$this->_em->setFlushMode($prev);
|
||||
}
|
||||
}
|
42
tests/Orm/EntityPersisterTest.php
Normal file
42
tests/Orm/EntityPersisterTest.php
Normal file
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
require_once 'lib/DoctrineTestInit.php';
|
||||
require_once 'lib/mocks/Doctrine_EntityManagerMock.php';
|
||||
require_once 'lib/mocks/Doctrine_ConnectionMock.php';
|
||||
|
||||
/**
|
||||
* EntityPersister tests.
|
||||
*/
|
||||
class Orm_EntityPersisterTest extends Doctrine_OrmTestCase
|
||||
{
|
||||
private $_persister; // SUT
|
||||
private $_connMock;
|
||||
private $_emMock;
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->_connMock = new Doctrine_ConnectionMock(array());
|
||||
$this->_emMock = new Doctrine_EntityManagerMock($this->_connMock);
|
||||
$this->_connMock->setDatabasePlatform(new Doctrine_DatabasePlatformMock());
|
||||
|
||||
$this->_persister = new Doctrine_EntityPersister_Standard(
|
||||
$this->_emMock, $this->_emMock->getClassMetadata("ForumUser"));
|
||||
}
|
||||
|
||||
public function testTest() {
|
||||
$user = new ForumUser();
|
||||
$user->username = "romanb";
|
||||
|
||||
$user->avatar = new ForumAvatar();
|
||||
|
||||
$this->_persister->insert($user);
|
||||
|
||||
$inserts = $this->_connMock->getInserts();
|
||||
//var_dump($inserts);
|
||||
$this->assertTrue(isset($inserts['forum_user']));
|
||||
$this->assertEquals(1, count($inserts['forum_user']));
|
||||
$this->assertEquals(1, count($inserts['forum_user'][0]));
|
||||
$this->assertTrue(isset($inserts['forum_user'][0]['username']));
|
||||
$this->assertEquals('romanb', $inserts['forum_user'][0]['username']);
|
||||
}
|
||||
|
||||
}
|
@ -123,7 +123,7 @@ class Orm_Hydration_BasicHydrationTest extends Doctrine_OrmTestCase
|
||||
'p' => array(
|
||||
'metadata' => $this->_em->getClassMetadata('CmsPhonenumber'),
|
||||
'parent' => 'u',
|
||||
'relation' => $this->_em->getClassMetadata('CmsUser')->getRelation('phonenumbers'),
|
||||
'relation' => $this->_em->getClassMetadata('CmsUser')->getAssociationMapping('phonenumbers'),
|
||||
'map' => null
|
||||
)
|
||||
);
|
||||
@ -226,7 +226,7 @@ class Orm_Hydration_BasicHydrationTest extends Doctrine_OrmTestCase
|
||||
'p' => array(
|
||||
'metadata' => $this->_em->getClassMetadata('CmsPhonenumber'),
|
||||
'parent' => 'u',
|
||||
'relation' => $this->_em->getClassMetadata('CmsUser')->getRelation('phonenumbers'),
|
||||
'relation' => $this->_em->getClassMetadata('CmsUser')->getAssociationMapping('phonenumbers'),
|
||||
'map' => null,
|
||||
'agg' => array('0' => 'numPhones')
|
||||
)
|
||||
@ -311,7 +311,7 @@ class Orm_Hydration_BasicHydrationTest extends Doctrine_OrmTestCase
|
||||
'p' => array(
|
||||
'metadata' => $this->_em->getClassMetadata('CmsPhonenumber'),
|
||||
'parent' => 'u',
|
||||
'relation' => $this->_em->getClassMetadata('CmsUser')->getRelation('phonenumbers'),
|
||||
'relation' => $this->_em->getClassMetadata('CmsUser')->getAssociationMapping('phonenumbers'),
|
||||
'map' => 'phonenumber'
|
||||
)
|
||||
);
|
||||
@ -415,13 +415,13 @@ class Orm_Hydration_BasicHydrationTest extends Doctrine_OrmTestCase
|
||||
'p' => array(
|
||||
'metadata' => $this->_em->getClassMetadata('CmsPhonenumber'),
|
||||
'parent' => 'u',
|
||||
'relation' => $this->_em->getClassMetadata('CmsUser')->getRelation('phonenumbers'),
|
||||
'relation' => $this->_em->getClassMetadata('CmsUser')->getAssociationMapping('phonenumbers'),
|
||||
'map' => null
|
||||
),
|
||||
'a' => array(
|
||||
'metadata' => $this->_em->getClassMetadata('CmsArticle'),
|
||||
'parent' => 'u',
|
||||
'relation' => $this->_em->getClassMetadata('CmsUser')->getRelation('articles'),
|
||||
'relation' => $this->_em->getClassMetadata('CmsUser')->getAssociationMapping('articles'),
|
||||
'map' => null
|
||||
),
|
||||
);
|
||||
@ -571,19 +571,19 @@ class Orm_Hydration_BasicHydrationTest extends Doctrine_OrmTestCase
|
||||
'p' => array(
|
||||
'metadata' => $this->_em->getClassMetadata('CmsPhonenumber'),
|
||||
'parent' => 'u',
|
||||
'relation' => $this->_em->getClassMetadata('CmsUser')->getRelation('phonenumbers'),
|
||||
'relation' => $this->_em->getClassMetadata('CmsUser')->getAssociationMapping('phonenumbers'),
|
||||
'map' => null
|
||||
),
|
||||
'a' => array(
|
||||
'metadata' => $this->_em->getClassMetadata('CmsArticle'),
|
||||
'parent' => 'u',
|
||||
'relation' => $this->_em->getClassMetadata('CmsUser')->getRelation('articles'),
|
||||
'relation' => $this->_em->getClassMetadata('CmsUser')->getAssociationMapping('articles'),
|
||||
'map' => null
|
||||
),
|
||||
'c' => array(
|
||||
'metadata' => $this->_em->getClassMetadata('CmsComment'),
|
||||
'parent' => 'a',
|
||||
'relation' => $this->_em->getClassMetadata('CmsArticle')->getRelation('comments'),
|
||||
'relation' => $this->_em->getClassMetadata('CmsArticle')->getAssociationMapping('comments'),
|
||||
'map' => null
|
||||
),
|
||||
);
|
||||
@ -779,7 +779,7 @@ class Orm_Hydration_BasicHydrationTest extends Doctrine_OrmTestCase
|
||||
'b' => array(
|
||||
'metadata' => $this->_em->getClassMetadata('ForumBoard'),
|
||||
'parent' => 'c',
|
||||
'relation' => $this->_em->getClassMetadata('ForumCategory')->getRelation('boards'),
|
||||
'relation' => $this->_em->getClassMetadata('ForumCategory')->getAssociationMapping('boards'),
|
||||
'map' => null
|
||||
),
|
||||
);
|
||||
|
@ -84,7 +84,7 @@ class Orm_Query_IdentifierRecognitionTest extends Doctrine_OrmTestCase
|
||||
$decl = $parserResult->getQueryComponent('p');
|
||||
|
||||
$this->assertTrue($decl['metadata'] instanceof Doctrine_ClassMetadata);
|
||||
$this->assertTrue($decl['relation'] instanceof Doctrine_Relation);
|
||||
$this->assertTrue($decl['relation'] instanceof Doctrine_Association);
|
||||
$this->assertEquals('u', $decl['parent']);
|
||||
$this->assertEquals(null, $decl['scalar']);
|
||||
$this->assertEquals(null, $decl['map']);
|
||||
@ -108,7 +108,7 @@ class Orm_Query_IdentifierRecognitionTest extends Doctrine_OrmTestCase
|
||||
$decl = $parserResult->getQueryComponent('a');
|
||||
|
||||
$this->assertTrue($decl['metadata'] instanceof Doctrine_ClassMetadata);
|
||||
$this->assertTrue($decl['relation'] instanceof Doctrine_Relation);
|
||||
$this->assertTrue($decl['relation'] instanceof Doctrine_Association);
|
||||
$this->assertEquals('u', $decl['parent']);
|
||||
$this->assertEquals(null, $decl['scalar']);
|
||||
$this->assertEquals(null, $decl['map']);
|
||||
@ -116,7 +116,7 @@ class Orm_Query_IdentifierRecognitionTest extends Doctrine_OrmTestCase
|
||||
$decl = $parserResult->getQueryComponent('pn');
|
||||
|
||||
$this->assertTrue($decl['metadata'] instanceof Doctrine_ClassMetadata);
|
||||
$this->assertTrue($decl['relation'] instanceof Doctrine_Relation);
|
||||
$this->assertTrue($decl['relation'] instanceof Doctrine_Association);
|
||||
$this->assertEquals('u', $decl['parent']);
|
||||
$this->assertEquals(null, $decl['scalar']);
|
||||
$this->assertEquals('phonenumber', $decl['map']);
|
||||
|
@ -8,6 +8,7 @@ class Doctrine_ConnectionMock extends Doctrine_Connection
|
||||
protected $_driverName = 'Mock';
|
||||
private $_sequenceModuleMock;
|
||||
private $_platformMock;
|
||||
private $_inserts = array();
|
||||
|
||||
public function __construct(array $params)
|
||||
{
|
||||
@ -30,6 +31,14 @@ class Doctrine_ConnectionMock extends Doctrine_Connection
|
||||
return $this->_platformMock;
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public function insert($tableName, array $data)
|
||||
{
|
||||
$this->_inserts[$tableName][] = $data;
|
||||
}
|
||||
|
||||
/* Mock API */
|
||||
|
||||
public function setDatabasePlatform($platform)
|
||||
@ -41,6 +50,16 @@ class Doctrine_ConnectionMock extends Doctrine_Connection
|
||||
{
|
||||
$this->_sequenceModuleMock = $seqManager;
|
||||
}
|
||||
|
||||
public function getInserts()
|
||||
{
|
||||
return $this->_inserts;
|
||||
}
|
||||
|
||||
public function reset()
|
||||
{
|
||||
$this->_inserts = array();
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -34,7 +34,18 @@ class CmsArticle extends Doctrine_Entity
|
||||
'type' => 'integer',
|
||||
'length' => 4
|
||||
));
|
||||
$mapping->hasMany('CmsComment as comments', array(
|
||||
'local' => 'id', 'foreign' => 'article_id'));
|
||||
|
||||
/*$mapping->hasMany('CmsComment as comments', array(
|
||||
'local' => 'id', 'foreign' => 'article_id'));*/
|
||||
|
||||
$mapping->mapOneToMany(array(
|
||||
'fieldName' => 'comments',
|
||||
'targetEntity' => 'CmsComment',
|
||||
));
|
||||
|
||||
/*$mapping->mapManyToOne(array(
|
||||
'fieldName' => 'author',
|
||||
'joinColumns' => array('user_id' => 'id')
|
||||
));*/
|
||||
}
|
||||
}
|
||||
|
@ -36,9 +36,21 @@ class CmsUser extends Doctrine_Entity
|
||||
'length' => 255
|
||||
));
|
||||
|
||||
$mapping->hasMany('CmsPhonenumber as phonenumbers', array(
|
||||
/*$mapping->hasMany('CmsPhonenumber as phonenumbers', array(
|
||||
'local' => 'id', 'foreign' => 'user_id'));
|
||||
$mapping->hasMany('CmsArticle as articles', array(
|
||||
'local' => 'id', 'foreign' => 'user_id'));
|
||||
'local' => 'id', 'foreign' => 'user_id'));*/
|
||||
|
||||
$mapping->mapOneToMany(array(
|
||||
'fieldName' => 'phonenumbers',
|
||||
'targetEntity' => 'CmsPhonenumber',
|
||||
|
||||
));
|
||||
|
||||
$mapping->mapOneToMany(array(
|
||||
'fieldName' => 'articles',
|
||||
'targetEntity' => 'CmsArticle',
|
||||
));
|
||||
|
||||
}
|
||||
}
|
||||
|
20
tests/models/forum/ForumAvatar.php
Normal file
20
tests/models/forum/ForumAvatar.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
class ForumAvatar extends Doctrine_Entity
|
||||
{
|
||||
|
||||
public static function initMetadata($mapping)
|
||||
{
|
||||
$mapping->mapField(array(
|
||||
'fieldName' => 'id',
|
||||
'type' => 'integer',
|
||||
'length' => 4,
|
||||
'id' => true,
|
||||
'idGenerator' => 'auto'
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
?>
|
@ -25,14 +25,13 @@ class ForumBoard extends Doctrine_Entity
|
||||
'type' => 'integer'
|
||||
));
|
||||
|
||||
$mapping->hasOne('ForumCategory as category',
|
||||
array('local' => 'category_id', 'foreign' => 'id'));
|
||||
/*
|
||||
$metadata->mapOneToOne(array(
|
||||
'fieldName' => 'category', // optional, defaults to targetEntity
|
||||
/*$mapping->hasOne('ForumCategory as category',
|
||||
array('local' => 'category_id', 'foreign' => 'id'));*/
|
||||
|
||||
$mapping->mapOneToOne(array(
|
||||
'fieldName' => 'category',
|
||||
'targetEntity' => 'ForumCategory',
|
||||
'joinColumns' => array('category_id' => 'id')
|
||||
));
|
||||
*/
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,12 @@ class ForumCategory extends Doctrine_Entity
|
||||
'length' => 255
|
||||
));
|
||||
|
||||
$mapping->hasMany('ForumBoard as boards', array(
|
||||
'local' => 'id' , 'foreign' => 'category_id'));
|
||||
/*$mapping->hasMany('ForumBoard as boards', array(
|
||||
'local' => 'id' , 'foreign' => 'category_id'));*/
|
||||
|
||||
$mapping->mapOneToMany(array(
|
||||
'fieldName' => 'boards',
|
||||
'targetEntity' => 'ForumBoard'
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -6,9 +6,9 @@
|
||||
|
||||
class ForumUser extends Doctrine_Entity
|
||||
{
|
||||
#protected $dtype;
|
||||
#protected $id;
|
||||
#protected $username;
|
||||
#protected $avatar;
|
||||
|
||||
public static function initMetadata($mapping)
|
||||
{
|
||||
@ -42,6 +42,12 @@ class ForumUser extends Doctrine_Entity
|
||||
'length' => 50
|
||||
));
|
||||
|
||||
$mapping->mapOneToOne(array(
|
||||
'fieldName' => 'avatar',
|
||||
'targetEntity' => 'ForumAvatar',
|
||||
'joinColumns' => array('avatar_id' => 'id'),
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user