/** * Persists an object storage. Objects of a 1:n or m:n relation are queued and processed with the parent object. A 1:1 relation * gets persisted immediately. Objects which were removed from the property were detached from the parent object. They will not be * deleted by default. You have to annotate the property with "@cascade remove" if you want them to be deleted as well. * * @param \TYPO3\CMS\Extbase\Persistence\ObjectStorage $objectStorage The object storage to be persisted. * @param \TYPO3\CMS\Extbase\DomainObject\DomainObjectInterface $parentObject The parent object. One of the properties holds the object storage. * @param string $propertyName The name of the property holding the object storage. * @param array &$row The row array of the parent object to be persisted. It's passed by reference and gets filled with either a comma separated list of uids (csv) or the number of contained objects. * @return void */ protected function persistObjectStorage(\TYPO3\CMS\Extbase\Persistence\ObjectStorage $objectStorage, \TYPO3\CMS\Extbase\DomainObject\DomainObjectInterface $parentObject, $propertyName, array &$row) { $className = get_class($parentObject); $columnMap = $this->dataMapper->getDataMap($className)->getColumnMap($propertyName); $propertyMetaData = $this->reflectionService->getClassSchema($className)->getProperty($propertyName); foreach ($this->getRemovedChildObjects($parentObject, $propertyName) as $removedObject) { $this->detachObjectFromParentObject($removedObject, $parentObject, $propertyName); if ($columnMap->getTypeOfRelation() === \TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap::RELATION_HAS_MANY && $propertyMetaData['cascade'] === 'remove') { $this->removeEntity($removedObject); } } $currentUids = array(); $sortingPosition = 1; $updateSortingOfFollowing = false; foreach ($objectStorage as $object) { /** @var DomainObjectInterface $object */ if (empty($currentUids)) { $sortingPosition = 1; } else { $sortingPosition++; } $cleanProperty = $parentObject->_getCleanProperty($propertyName); if ($object->_isNew()) { $this->insertObject($object); $this->attachObjectToParentObject($object, $parentObject, $propertyName, $sortingPosition); // if a new object is inserted, all objects after this need to have their sorting updated $updateSortingOfFollowing = true; } elseif ($cleanProperty === null || $cleanProperty->getPosition($object) === null) { // if parent object is new then it doesn't have cleanProperty yet; before attaching object it's clean position is null $this->attachObjectToParentObject($object, $parentObject, $propertyName, $sortingPosition); // if a relation is dirty (speaking the same object is removed and added again at a different position), all objects after this needs to be updated the sorting $updateSortingOfFollowing = true; } elseif ($objectStorage->isRelationDirty($object) || $cleanProperty->getPosition($object) !== $objectStorage->getPosition($object)) { $this->updateRelationOfObjectToParentObject($object, $parentObject, $propertyName, $sortingPosition); $updateSortingOfFollowing = true; } elseif ($updateSortingOfFollowing) { if ($sortingPosition > $objectStorage->getPosition($object)) { $this->updateRelationOfObjectToParentObject($object, $parentObject, $propertyName, $sortingPosition); } else { $sortingPosition = $objectStorage->getPosition($object); } } $currentUids[] = $object->getUid(); } if ($columnMap->getParentKeyFieldName() === null) { $row[$columnMap->getColumnName()] = implode(',', $currentUids); } else { $row[$columnMap->getColumnName()] = $this->dataMapper->countRelated($parentObject, $propertyName); } }
/** * Counts the elements in the storage array * * @throws Exception * @return integer The number of elements in the ObjectStorage */ public function count() { $columnMap = $this->dataMapper->getDataMap(get_class($this->parentObject))->getColumnMap($this->propertyName); $numberOfElements = NULL; if (!$this->isInitialized && $columnMap->getTypeOfRelation() === Mapper\ColumnMap::RELATION_HAS_MANY) { $numberOfElements = $this->dataMapper->countRelated($this->parentObject, $this->propertyName, $this->fieldValue); } else { $this->initialize(); $numberOfElements = count($this->storage); } if (is_null($numberOfElements)) { throw new \TYPO3\CMS\Extbase\Persistence\Generic\Exception('The number of elements could not be determined.', 1252514486); } return $numberOfElements; }