parentObject = $parentObject; $this->propertyName = $propertyName; $this->fieldValue = $fieldValue; if ($dataMapper === null) { $dataMapper = GeneralUtility::makeInstance(DataMapper::class); } $this->dataMapper = $dataMapper; } /** * Populate this proxy by asking the $population closure. * * @return object|null The instance (hopefully) returned */ public function _loadRealInstance() { // this check safeguards against a proxy being activated multiple times // usually that does not happen, but if the proxy is held from outside // its parent ... the result would be weird. if ($this->parentObject->_getProperty($this->propertyName) instanceof LazyLoadingProxy && $this->dataMapper) { $objects = $this->dataMapper->fetchRelated($this->parentObject, $this->propertyName, $this->fieldValue, false); $propertyValue = $this->dataMapper->mapResultToPropertyValue($this->parentObject, $this->propertyName, $objects); $this->parentObject->_setProperty($this->propertyName, $propertyValue); $this->parentObject->_memorizeCleanState($this->propertyName); return $propertyValue; } return $this->parentObject->_getProperty($this->propertyName); } /** * @return string */ public function _getTypeAndUidString() { $type = $this->dataMapper->getType(get_class($this->parentObject), $this->propertyName); return $type . ':' . $this->fieldValue; } public function getUid(): int { return (int)$this->fieldValue; } /** * Magic method call implementation. * * @param string $methodName The name of the property to get * @param array $arguments The arguments given to the call * @return mixed */ public function __call($methodName, $arguments) { $realInstance = $this->_loadRealInstance(); if (!is_object($realInstance)) { return null; } /** @var callable $callable */ $callable = [$realInstance, $methodName]; return $callable(...$arguments); } /** * Magic get call implementation. * * @param string $propertyName The name of the property to get * @return mixed */ public function __get($propertyName) { $realInstance = $this->_loadRealInstance(); if ($realInstance instanceof DomainObjectInterface) { return $realInstance->_getProperty($propertyName); } return $realInstance?->{$propertyName}; } /** * Magic set call implementation. * * @param string $propertyName The name of the property to set * @param mixed $value The value for the property to set */ public function __set($propertyName, $value) { $realInstance = $this->_loadRealInstance(); $realInstance->{$propertyName} = $value; } /** * Magic isset call implementation. * * @param string $propertyName The name of the property to check * @return bool */ public function __isset($propertyName) { $realInstance = $this->_loadRealInstance(); return isset($realInstance->{$propertyName}); } /** * Magic unset call implementation. * * @param string $propertyName The name of the property to unset */ public function __unset($propertyName) { $realInstance = $this->_loadRealInstance(); unset($realInstance->{$propertyName}); } /** * Magic toString call implementation. * * @return string */ public function __toString() { $realInstance = $this->_loadRealInstance(); return $realInstance->__toString(); } /** * Returns the current value of the storage array */ public function current(): mixed { // todo: make sure current() can be performed on $realInstance $realInstance = $this->_loadRealInstance(); return current($realInstance); } /** * Returns the current key storage array * @return int|string|null */ public function key(): mixed { // todo: make sure key() can be performed on $realInstance $realInstance = $this->_loadRealInstance(); return key($realInstance); } /** * Returns the next position of the storage array */ public function next(): void { // todo: make sure next() can be performed on $realInstance $realInstance = $this->_loadRealInstance(); next($realInstance); } /** * Resets the array pointer of the storage */ public function rewind(): void { // todo: make sure reset() can be performed on $realInstance $realInstance = $this->_loadRealInstance(); reset($realInstance); } /** * Checks if the array pointer of the storage points to a valid position */ public function valid(): bool { return $this->current() !== false; } public function __serialize(): array { $properties = get_object_vars($this); unset($properties['dataMapper']); return $properties; } public function __unserialize(array $data): void { foreach ($data as $propertyName => $propertyValue) { $this->{$propertyName} = $propertyValue; } $this->dataMapper = GeneralUtility::getContainer()->get(DataMapper::class); } }