MappingFactory   A
last analyzed

Complexity

Total Complexity 10

Size/Duplication

Total Lines 70
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Importance

Changes 3
Bugs 0 Features 1
Metric Value
wmc 10
c 3
b 0
f 1
lcom 1
cbo 0
dl 0
loc 70
rs 10

2 Methods

Rating   Name   Duplication   Size   Complexity  
A getClassProperties() 0 20 3
C getRelationshipMethodsAsPropertyName() 0 29 7
1
<?php
2
/**
3
 * Author: Nil Portugués Calderó <[email protected]>
4
 * Date: 10/16/15
5
 * Time: 8:59 PM.
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace NilPortugues\Laravel5\HalJsonSerializer\Mapper;
12
13
use ErrorException;
14
use Illuminate\Database\Eloquent\Model;
15
use Illuminate\Support\Facades\Schema;
16
use ReflectionClass;
17
use ReflectionMethod;
18
19
/**
20
 * Class MappingFactory.
21
 */
22
class MappingFactory extends \NilPortugues\Api\Mapping\MappingFactory
23
{
24
    /**
25
     * @var array
26
     */
27
    protected static $eloquentClasses = [];
28
29
    /**
30
     * @param string $className
31
     *
32
     * @return array
33
     */
34
    protected static function getClassProperties($className)
35
    {
36
        if (\class_exists($className, true)) {
37
            $reflection = new ReflectionClass($className);
38
            $value = $reflection->newInstanceWithoutConstructor();
39
40
            if (\is_subclass_of($value, Model::class, true)) {
0 ignored issues
show
Bug introduced by
Due to PHP Bug #53727, is_subclass_of might return inconsistent results on some PHP versions if \Illuminate\Database\Eloquent\Model::class can be an interface. If so, you could instead use ReflectionClass::implementsInterface.
Loading history...
41
                $attributes = \array_merge(
42
                    Schema::getColumnListing($value->getTable()),
43
                    self::getRelationshipMethodsAsPropertyName($value, $className, $reflection)
44
                );
45
46
                self::$eloquentClasses[$className] = $attributes;
47
48
                return self::$eloquentClasses[$className];
49
            }
50
        }
51
52
        return parent::getClassProperties($className);
53
    }
54
55
    /**
56
     * @param                 $value
57
     * @param string          $className
58
     * @param ReflectionClass $reflection
59
     *
60
     * @return array
61
     */
62
    protected static function getRelationshipMethodsAsPropertyName($value, $className, ReflectionClass $reflection)
63
    {
64
        $methods = [];
65
        foreach ($reflection->getMethods(ReflectionMethod::IS_PUBLIC) as $method) {
66
            if (\ltrim($method->class, '\\') === \ltrim($className, '\\')) {
67
                $name = $method->name;
68
                $reflectionMethod = $reflection->getMethod($name);
69
70
                // Eloquent relations do not include parameters, so we'll be filtering based on this criteria.
71
                if (0 == $reflectionMethod->getNumberOfParameters()) {
72
                    try {
73
                        $returned = $reflectionMethod->invoke($value);
74
                        //All operations (eg: boolean operations) are now filtered out.
75
                        if (\is_object($returned)) {
76
77
                            // Only keep those methods as properties if these are returning Eloquent relations.
78
                            // But do not run the operation as it is an expensive operation.
79
                            if (false !== \strpos(\get_class($returned), 'Illuminate\Database\Eloquent\Relations')) {
80
                                $methods[] = $method->name;
81
                            }
82
                        }
83
                    } catch (ErrorException $e) {
84
                    }
85
                }
86
            }
87
        }
88
89
        return $methods;
90
    }
91
}
92