Completed
Pull Request — master (#5)
by Zach
01:52
created

Controller::setTransformer()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
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\Database\Eloquent\Builder;
6
use Illuminate\Support\Facades\App;
7
use Illuminate\Support\Facades\Input;
8
use NavJobs\Transmit\Traits\ErrorResponsesTrait;
9
use NavJobs\Transmit\Traits\QueryHelperTrait;
10
use Illuminate\Routing\Controller as BaseController;
11
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
12
13
abstract class Controller extends BaseController
14
{
15
    use QueryHelperTrait, ErrorResponsesTrait;
16
17
    protected $statusCode = 200;
18
    protected $fractal;
19
20
    public function __construct()
21
    {
22
        $this->fractal = App::make(Fractal::class);
23
24
        $this->parseIncludes();
25
26
        $this->resourceKey = null;
0 ignored issues
show
Bug introduced by
The property resourceKey does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
27
    }
28
29
    /**
30
     * Sets the fractal transformer
31
     *
32
     * @return mixed
33
     */
34
    public function setTransformer($transformer) {
35
        $this->transformer = $transformer;
0 ignored issues
show
Bug introduced by
The property transformer does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
36
        return $this;
37
    }
38
39
    /**
40
     * Sets model builder
41
     *
42
     * @return mixed
43
     */
44
    public function setModel($model) {
45
        $this->model = $model;
0 ignored issues
show
Bug introduced by
The property model does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
46
        return $this;
47
    }
48
49
    /**
50
     * Calls authorization methods on the default traits
51
     *
52
     * @return mixed
53
     */
54
    public function shouldAuthorize() {
55
        $this->shouldAuthorize = true;
0 ignored issues
show
Bug introduced by
The property shouldAuthorize does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
56
        return $this;
57
    }
58
59
    /**
60
     * Sets resource key for fractal
61
     *
62
     * @return mixed
63
     */
64
    public function setResourceKey($resourceKey) {
65
        $this->resourceKey = $resourceKey;
66
        return $this;
67
    }
68
69
    /**
70
     * Parses includes from either the header or query string.
71
     *
72
     * @return mixed
73
     */
74
    protected function parseIncludes()
75
    {
76
        if (Input::header('include')) {
77
            return $this->fractal->parseIncludes(Input::header('include'));
78
        }
79
80
        if (Input::get('include')) {
81
            return $this->fractal->parseIncludes(Input::get('include'));
82
        }
83
84
        return null;
85
    }
86
87
    /**
88
     * Returns the current status code.
89
     *
90
     * @return int
91
     */
92
    protected function getStatusCode()
93
    {
94
        return $this->statusCode;
95
    }
96
97
    /**
98
     * Sets the current status code.
99
     *
100
     * @param $statusCode
101
     * @return $this
102
     */
103
    protected function setStatusCode($statusCode)
104
    {
105
        $this->statusCode = $statusCode;
106
107
        return $this;
108
    }
109
110
    private function prepareBuilder($builder)
111
    {
112
        $model = $builder ?: $this->model;
113
114
        $includes = $this->transformer->getEagerLoads($this->fractal->getRequestedIncludes());
115
        $includedItems = $this->eagerLoadIncludes($model, $includes);
116
        return $this->applyParameters($includedItems, request()->query);
117
    }
118
119
    /**
120
     * Returns a json response that contains the specified resource
121
     * passed through fractal and optionally a transformer.
122
     *
123
     * @param $item
124
     * @param null $callback
125
     * @return \Illuminate\Http\JsonResponse
126
     */
127 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...
128
    {
129
        if($callback) {
130
            $builder = $this->prepareBuilder($item);
131
            $item = $callback($builder);
132
        }
133
134
        $rootScope = $this->fractal->item($item, $this->transformer, is_null($this->resourceKey) ? false : $this->resourceKey);
135
136
        return $this->respondWithArray($rootScope->toArray());
137
    }
138
139
    /**
140
     * Returns a json response that indicates the resource was successfully created also
141
     * returns the resource passed through fractal and optionally a transformer.
142
     *
143
     * @param $item
144
     * @param null $callback
145
     * @return \Illuminate\Http\JsonResponse
146
     */
147 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...
148
    {
149
        if($callback) {
150
            $builder = $this->prepareBuilder($item);
151
            $item = $callback($builder);
152
        }
153
154
        $this->setStatusCode(201);
155
        $rootScope = $this->fractal->item($item, $this->transformer, is_null($this->resourceKey) ? false : $this->resourceKey);
156
157
        return $this->respondWithArray($rootScope->toArray());
158
    }
159
160
    /**
161
     * Returns a json response that contains the specified collection
162
     * passed through fractal and optionally a transformer.
163
     *
164
     * @param $collection
165
     * @param $callback
166
     * @return \Illuminate\Http\JsonResponse
167
     */
168
    protected function respondWithCollection($collection)
169
    {
170
        $rootScope = $this->fractal->collection($collection, $this->transformer, is_null($this->resourceKey) ? false : $this->resourceKey);
171
172
        return $this->respondWithArray($rootScope->toArray());
173
    }
174
175
    /**
176
     * Returns a json response that contains the specified paginated collection
177
     * passed through fractal and optionally a transformer.
178
     *
179
     * @param $builder
180
     * @param $callback
181
     * @param int $perPage
182
     * @return \Illuminate\Http\JsonResponse
183
     */
184
    protected function respondWithPaginatedCollection($builder = null, $perPage = 10)
185
    {
186
        $builder = $this->prepareBuilder($builder);
187
188
        $paginator = $builder->paginate($perPage);
189
        $paginator->appends($this->getQueryParameters());
190
191
        $rootScope = $this->fractal
192
            ->collection($paginator->getCollection(), $this->transformer, $this->resourceKey)
193
            ->paginateWith(new IlluminatePaginatorAdapter($paginator));
194
195
        return $this->respondWithArray($rootScope->toArray());
196
    }
197
198
    /**
199
     * Returns an array of Query Parameters, not including pagination.
200
     *
201
     * @return array
202
     */
203
    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...
204
    {
205
        return array_diff_key($_GET, array_flip(['page']));
206
    }
207
208
    /**
209
     * Returns a json response that contains the specified array,
210
     * the current status code and optional headers.
211
     *
212
     * @param array $array
213
     * @param array $headers
214
     * @return \Illuminate\Http\JsonResponse
215
     */
216
    protected function respondWithArray(array $array, array $headers = [])
217
    {
218
        return response()->json($array, $this->statusCode, $headers);
219
    }
220
221
    /**
222
     * Returns a response that indicates success but no content returned.
223
     *
224
     * @return \Illuminate\Http\Response
225
     */
226
    protected function respondWithNoContent()
227
    {
228
        return response()->make('', 204);
229
    }
230
}
231