/** * Extracts objects recursively from $row. * * Checks if $row contains new objects defined in $relations. If this is * the case, the objects will be extracted and added as related objects of * their class for the object of $parentClass with $parentId. If * sub-sequent relations exist for an extracted object, this method is * called recursively. If $restricted is set to true, named related object * sets will be created instead of normal related object sets. * * @param array(string=>string) $row * @param array(ezcPersistentRelationFindDefinition) $relations * @param ezcPersistentObject $parent * @param bool $restricted */ protected function extractObjectsRecursive(array $row, array $relations, $parent, $restricted = false) { foreach ($relations as $tableAlias => $relation) { $id = $row[$this->getColumnAlias($relation->definition->idProperty->propertyName, $tableAlias)]; if ($id === null) { // Related object not present, check if a relation is recorded // in general, to potentially add an empty set if ($restricted) { $relatedObjects = $this->idMap->getRelatedObjectSet($parent, $tableAlias); if ($relatedObjects === null) { $this->idMap->setRelatedObjectSet($parent, array(), $tableAlias); } } else { $relatedObjects = $this->idMap->getRelatedObjects($parent, $relation->relatedClass, $relation->relationName); if ($relatedObjects === null) { $this->idMap->setRelatedObjects($parent, array(), $relation->relatedClass, $relation->relationName); } } // Skip further processing since this related object did not exist continue; } // Check if object was already extracted $object = $this->idMap->getIdentity($relation->relatedClass, $id); if ($this->options->refetch || $object === null) { $object = $this->createObject($row, $tableAlias, $relation); $this->idMap->setIdentity($object); } // Check if relations from $parentClass to $relation->relatedClass // were already recorded if ($restricted) { $relatedObjects = $this->idMap->getRelatedObjectSet($parent, $tableAlias); } else { $relatedObjects = $this->idMap->getRelatedObjects($parent, $relation->relatedClass, $relation->relationName); } if ($relatedObjects === null) { // No relation set recorded, create $relatedObjects = array(); } // Check if relation itself is already recorded and only set the // identities if not if ($this->options->refetch || !isset($relatedObjects[$id])) { $relatedObjects[$id] = $object; // This performs the full setting process on every new object, // which is somewhat expensive but not really possible in a // different way, since adding new related objects invalidates // named related sets. if ($restricted) { $this->idMap->setRelatedObjectSet($parent, $relatedObjects, $tableAlias); } else { $this->idMap->setRelatedObjects($parent, $relatedObjects, $relation->relatedClass, $relation->relationName); } } // Recurse $this->extractObjectsRecursive($row, $relation->furtherRelations, $object, $restricted); } }
/** * Returns the next persistent object in the result set. * * The next object is set to the current object of the iterator. * Returns null and sets the current object to null if there * are no more results in the result set. * * @return object */ public function next() { $object = parent::next(); if ($object !== null) { $identity = null; if (!$this->options->refetch) { $class = get_class($object); $state = $object->getState(); $identity = $this->idMap->getIdentity($class, $state[$this->def->idProperty->propertyName]); } if ($identity !== null) { $this->object = $identity; } else { $this->idMap->setIdentity($object); } } return $this->object; }