Completed
Push — master ( c3f7f6...458bfd )
by Changwan
02:39
created

Restifier   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 108
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 96.23%

Importance

Changes 0
Metric Value
dl 0
loc 108
ccs 51
cts 53
cp 0.9623
rs 10
c 0
b 0
f 0
wmc 25
lcom 1
cbo 1

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 2
A addTransformer() 0 8 2
B restify() 0 18 6
A restifyMany() 0 8 2
B findTransformer() 0 15 5
C parseIncludes() 0 27 8
1
<?php
2
namespace Wandu\Restifier;
3
4
use InvalidArgumentException;
5
use Wandu\Restifier\Contracts\Restifiable;
6
use Wandu\Restifier\Exception\NotFoundTransformerException;
7
8
class Restifier implements Restifiable
9
{
10
    /** @var callable[] */
11
    protected $transformers = [];
12
    
13 9
    public function __construct(array $transformers = [])
14
    {
15 9
        foreach ($transformers as $name => $transformer) {
16
            $this->addTransformer($name, $transformer);
17
        }
18 9
    }
19
20
    /**
21
     * @param string $name
22
     * @param callable $transformer
23
     */
24 6
    public function addTransformer(string $name, callable $transformer)
25
    {
26 6
        if (is_callable($transformer)) {
27 6
            $this->transformers[$name] = $transformer;
28 6
            return;
29
        }
30
        throw new InvalidArgumentException("Argument 2 passed to pushTransformer() must be callable");
31
    }
32
    
33
    /**
34
     * {@inheritdoc}
35
     */
36 9
    public function restify($resource, array $includes = [], callable $transformer = null)
37
    {
38 9
        if ($resource === null) return null;
39 8
        if (!$transformer) {
40 7
            $transformer = $this->findTransformer($resource);
41
        }
42 7
        $parsedIncludes = $this->parseIncludes($includes, $resource);
43 7
        $entity = call_user_func($transformer, $resource, $this, $parsedIncludes);
44 7
        foreach ($parsedIncludes as $key => $nextIncludes) {
45 2
            if (is_object($transformer) && method_exists($transformer, $key)) {
46 2
                $entity = array_merge(
47 2
                    $entity,
48 2
                    $transformer->{$key}($resource, $this, $nextIncludes)
49
                );
50
            }
51
        }
52 7
        return $entity;
53
    }
54
55
    /**
56
     * {@inheritdoc}
57
     */
58 1
    public function restifyMany($resource, array $includes = [], callable $transformer = null): array
59
    {
60 1
        $result = [];
61 1
        foreach ($resource as $key => $value) {
62 1
            $result[$key] = $this->restify($value, $includes, $transformer);
63
        }
64 1
        return $result;
65
    }
66
67 7
    protected function findTransformer($resource)
68
    {
69 7
        $className = null;
70 7
        if (is_object($resource) && $className = get_class($resource)) {
71 7
            if (array_key_exists($className, $this->transformers)) {
72 6
                return $this->transformers[$className];
73
            }
74
        }
75 1
        if ($className) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $className of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
76 1
            throw new NotFoundTransformerException(
77 1
                sprintf("cannot find the transformer named %s.", $className)
78
            );
79
        }
80 1
        throw new NotFoundTransformerException("resource is not an object.");
81
    }
82
    
83
    /**
84
     * @param array $includes
85
     * @param mixed $resource
86
     * @return array
87
     */
88 7
    private function parseIncludes(array $includes = [], $resource)
89
    {
90 7
        $parsedIncludes = [];
91 7
        foreach ($includes as $include => $condition) {
92 2
            if (is_integer($include)) {
93 2
                $include = $condition;
94 2
                $condition = true;
95
            }
96 2
            while (is_callable($condition)) {
97 1
                $condition = call_user_func($condition, $resource);
98
            }
99 2
            if (!$condition) continue;
100 2
            if (strpos($include, '.') === false) {
101 2
                $key = $include;
102 2
                $param = null;
103
            } else {
104 1
                list($key, $param) = explode('.', $include, 2);
105
            }
106 2
            if (!isset($parsedIncludes[$key])) {
107 2
                $parsedIncludes[$key] = [];
108
            }
109 2
            if ($param) {
110 2
                $parsedIncludes[$key][] = $param;
111
            }
112
        }
113 7
        return $parsedIncludes;
114
    }
115
}
116