Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
61 lines (51 sloc) 2.21 KB
<?php
namespace Emonkak\Orm\Relation\JoinStrategy;
use Emonkak\Enumerable\Iterator\SelectIterator;
use Emonkak\Orm\ResultSet\ResultSetInterface;
use ProxyManager\Factory\LazyLoadingValueHolderFactory;
use ProxyManager\Proxy\LazyLoadingInterface;
class LazyOuterJoin implements JoinStrategyInterface
{
/**
* @var LazyLoadingValueHolderFactory
*/
private $proxyFactory;
/**
* @param LazyLoadingValueHolderFactory $proxyFactory
*/
public function __construct(LazyLoadingValueHolderFactory $proxyFactory)
{
$this->proxyFactory = $proxyFactory;
}
/**
* {@inheritDoc}
*/
public function join(ResultSetInterface $outer, ResultSetInterface $inner, callable $outerKeySelector, callable $innerKeySelector, callable $resultSelector)
{
$proxyFactory = $this->proxyFactory;
$cachedElements = null;
return new SelectIterator($outer, static function($outerElement) use ($proxyFactory, &$cachedElements, $inner, $outerKeySelector, $innerKeySelector, $resultSelector) {
$initializer = static function (&$wrappedObject, LazyLoadingInterface $proxy, $method, array $parameters, &$initializer) use (&$cachedElements, $outerElement, $inner, $outerKeySelector, $innerKeySelector) {
$initializer = null;
if ($cachedElements === null) {
$cachedElements = [];
foreach ($inner as $innerElement) {
$cachedElements[$innerKeySelector($innerElement)] = $innerElement;
}
}
$outerKey = $outerKeySelector($outerElement);
if (isset($cachedElements[$outerKey])) {
$wrappedObject = $cachedElements[$outerKey];
} else {
// Wraps the dummy object instead of null.
$wrappedObject = (new \ReflectionClass($inner->getClass()))
->newInstanceWithoutConstructor();
}
return true;
};
$innerClass = $inner->getClass();
$proxy = $proxyFactory->createProxy($innerClass, $initializer);
return $resultSelector($outerElement, $proxy);
});
}
}