Completed
Push — master ( 64a74a...627385 )
by Pavel
02:37
created

CrudController::actionIndex()   C

Complexity

Conditions 7
Paths 18

Size

Total Lines 28
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 28
rs 6.7272
c 1
b 0
f 0
cc 7
eloc 18
nc 18
nop 3
1
<?php
2
3
namespace App\Controller;
4
5
use App\Common\Helper;
6
use App\Common\JsonException;
7
use App\Scopes\MaxPerPageScope;
8
use Slim\Http\Request;
9
use Slim\Http\Response;
10
11
class CrudController extends BaseController
12
{
13
    /**
14
     * Default page size
15
     */
16
    const DEFAULT_PAGE_SIZE = 15;
17
18
    /**
19
     * @param Request  $request
20
     * @param Response $response
21
     * @param array    $args
22
     *
23
     * @return \Psr\Http\Message\ResponseInterface
24
     */
25
    public function actionIndex(Request $request, Response $response, $args)
26
    {
27
        $modelName = 'App\Model\\'.Helper::dashesToCamelCase($args['entity'], true);
28
        $params    = $request->getQueryParams();
29
        $query     = $modelName::CurrentUser();
30
31
        if (isset($params['withTrashed']) && $params['withTrashed'] == 1) {
32
            $query = $modelName::withTrashed();
33
        }
34
35
        $this->applyFilters($query, $params)
36
            ->applySorters($query, $params)
37
        ;
38
39
        $pageNumber = null;
40
        $pageSize   = null;
41
        if (isset($params['page']['number'])) {
42
            $pageNumber = $params['page']['number'] > 0 ? $params['page']['number'] : 1;
43
            $pageSize   = (isset($params['page']['size']) && $params['page']['size'] <= 100) ? $params['page']['size'] : self::DEFAULT_PAGE_SIZE;
44
            $entities   = $query->withoutGlobalScopes([MaxPerPageScope::class])->paginate($pageSize, ['*'], 'page', $pageNumber);
45
        } else {
46
            $entities = $query->get();
47
        }
48
49
        $result = $this->encoder->encode($request, $entities, $pageNumber, $pageSize);
50
51
        return $this->apiRenderer->jsonResponse($response, 200, $result);
52
    }
53
54
    /**
55
     * @param Request  $request
56
     * @param Response $response
57
     * @param array    $args
58
     *
59
     * @return \Psr\Http\Message\ResponseInterface
60
     * @throws JsonException
61
     */
62
    public function actionGet(Request $request, Response $response, $args)
63
    {
64
        $modelName = 'App\Model\\'.Helper::dashesToCamelCase($args['entity'], true);
65
        $query     = $modelName::CurrentUser();
66
        $entity    = $query->find($args['id']);
67
68
        if (!$entity) {
69
            throw new JsonException($args['entity'], 404, 'Not found', 'Entity not found');
70
        }
71
72
        $result = $this->encoder->encode($request, $entity);
73
74
        return $this->apiRenderer->jsonResponse($response, 200, $result);
75
    }
76
77
    /**
78
     * @param Request  $request
79
     * @param Response $response
80
     * @param array    $args
81
     *
82
     * @return \Psr\Http\Message\ResponseInterface
83
     * @throws JsonException
84
     */
85
    public function actionCreate(Request $request, Response $response, $args)
86
    {
87
        $modelName    = 'App\Model\\'.Helper::dashesToCamelCase($args['entity'], true);
88
        $requestClass = 'App\Requests\\'.Helper::dashesToCamelCase($args['entity'], true).'CreateRequest';
89
        $params       = $request->getParsedBody();
90
91
        $this->validateRequestParams($params, $args['entity'], new $requestClass());
92
93
        $entity = $modelName::create($params['data']['attributes']);
94
        $result = $this->encoder->encode($request, $entity);
95
96
        return $this->apiRenderer->jsonResponse($response, 200, $result);
97
98
    }
99
100
    /**
101
     * @param Request  $request
102
     * @param Response $response
103
     * @param array    $args
104
     *
105
     * @return \Psr\Http\Message\ResponseInterface
106
     * @throws JsonException
107
     */
108
    public function actionUpdate(Request $request, Response $response, $args)
109
    {
110
        $modelName    = 'App\Model\\'.Helper::dashesToCamelCase($args['entity'], true);
111
        $requestClass = 'App\Requests\\'.Helper::dashesToCamelCase($args['entity'], true).'UpdateRequest';
112
        $params       = $request->getParsedBody();
113
        $query        = $modelName::CurrentUser();
114
        $entity       = $query->find($args['id']);
115
116
        if (!$entity) {
117
            throw new JsonException($args['entity'], 404, 'Not found', 'Entity not found');
118
        }
119
120
        $this->validateRequestParams($params, $args['entity'], new $requestClass());
121
122
        $entity->update($params['data']['attributes']);
123
124
        $result = $this->encoder->encode($request, $entity);
125
126
        return $this->apiRenderer->jsonResponse($response, 200, $result);
127
    }
128
129
    /**
130
     * @param Request  $request
131
     * @param Response $response
132
     * @param array    $args
133
     *
134
     * @return \Psr\Http\Message\ResponseInterface
135
     * @throws JsonException
136
     */
137
    public function actionDelete(Request $request, Response $response, $args)
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
138
    {
139
        $modelName = 'App\Model\\'.Helper::dashesToCamelCase($args['entity'], true);
140
        $query     = $modelName::CurrentUser();
141
        $entity    = $query->find($args['id']);
142
143
        if (!$entity) {
144
            throw new JsonException($args['entity'], 404, 'Not found', 'Entity not found');
145
        }
146
147
        $entity->delete();
148
149
        return $this->apiRenderer->jsonResponse($response, 204);
150
    }
151
152
    /**
153
     * @param array  $params
154
     * @param string $key
155
     * @return array|mixed
156
     */
157
    private function getDecodedParams($params, $key)
158
    {
159
        $decoded = [];
160
        if (isset($params[$key])) {
161
            $decoded = json_decode($params[$key], true);
162
            if (json_last_error() !== JSON_ERROR_NONE) {
163
                $decoded = [];
164
            }
165
        }
166
167
        return $decoded;
168
    }
169
170
    /**
171
     * @param $query
172
     * @param $params
173
     * @return $this
174
     */
175
    private function applyFilters($query, $params)
176
    {
177
        $filters = $this->getDecodedParams($params, 'filters');
178
        foreach ($filters as $filter) {
179
            $filter['operator']  = trim(strtolower($filter['operator']));
180
            $filter['attribute'] = trim($filter['attribute']);
181
182
            if (
183
                empty($filter['operator'])
184
                || empty($filter['attribute'])
185
                || !isset($filter['value'])
186
            ) {
187
                continue;
188
            }
189
190
            switch ($filter['operator']) {
191
                case 'in':
192
                    $query = $query->whereIn($filter['attribute'], $filter['value']);
193
                    break;
194
                case 'not in':
195
                    $query = $query->whereNotIn($filter['attribute'], $filter['value']);
196
                    break;
197
                case 'like':
198
                    $query = $query->where($filter['attribute'], 'like', '%'.$filter['value'].'%');
199
                    break;
200
                case '=':
201
                case '!=':
202
                case '>':
203
                case '>=':
204
                case '<':
205
                case '<=':
206
                    $query = $query->where($filter['attribute'], $filter['operator'], $filter['value']);
207
                    break;
208
            }
209
        }
210
211
        return $this;
212
    }
213
214
    /**
215
     * @param $query
216
     * @param $params
217
     * @return $this
218
     */
219
    private function applySorters($query, $params)
220
    {
221
        $sorters = $this->getDecodedParams($params, 'sort');
222
        foreach ($sorters as $sorter) {
223
            $sorter['direction'] = trim(strtolower($sorter['direction'])) == 'asc' ? 'asc' : 'desc';
224
            $query->orderBy(trim($sorter['attribute']), $sorter['direction']);
225
        }
226
227
        return $this;
228
    }
229
}
230