The new implementation introduces a LazyLoadingProxyFactory
which generates a LazyProxy
object which extends the concrete object. With this way proxy objects will pass type hints.
The implementation in detail:
LazyLoadingProxyFactory¶
The class can be found at \TYPO3\CMS\Extbase\Persistence\Generic\LazyLoadingProxyFactory
. To retrieve a lazy proxy object call the get() method of the class, which expects three parameters:
- The classname or object to create the proxy from
- The parent object
- The property
- The value of the field
$this->lazyProxyFactory->getProxy($propertyMetaData['type'], $parentObject, $propertyName, $fieldValue);
The generated proxy class is cached and you will find it at typo3temp/Cache/Code/extbase_lazyproxyobject_storage/*LazyProxy.php
Example¶
Lets use the blog_example as … well … as an example:
At some point the DataMapper calls
$this->lazyProxyFactory->getProxy(…)
with this values:
- string $className: ExtbaseTeam\BlogExample\Domain\Model\Administrator
- object $parentObject: ExtbaseTeam\BlogExample\Domain\Model\Blog
- string $propertyName: administrator
- string $fieldValue: 351
Here is the code of the generated AdministratorLazyProxy.php:
<?php
namespace ExtbaseTeam\BlogExample\Domain\Model;
use TYPO3\CMS\Extbase\Persistence\QueryResultInterface;
/**
* This class is generated by the LazyProxyFactory of Extbase. Don't change the file by yourself!
*/
class AdministratorLazyProxy extends \ExtbaseTeam\BlogExample\Domain\Model\Administrator implements \TYPO3\CMS\Extbase\Persistence\Generic\LoadingStrategyInterface {
private $parentObject;
private $propertyName;
private $fieldValue;
private $parentQueryResult;
public function __construct($parentObject, $propertyName, $fieldValue) {
$this->parentObject = $parentObject;
$this->propertyName = $propertyName;
$this->fieldValue = $fieldValue;
}
public function setUsername($username) {
$this->parentQueryResult->fetchLazyObjects($this->propertyName);
return parent::setUsername($username);
}
public function getUsername() {
$this->parentQueryResult->fetchLazyObjects($this->propertyName);
return parent::getUsername();
}
...
/**
* @param QueryResultInterface $queryResult
*
* @return void
*/
public function setParentQueryResult(QueryResultInterface $queryResult) {
$this->parentQueryResult = $queryResult;
}
/**
* Returns the parentObject so we can populate the proxy.
*
* @return object
*/
public function _getParentObject() {
return $this->parentObject;
}
/**
* Returns the fieldValue so we can fetch multiple LazyObjects in one query.
*
* @return mixed
*/
public function _getFieldValue() {
return $this->fieldValue;
}
}
The proxy class overrides all public methods from his parent with his own variant of the methods. This just just add a call to the methods whereby the proxy is able to resolve himself. At the end it will return the requested value from the concrete object.