Completed
Pull Request — master (#5)
by Zach
09:01 queued 06:55
created

Controller::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

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