Laravel5JsonApiServiceProvider   A
last analyzed

Complexity

Total Complexity 18

Size/Duplication

Total Lines 139
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Importance

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

7 Methods

Rating   Name   Duplication   Size   Complexity  
A boot() 0 4 1
A register() 0 17 1
B parseRoutes() 0 25 5
A setUrlWithReflection() 0 11 2
B setJsonApiRelationships() 0 19 6
A calculateRoute() 0 11 2
A provides() 0 4 1
1
<?php
2
3
/**
4
 * Author: Nil Portugués Calderó <[email protected]>
5
 * Date: 8/15/15
6
 * Time: 5:45 PM.
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace NilPortugues\Laravel5\JsonApi;
13
14
use Illuminate\Support\Facades\Cache;
15
use Illuminate\Support\ServiceProvider;
16
use NilPortugues\Api\JsonApi\JsonApiTransformer;
17
use NilPortugues\Api\Mapping\Mapping;
18
use NilPortugues\Laravel5\JsonApi\Mapper\Mapper;
19
use ReflectionClass;
20
21
class Laravel5JsonApiServiceProvider extends ServiceProvider
22
{
23
    const PATH = '/../../../config/jsonapi.php';
24
25
    /**
26
     * Indicates if loading of the provider is deferred.
27
     *
28
     * @var bool
29
     */
30
    protected $defer = false;
31
32
    /**
33
     * Bootstrap the application events.
34
     */
35
    public function boot()
36
    {
37
        $this->publishes([__DIR__.self::PATH => config('jsonapi.php')]);
38
    }
39
40
    /**
41
     * Register the service provider.
42
     */
43
    public function register()
44
    {
45
        $this->mergeConfigFrom(__DIR__.self::PATH, 'jsonapi');
46
        $this->app->singleton(
47
            JsonApiSerializer::class,
48
            function ($app) {
49
                $mapping = $app['config']->get('jsonapi');
50
                $transformer = new JsonApiTransformer(self::parseRoutes(new Mapper($mapping)));
51
52
                $cacheableConfig = function () use ($transformer) {
53
                    return new JsonApiSerializer($transformer);
54
                };
55
56
                return Cache::rememberForever(md5(json_encode($mapping)), $cacheableConfig);
57
            }
58
        );
59
    }
60
61
    /**
62
     * @param Mapper $mapper
63
     *
64
     * @return Mapper
65
     */
66
    private static function parseRoutes(Mapper $mapper)
67
    {
68
        foreach ($mapper->getClassMap() as &$mapping) {
0 ignored issues
show
Bug introduced by
The expression $mapper->getClassMap() cannot be used as a reference.

Let?s assume that you have the following foreach statement:

foreach ($array as &$itemValue) { }

$itemValue is assigned by reference. This is possible because the expression (in the example $array) can be used as a reference target.

However, if we were to replace $array with something different like the result of a function call as in

foreach (getArray() as &$itemValue) { }

then assigning by reference is not possible anymore as there is no target that could be modified.

Available Fixes

1. Do not assign by reference
foreach (getArray() as $itemValue) { }
2. Assign to a local variable first
$array = getArray();
foreach ($array as &$itemValue) {}
3. Return a reference
function &getArray() { $array = array(); return $array; }

foreach (getArray() as &$itemValue) { }
Loading history...
69
            $mappingClass = new \ReflectionClass($mapping);
70
71
            self::setUrlWithReflection($mapping, $mappingClass, 'resourceUrlPattern');
72
            self::setUrlWithReflection($mapping, $mappingClass, 'selfUrl');
73
            $mappingProperty = $mappingClass->getProperty('otherUrls');
74
            $mappingProperty->setAccessible(true);
75
76
            $otherUrls = (array) $mappingProperty->getValue($mapping);
77
            if (!empty($otherUrls)) {
78
                foreach ($otherUrls as &$url) {
79
                    if (!empty($url['name'])) {
80
                        $url = self::calculateRoute($url);
81
                    }
82
                }
83
            }
84
            $mappingProperty->setValue($mapping, $otherUrls);
85
86
            self::setJsonApiRelationships($mappingClass, $mapping);
87
        }
88
89
        return $mapper;
90
    }
91
92
    /**
93
     * @param Mapping         $mapping
94
     * @param ReflectionClass $mappingClass
95
     * @param string          $property
96
     */
97
    private static function setUrlWithReflection(Mapping $mapping, ReflectionClass $mappingClass, $property)
98
    {
99
        $mappingProperty = $mappingClass->getProperty($property);
100
        $mappingProperty->setAccessible(true);
101
        $value = $mappingProperty->getValue($mapping);
102
103
        if (!empty($value['name'])) {
104
            $route = self::calculateRoute($value);
105
            $mappingProperty->setValue($mapping, $route);
106
        }
107
    }
108
109
    /**
110
     * @param ReflectionClass $mappingClass
111
     * @param                 $mapping
112
     */
113
    private static function setJsonApiRelationships(ReflectionClass $mappingClass, $mapping)
114
    {
115
        $mappingProperty = $mappingClass->getProperty('relationshipSelfUrl');
116
        $mappingProperty->setAccessible(true);
117
118
        $relationshipSelfUrl = (array) $mappingProperty->getValue($mapping);
119
        if (!empty($relationshipSelfUrl)) {
120
            foreach ($relationshipSelfUrl as &$urlMember) {
121
                if (!empty($urlMember)) {
122
                    foreach ($urlMember as &$url) {
123
                        if (!empty($url['name'])) {
124
                            $url = self::calculateRoute($url);
125
                        }
126
                    }
127
                }
128
            }
129
        }
130
        $mappingProperty->setValue($mapping, $relationshipSelfUrl);
131
    }
132
133
    /**
134
     * @param array $value
135
     *
136
     * @return mixed|string
137
     */
138
    private static function calculateRoute(array $value)
139
    {
140
        $route = urldecode(route($value['name']));
141
142
        if (!empty($value['as_id'])) {
143
            preg_match_all('/{(.*?)}/', $route, $matches);
144
            $route = str_replace($matches[0], '{'.$value['as_id'].'}', $route);
145
        }
146
147
        return $route;
148
    }
149
150
    /**
151
     * Get the services provided by the provider.
152
     *
153
     * @return array
154
     */
155
    public function provides()
156
    {
157
        return ['jsonapi'];
158
    }
159
}
160