Completed
Pull Request — master (#5)
by Josh
01:58
created

Controller::setResourceKey()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 1
1
<?php
2
3
namespace NavJobs\Transmit;
4
5
use Illuminate\Support\Facades\Input;
6
use NavJobs\Transmit\Traits\QueryHelperTrait;
7
use NavJobs\Transmit\Traits\ErrorResponsesTrait;
8
use Illuminate\Routing\Controller as BaseController;
9
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
10
11
abstract class Controller extends BaseController
12
{
13
    use QueryHelperTrait, ErrorResponsesTrait;
14
15
    protected $statusCode = 200;
16
    protected $resourceKey = null;
17
    protected $fractal, $transformer;
0 ignored issues
show
Coding Style introduced by
It is generally advisable to only define one property per statement.

Only declaring a single property per statement allows you to later on add doc comments more easily.

It is also recommended by PSR2, so it is a common style that many people expect.

Loading history...
18
19
    public function __construct()
20
    {
21
        $this->fractal = app(Fractal::class);
22
23
        $this->parseIncludes();
24
    }
25
26
    /**
27
     * Sets the fractal transformer
28
     *
29
     * @param $transformer
30
     * @return mixed
31
     */
32
    public function setTransformer($transformer)
33
    {
34
        $this->transformer = $transformer;
35
36
        return $this;
37
    }
38
39
    /**
40
     * Sets resource key for fractal
41
     *
42
     * @param $resourceKey
43
     * @return mixed
44
     */
45
    public function setResourceKey($resourceKey)
46
    {
47
        $this->resourceKey = $resourceKey;
48
49
        return $this;
50
    }
51
52
    /**
53
     * Parses includes from either the header or query string.
54
     *
55
     * @return mixed
56
     */
57
    protected function parseIncludes()
58
    {
59
        if (Input::header('include')) {
60
            return $this->fractal->parseIncludes(Input::header('include'));
61
        }
62
63
        if (Input::get('include')) {
64
            return $this->fractal->parseIncludes(Input::get('include'));
65
        }
66
67
        return null;
68
    }
69
70
    /**
71
     * Returns the current status code.
72
     *
73
     * @return int
74
     */
75
    protected function getStatusCode()
76
    {
77
        return $this->statusCode;
78
    }
79
80
    /**
81
     * Sets the current status code.
82
     *
83
     * @param $statusCode
84
     * @return $this
85
     */
86
    protected function setStatusCode($statusCode)
87
    {
88
        $this->statusCode = $statusCode;
89
90
        return $this;
91
    }
92
93
    /**
94
     * Eager load any available includes and apply query parameters.
95
     *
96
     * @param $builder
97
     * @return mixed
98
     */
99
    protected function withIncludes($builder)
100
    {
101
        $includes = $this->transformer->getEagerLoads($this->fractal->getRequestedIncludes());
102
        $includedItems = $this->eagerLoadIncludes($builder, $includes);
103
        $this->applyParameters($includedItems, request()->query);
104
105
        return $builder;
106
    }
107
108
    /**
109
     * Returns a json response that contains the specified resource
110
     * passed through fractal and optionally a transformer.
111
     *
112
     * @param $item
113
     * @param null $callback
114
     * @return \Illuminate\Http\JsonResponse
115
     */
116 View Code Duplication
    protected function respondWithItem($item, $callback = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
117
    {
118
        if ($callback) {
119
            $builder = $this->withIncludes($item);
120
            $item = $callback($builder);
121
        }
122
123
        $rootScope = $this->fractal->item($item, $this->transformer, $this->resourceKey);
124
125
        return $this->respondWithArray($rootScope->toArray());
126
    }
127
128
    /**
129
     * Returns a json response that indicates the resource was successfully created also
130
     * returns the resource passed through fractal and optionally a transformer.
131
     *
132
     * @param $item
133
     * @param null $callback
134
     * @return \Illuminate\Http\JsonResponse
135
     */
136 View Code Duplication
    protected function respondWithItemCreated($item, $callback = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
137
    {
138
        if ($callback) {
139
            $builder = $this->withIncludes($item);
140
            $item = $callback($builder);
141
        }
142
143
        $this->setStatusCode(201);
144
        $rootScope = $this->fractal->item($item, $this->transformer, $this->resourceKey);
145
146
        return $this->respondWithArray($rootScope->toArray());
147
    }
148
149
    /**
150
     * Returns a json response that contains the specified collection
151
     * passed through fractal and optionally a transformer.
152
     *
153
     * @param $collection
154
     * @return \Illuminate\Http\JsonResponse
155
     */
156
    protected function respondWithCollection($collection)
157
    {
158
        $rootScope = $this->fractal->collection($collection, $this->transformer, $this->resourceKey);
159
160
        return $this->respondWithArray($rootScope->toArray());
161
    }
162
163
    /**
164
     * Returns a json response that contains the specified paginated collection
165
     * passed through fractal and optionally a transformer.
166
     *
167
     * @param $builder
168
     * @param int $perPage
169
     * @return \Illuminate\Http\JsonResponse
170
     */
171
    protected function respondWithPaginatedCollection($builder, $perPage = 10)
172
    {
173
        $builder = $this->withIncludes($builder);
174
175
        $paginator = $builder->paginate($perPage);
176
        $paginator->appends($this->getQueryParameters());
177
178
        $rootScope = $this->fractal
179
            ->collection($paginator->getCollection(), $this->transformer, $this->resourceKey)
180
            ->paginateWith(new IlluminatePaginatorAdapter($paginator));
181
182
        return $this->respondWithArray($rootScope->toArray());
183
    }
184
185
    /**
186
     * Returns an array of Query Parameters, not including pagination.
187
     *
188
     * @return array
189
     */
190
    protected function getQueryParameters()
0 ignored issues
show
Coding Style introduced by
getQueryParameters uses the super-global variable $_GET which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
191
    {
192
        return array_diff_key($_GET, array_flip(['page']));
193
    }
194
195
    /**
196
     * Returns a json response that contains the specified array,
197
     * the current status code and optional headers.
198
     *
199
     * @param array $array
200
     * @param array $headers
201
     * @return \Illuminate\Http\JsonResponse
202
     */
203
    protected function respondWithArray(array $array, array $headers = [])
204
    {
205
        return response()->json($array, $this->statusCode, $headers);
206
    }
207
208
    /**
209
     * Returns a response that indicates success but no content returned.
210
     *
211
     * @return \Illuminate\Http\Response
212
     */
213
    protected function respondWithNoContent()
214
    {
215
        return response()->make('', 204);
216
    }
217
}
218