MappingFactory   A
last analyzed

Complexity

Total Complexity 10

Size/Duplication

Total Lines 73
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

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

2 Methods

Rating   Name   Duplication   Size   Complexity  
A getClassProperties() 0 21 3
C getRelationshipMethodsAsPropertyName() 0 31 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\JsonSerializer\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
 * @package NilPortugues\Laravel5\JsonApiSerializer\Mapper
22
 */
23
class MappingFactory extends \NilPortugues\Api\Mapping\MappingFactory
24
{
25
    /**
26
     * @var array
27
     */
28
    protected static $eloquentClasses = [];
29
30
    /**
31
     * @param string $className
32
     *
33
     * @return array
34
     */
35
    protected static function getClassProperties($className)
36
    {
37
        if (class_exists($className, true)) {
38
            $reflection = new ReflectionClass($className);
39
            $value = $reflection->newInstanceWithoutConstructor();
40
41
            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...
42
                $attributes =  array_merge(
43
                    Schema::getColumnListing($value->getTable()),
44
                    self::getRelationshipMethodsAsPropertyName($value, $className, $reflection)
45
                );
46
47
                self::$eloquentClasses[$className] = $attributes;
48
49
                return self::$eloquentClasses[$className];
50
            }
51
52
        }
53
54
        return parent::getClassProperties($className);
55
    }
56
57
    /**
58
     * @param                 $value
59
     * @param string          $className
60
     * @param ReflectionClass $reflection
61
     *
62
     * @return array
63
     */
64
    protected static function getRelationshipMethodsAsPropertyName($value, $className, ReflectionClass $reflection)
65
    {
66
        $methods = [];
67
        foreach ($reflection->getMethods(ReflectionMethod::IS_PUBLIC) as $method) {
68
69
            if (ltrim($method->class, "\\") === ltrim($className, "\\")) {
70
71
                $name = $method->name;
72
                $reflectionMethod = $reflection->getMethod($name);
73
74
                // Eloquent relations do not include parameters, so we'll be filtering based on this criteria.
75
                if (0 == $reflectionMethod->getNumberOfParameters()) {
76
                    try {
77
                        $returned = $reflectionMethod->invoke($value);
78
                        //All operations (eg: boolean operations) are now filtered out.
79
                        if (is_object($returned)) {
80
81
                            // Only keep those methods as properties if these are returning Eloquent relations.
82
                            // But do not run the operation as it is an expensive operation.
83
                            if (false !== strpos(get_class($returned), 'Illuminate\Database\Eloquent\Relations')) {
84
                                $methods[] = $method->name;
85
                            }
86
87
                        }
88
                    } catch (ErrorException $e) {}
89
                }
90
            }
91
        }
92
93
        return $methods;
94
    }
95
}
96