Passed
Push — master ( 4bc322...e35e92 )
by Peter
04:39
created

ApiAbstract::handleException()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 5
nc 1
nop 2
dl 0
loc 11
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace AbterPhp\Framework\Http\Controllers\Admin;
6
7
use AbterPhp\Framework\Http\Service\Execute\RepoServiceAbstract;
8
use Opulence\Http\Responses\Response;
9
use Opulence\Http\Responses\ResponseHeaders;
10
use Opulence\Routing\Controller;
11
use Psr\Log\LoggerInterface;
12
13
abstract class ApiAbstract extends Controller
14
{
15
    const LOG_MSG_CREATE_FAILURE = 'Creating %1$s failed.';
16
    const LOG_MSG_CREATE_SUCCESS = 'Creating %1$s was successful.';
17
    const LOG_MSG_UPDATE_FAILURE = 'Updating %1$s with id "%2$s" failed.';
18
    const LOG_MSG_UPDATE_SUCCESS = 'Updating %1$s with id "%2$s" was successful.';
19
    const LOG_MSG_DELETE_FAILURE = 'Deleting %1$s with id "%2$s" failed.';
20
    const LOG_MSG_DELETE_SUCCESS = 'Deleting %1$s with id "%2$s" was successful.';
21
22
    const LOG_CONTEXT_EXCEPTION  = 'Exception';
23
    const LOG_PREVIOUS_EXCEPTION = 'Previous exception #%d';
24
25
    const ENTITY_TITLE_SINGULAR = '';
26
    const ENTITY_TITLE_PLURAL   = '';
27
28
    /** @var LoggerInterface */
29
    protected $logger;
30
31
    /** @var RepoService */
0 ignored issues
show
Bug introduced by
The type AbterPhp\Framework\Http\...llers\Admin\RepoService was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
32
    protected $repoService;
33
34
    /**
35
     * ApiAbstract constructor.
36
     *
37
     * @param LoggerInterface     $logger
38
     * @param RepoServiceAbstract $repoService
39
     */
40
    public function __construct(LoggerInterface $logger, RepoServiceAbstract $repoService)
41
    {
42
        $this->logger      = $logger;
43
        $this->repoService = $repoService;
0 ignored issues
show
Documentation Bug introduced by
It seems like $repoService of type AbterPhp\Framework\Http\...ute\RepoServiceAbstract is incompatible with the declared type AbterPhp\Framework\Http\...llers\Admin\RepoService of property $repoService.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
44
    }
45
46
    /**
47
     * @return Response
48
     */
49
    public function create(): Response
50
    {
51
        $data = $this->getCreateData();
52
53
        $errors = $this->repoService->validateForm($data);
54
55
        if (count($errors) > 0) {
56
            $msg = sprintf(static::LOG_MSG_CREATE_FAILURE, static::ENTITY_SINGULAR);
0 ignored issues
show
Bug introduced by
The constant AbterPhp\Framework\Http\...stract::ENTITY_SINGULAR was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
57
58
            return $this->handleErrors($msg, $errors);
59
        }
60
61
        try {
62
            $entityId = $this->repoService->create($data, []);
63
        } catch (\Exception $e) {
64
            $msg = sprintf(static::LOG_MSG_CREATE_FAILURE, static::ENTITY_SINGULAR);
65
66
            return $this->handleException($msg, $e);
67
        }
68
69
        return $this->handleCreateSuccess($entityId);
70
    }
71
72
    /**
73
     * @param string $entityId
74
     *
75
     * @return Response
76
     */
77
    public function update(string $entityId): Response
78
    {
79
        $data = $this->getUpdateData();
80
81
        $errors = $this->repoService->validateForm($data);
82
83
        if (count($errors) > 0) {
84
            $msg = sprintf(static::LOG_MSG_UPDATE_FAILURE, static::ENTITY_SINGULAR, $entityId);
0 ignored issues
show
Bug introduced by
The constant AbterPhp\Framework\Http\...stract::ENTITY_SINGULAR was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
85
86
            return $this->handleErrors($msg, $errors);
87
        }
88
89
        try {
90
            $this->repoService->update($entityId, $data, []);
91
        } catch (\Exception $e) {
92
            $msg = sprintf(static::LOG_MSG_UPDATE_FAILURE, static::ENTITY_SINGULAR, $entityId);
93
94
            return $this->handleException($msg, $e);
95
        }
96
97
        return $this->handleUpdateSuccess($entityId);
98
    }
99
100
    /**
101
     * @param string $entityId
102
     *
103
     * @return Response
104
     */
105
    public function delete(string $entityId): Response
106
    {
107
        try {
108
            $entityId = $this->repoService->delete($entityId);
109
        } catch (\Exception $e) {
110
            $msg = sprintf(static::LOG_MSG_DELETE_FAILURE, static::ENTITY_SINGULAR, $entityId);
0 ignored issues
show
Bug introduced by
The constant AbterPhp\Framework\Http\...stract::ENTITY_SINGULAR was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
111
112
            return $this->handleException($msg, $e);
113
        }
114
115
        return $this->handleDeleteSuccess($entityId);
116
    }
117
118
    /**
119
     * @return array
120
     */
121
    public function getCreateData(): array
122
    {
123
        return $this->getSharedData();
124
    }
125
126
    /**
127
     * @return array
128
     */
129
    public function getUpdateData(): array
130
    {
131
        return $this->getSharedData();
132
    }
133
134
    /**
135
     * @return array
136
     */
137
    public function getSharedData(): array
138
    {
139
        return $this->request->getJsonBody();
140
    }
141
142
    /**
143
     * @param string $msg
144
     * @param array  $errors
145
     *
146
     * @return Response
147
     */
148
    protected function handleErrors(string $msg, array $errors): Response
149
    {
150
        $this->logger->debug($msg);
151
152
        $response = new Response();
153
154
        $response->setStatusCode(ResponseHeaders::HTTP_BAD_REQUEST);
155
156
        $response->setContent(json_encode(['errors' => $errors]));
157
158
        return $response;
159
    }
160
161
    /**
162
     * @param string     $msg
163
     * @param \Exception $exception
164
     *
165
     * @return Response
166
     */
167
    protected function handleException(string $msg, \Exception $exception): Response
168
    {
169
        $this->logger->error($msg, $this->getExceptionContext($exception));
170
171
        $response = new Response();
172
173
        $response->setStatusCode(ResponseHeaders::HTTP_INTERNAL_SERVER_ERROR);
174
175
        $response->setContent(json_encode(['errors' => [$msg]]));
176
177
        return $response;
178
    }
179
180
    /**
181
     * @param \Exception $exception
182
     *
183
     * @return array
184
     */
185
    protected function getExceptionContext(\Exception $exception): array
186
    {
187
        $result = [static::LOG_CONTEXT_EXCEPTION => $exception->getMessage()];
188
189
        $i = 1;
190
        while ($exception = $exception->getPrevious()) {
191
            $result[sprintf(static::LOG_PREVIOUS_EXCEPTION, $i++)] = $exception->getMessage();
192
        }
193
194
        return $result;
195
    }
196
197
    /**
198
     * @return Response
199
     */
200
    protected function handleCreateSuccess(string $entityId): Response
201
    {
202
        $response = new Response();
203
204
        $response->setStatusCode(ResponseHeaders::HTTP_CREATED);
205
206
        $response->setContent(json_encode(['id' => $entityId]));
207
208
        return $response;
209
    }
210
211
    /**
212
     * @return Response
213
     */
214
    protected function handleUpdateSuccess(string $entityId): Response
215
    {
216
        $response = new Response();
217
218
        $response->setStatusCode(ResponseHeaders::HTTP_OK);
219
220
        $response->setContent(json_encode(['id' => $entityId]));
221
222
        return $response;
223
    }
224
225
    /**
226
     * @return Response
227
     */
228
    protected function handleDeleteSuccess(string $entityId): Response
229
    {
230
        $response = new Response();
231
232
        $response->setStatusCode(ResponseHeaders::HTTP_OK);
233
234
        $response->setContent(json_encode(['id' => $entityId]));
235
236
        return $response;
237
    }
238
}
239