protected function with($collection, $entityName, $with = [])
{
$eventEmitter = $this->eventEmitter();
$return = $eventEmitter->emit('beforeWith', [$this, $collection, $with]);
if (false === $return) {
return $collection;
}
foreach ($with as $relationName) {
// We only need a single entity from the collection, because we're
// going to modify the query to pass in an array of all the
// identity keys from the collection instead of just that single entity
$singleEntity = $collection->first();
// Ensure we have a valid entity object
if (!$singleEntity instanceof Entity) {
throw new Exception("Relation object must be instance of 'Spot\\Entity', given '" . get_class($singleEntity) . "'");
}
$relationObject = $singleEntity->relation($relationName);
// Ensure we have a valid relation name
if ($relationObject === false) {
throw new Exception("Invalid relation name eager-loaded in 'with' clause: No relation on {$entityName} with name '{$relationName}'");
}
// Ensure we have a valid relation object
if (!$relationObject instanceof Relation\RelationAbstract) {
throw new Exception("Relation object must be instance of 'Spot\\Relation\\RelationAbstract', given '" . get_class($relationObject) . "'");
}
// Hook so user can load custom relations their own way if they
// want to, and then bypass the normal loading process by returning
// false from their event
$return = $eventEmitter->emit('loadWith', [$this, $collection, $relationName]);
if (false === $return) {
continue;
}
// Eager-load relation results back to collection
$collection = $relationObject->eagerLoadOnCollection($relationName, $collection);
}
$eventEmitter->emit('afterWith', [$this, $collection, $with]);
return $collection;
}