Skip to content

Commit

Permalink
possibility to use query object in entity
Browse files Browse the repository at this point in the history
  • Loading branch information
mibk committed Mar 2, 2014
1 parent 158c238 commit a55ebd6
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 1 deletion.
11 changes: 10 additions & 1 deletion LeanMapperQuery/Caller.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,14 @@
*/
class Caller extends \LeanMapper\Caller
{

// There are 4 possibilities:
// a) caller is just instance of
// LeanMapper\Caller:
// 1) caller is entity
// 2) caller is repository
// b) caller is instance of this class
// (LeanMapperQuery\Caller):
// 3) caller is query object
// 4) if method self::isEntity return TRUE,
// caller is query object via entity
}
99 changes: 99 additions & 0 deletions LeanMapperQuery/Entity.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
<?php

/**
* This file is part of the LeanMapperQuery extension
* for the Lean Mapper library (http://leanmapper.com)
* Copyright (c) 2013 Michal Bohuslávek
*/

namespace LeanMapperQuery;

use LeanMapper;
use LeanMapper\Filtering;
use LeanMapper\Fluent;
use LeanMapper\Reflection\Property;
use LeanMapper\Relationship;
use LeanMapperQuery\Caller;
use LeanMapperQuery\IQuery;
use LeanMapperQuery\Exception\InvalidArgumentException;
use LeanMapperQuery\Exception\InvalidMethodCallException;
use LeanMapperQuery\Exception\InvalidRelationshipException;
use LeanMapperQuery\Exception\InvalidStateException;
use LeanMapperQuery\Exception\MemberAccessException;

/**
* @author Michal Bohuslávek
*/
class Entity extends LeanMapper\Entity
{
/** @var array */
protected static $magicMethodsPrefixes = array();


protected function queryProperty($field, IQuery $query)
{
if ($this->isDetached()) {
throw new InvalidStateException('Cannot query detached entity.');
}
$property = $this->getCurrentReflection()->getEntityProperty($field);
if ($property === NULL) {
throw new MemberAccessException("Cannot access undefined property '$field' in entity " . get_called_class() . '.');
}
if (!$property->hasRelationship()) {
throw new InvalidArgumentException("Property '{$property->getName()}' in entity ". get_called_class() . " has no relationship.");
}
$class = $property->getType();
$filters = $this->createImplicitFilters($class, new Caller($this, $property))->getFilters();
$mapper = $this->mapper;
$filters[] = function (Fluent $fluent) use ($mapper, $query) {
$query->applyQuery($fluent, $mapper);
};

$relationship = $property->getRelationship();
if ($relationship instanceof Relationship\BelongsToMany) {
$targetTable = $relationship->getTargetTable();
$referencingColumn = $relationship->getColumnReferencingSourceTable();
$rows = $this->row->referencing($targetTable, $referencingColumn, new Filtering($filters));

} elseif ($relationship instanceof Relationship\HasMany) {
$relationshipTable = $relationship->getRelationshipTable();
$sourceReferencingColumn = $relationship->getColumnReferencingSourceTable();
$targetReferencingColumn = $relationship->getColumnReferencingTargetTable();
$targetTable = $relationship->getTargetTable();
$rows = array();
foreach ($this->row->referencing($relationshipTable, $sourceReferencingColumn) as $relationship) {
$row = $relationship->referenced($targetTable, $targetReferencingColumn, new Filtering($filters));
$row !== NULL && $rows[] = $row;
}
} else {
throw new InvalidRelationshipException('Only BelongsToMany and HasMany relationships are supported when querying entity property. ' . get_class($relationship) . ' given.');
}
$entities = array();
foreach ($rows as $row) {
$entity = $this->entityFactory->createEntity($class, $row);
$entity->makeAlive($this->entityFactory);
$entities[] = $entity;
}
return $entities;
}

public function __call($name, array $arguments)
{
if (preg_match('#^('.implode('|', static::$magicMethodsPrefixes).')(.+)$#', $name, $matches)) {
if (count($arguments) !== 1) {
throw new InvalidMethodCallException(get_called_class() . "::$name expects exactly 1 argument. " . count($arguments) . ' given.');
}
list($query) = $arguments;
if (!$query instanceof IQuery) {
throw new InvalidArgumentException('Argument 1 passed to ' . get_called_class() . "::$name must implement interface LeanMapperQuery\\IQuery. " . gettype($query) . ' given.');
}
list(, $method, $field) = $matches;
$field = lcfirst($field);
return $this->$method($field, $query);

} else {
return parent::__call($name, $arguments);
}
}

}
17 changes: 17 additions & 0 deletions LeanMapperQuery/Exception/InvalidMethodCallException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

/**
* This file is part of the LeanMapperQuery extension
* for the Lean Mapper library (http://leanmapper.com)
* Copyright (c) 2013 Michal Bohuslávek
*/

namespace LeanMapperQuery\Exception;

/**
* @author Michal Bohuslávek
*/
class InvalidMethodCallException extends Exception
{

}

0 comments on commit a55ebd6

Please sign in to comment.