From 47126a058a8614b94f01c449a7a288dd221adf80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nil=20Portugu=C3=A9s=20Calder=C3=B3?= Date: Sat, 17 Oct 2015 00:17:06 +0200 Subject: [PATCH] Map only those method names returning eloquent operations --- .../Mapper/MappingFactory.php | 28 +++++++++++++++++-- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/src/NilPortugues/Laravel5/JsonApiSerializer/Mapper/MappingFactory.php b/src/NilPortugues/Laravel5/JsonApiSerializer/Mapper/MappingFactory.php index f8c9dc9..a319e18 100644 --- a/src/NilPortugues/Laravel5/JsonApiSerializer/Mapper/MappingFactory.php +++ b/src/NilPortugues/Laravel5/JsonApiSerializer/Mapper/MappingFactory.php @@ -10,6 +10,7 @@ namespace NilPortugues\Laravel5\JsonApiSerializer\Mapper; +use ErrorException; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Facades\Schema; use ReflectionClass; @@ -40,7 +41,7 @@ protected static function getClassProperties($className) if (is_subclass_of($value, Model::class, true)) { $attributes = array_merge( Schema::getColumnListing($value->getTable()), - self::getRelationshipMethodsAsPropertyName($className, $reflection) + self::getRelationshipMethodsAsPropertyName($value, $className, $reflection) ); self::$eloquentClasses[$className] = $attributes; @@ -53,18 +54,39 @@ protected static function getClassProperties($className) return parent::getClassProperties($className); } + /** + * @param $value * @param string $className * @param ReflectionClass $reflection * * @return array */ - protected static function getRelationshipMethodsAsPropertyName($className, ReflectionClass $reflection) + protected static function getRelationshipMethodsAsPropertyName($value, $className, ReflectionClass $reflection) { $methods = []; foreach ($reflection->getMethods(ReflectionMethod::IS_PUBLIC) as $method) { if (ltrim($method->class, "\\") === ltrim($className, "\\")) { - $methods[] = $method->name; + + $name = $method->name; + $reflectionMethod = $reflection->getMethod($name); + + // Eloquent relations do not include parameters, so we'll be filtering based on this criteria. + if (0 == $reflectionMethod->getNumberOfParameters()) { + try { + $returned = $reflectionMethod->invoke($value); + //All operations (eg: boolean operations) are now filtered out. + if (is_object($returned)) { + + // Only keep those methods as properties if these are returning Eloquent relations. + // But do not run the operation as it is an expensive operation. + if (false !== strpos(get_class($returned), 'Illuminate\Database\Eloquent\Relations')) { + $methods[] = $method->name; + } + + } + } catch(ErrorException $e) {} + } } }