Completed
Pull Request — master (#5)
by Zach
02:45 queued 50s
created

Controller   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 181
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Importance

Changes 0
Metric Value
wmc 16
lcom 1
cbo 6
dl 0
loc 181
rs 10
c 0
b 0
f 0

12 Methods

Rating   Name   Duplication   Size   Complexity  
A getStatusCode() 0 4 1
A setStatusCode() 0 6 1
A __construct() 0 6 1
A parseIncludes() 0 12 3
A prepareBuilder() 0 8 2
A respondWithItem() 0 11 2
A respondWithItemCreated() 0 7 1
A respondWithCollection() 0 6 1
A respondWithPaginatedCollection() 0 13 1
A getQueryParameters() 0 4 1
A respondWithArray() 0 4 1
A respondWithNoContent() 0 4 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
27
    /**
28
     * Parses includes from either the header or query string.
29
     *
30
     * @return mixed
31
     */
32
    protected function parseIncludes()
33
    {
34
        if (Input::header('include')) {
35
            return $this->fractal->parseIncludes(Input::header('include'));
36
        }
37
38
        if (Input::get('include')) {
39
            return $this->fractal->parseIncludes(Input::get('include'));
40
        }
41
42
        return null;
43
    }
44
45
    /**
46
     * Returns the current status code.
47
     *
48
     * @return int
49
     */
50
    protected function getStatusCode()
51
    {
52
        return $this->statusCode;
53
    }
54
55
    /**
56
     * Sets the current status code.
57
     *
58
     * @param $statusCode
59
     * @return $this
60
     */
61
    protected function setStatusCode($statusCode)
62
    {
63
        $this->statusCode = $statusCode;
64
65
        return $this;
66
    }
67
68
    /**
69
     * Eager load anything that needs to be included
70
     *
71
     * @param Eloquent Builder
72
     * @return $builder
0 ignored issues
show
Documentation introduced by
The doc-type $builder could not be parsed: Unknown type name "$builder" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
73
     */
74
    private function prepareBuilder($builder)
75
    {
76
        $model = $builder ?: $this->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...
77
78
        $includes = $this->transformer->getEagerLoads($this->fractal->getRequestedIncludes());
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...
79
        $includedItems = $this->eagerLoadIncludes($model, $includes);
80
        return $this->applyParameters($includedItems, request()->query);
81
    }
82
83
    /**
84
     * Returns a json response that contains the specified resource
85
     * passed through fractal and optionally a transformer.
86
     *
87
     * @param $item
88
     * @param null $callback
89
     * @param null $resourceKey
90
     * @return \Illuminate\Http\JsonResponse
91
     */
92
    protected function respondWithItem($item, $callback = null, $resourceKey = false)
93
    {
94
        if($callback) {
95
            $builder = $this->prepareBuilder($item);
96
            $item = $callback($builder);
97
        }
98
99
        $rootScope = $this->fractal->item($item, $this->transformer, $resourceKey);
100
101
        return $this->respondWithArray($rootScope->toArray());
102
    }
103
104
    /**
105
     * Returns a json response that indicates the resource was successfully created also
106
     * returns the resource passed through fractal and optionally a transformer.
107
     *
108
     * @param $item
109
     * @param null $callback
110
     * @param null $resourceKey
111
     * @return \Illuminate\Http\JsonResponse
112
     */
113
    protected function respondWithItemCreated($item, $callback = null, $resourceKey = false)
114
    {
115
        $this->setStatusCode(201);
116
        $rootScope = $this->fractal->item($item, $callback, $resourceKey);
117
118
        return $this->respondWithArray($rootScope->toArray());
119
    }
120
121
    /**
122
     * Returns a json response that contains the specified collection
123
     * passed through fractal and optionally a transformer.
124
     *
125
     * @param $collection
126
     * @param $callback
127
     * @param null $resourceKey
128
     * @return \Illuminate\Http\JsonResponse
129
     */
130
    protected function respondWithCollection($collection, $callback, $resourceKey = false)
131
    {
132
        $rootScope = $this->fractal->collection($collection, $callback, $resourceKey);
133
134
        return $this->respondWithArray($rootScope->toArray());
135
    }
136
137
    /**
138
     * Returns a json response that contains the specified paginated collection
139
     * passed through fractal and optionally a transformer.
140
     *
141
     * @param $builder
142
     * @param $callback
143
     * @param int $perPage
144
     * @param null $resourceKey
145
     * @return \Illuminate\Http\JsonResponse
146
     */
147
    protected function respondWithPaginatedCollection($builder = null, $perPage = 10, $resourceKey = null)
148
    {
149
        $builder = $this->prepareBuilder($builder);
150
151
        $paginator = $builder->paginate($perPage);
152
        $paginator->appends($this->getQueryParameters());
153
154
        $rootScope = $this->fractal
155
            ->collection($paginator->getCollection(), $this->transformer, $resourceKey)
156
            ->paginateWith(new IlluminatePaginatorAdapter($paginator));
157
158
        return $this->respondWithArray($rootScope->toArray());
159
    }
160
161
    /**
162
     * Returns an array of Query Parameters, not including pagination.
163
     *
164
     * @return array
165
     */
166
    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...
167
    {
168
        return array_diff_key($_GET, array_flip(['page']));
169
    }
170
171
    /**
172
     * Returns a json response that contains the specified array,
173
     * the current status code and optional headers.
174
     *
175
     * @param array $array
176
     * @param array $headers
177
     * @return \Illuminate\Http\JsonResponse
178
     */
179
    protected function respondWithArray(array $array, array $headers = [])
180
    {
181
        return response()->json($array, $this->statusCode, $headers);
182
    }
183
184
    /**
185
     * Returns a response that indicates success but no content returned.
186
     *
187
     * @return \Illuminate\Http\Response
188
     */
189
    protected function respondWithNoContent()
190
    {
191
        return response()->make('', 204);
192
    }
193
}
194