Passed
Push — master ( 7a68ca...706354 )
by Peter
08:27 queued 01:17
created

ExecuteAbstract::getEditUrl()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 7
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace AbterPhp\Admin\Http\Controllers\Admin;
6
7
use AbterPhp\Framework\Constant\Session;
8
use AbterPhp\Framework\Domain\Entities\IStringerEntity;
9
use AbterPhp\Framework\Form\Extra\DefaultButtons;
10
use AbterPhp\Framework\Http\Service\Execute\IRepoService;
11
use AbterPhp\Framework\I18n\ITranslator;
12
use AbterPhp\Framework\Session\FlashService;
13
use Casbin\Exceptions\CasbinException;
14
use Opulence\Http\Responses\RedirectResponse;
15
use Opulence\Http\Responses\Response;
16
use Opulence\Orm\OrmException;
17
use Opulence\Routing\Urls\URLException;
18
use Opulence\Routing\Urls\UrlGenerator;
19
use Opulence\Sessions\ISession;
20
use Psr\Log\LoggerInterface;
21
22
abstract class ExecuteAbstract extends AdminAbstract
23
{
24
    const INPUT_NEXT = 'next';
25
26
    const URL_CREATE = '%s-create';
27
28
    const CREATE_SUCCESS = 'framework:create-success';
29
    const CREATE_FAILURE = 'framework:create-failure';
30
    const UPDATE_SUCCESS = 'framework:update-success';
31
    const UPDATE_FAILURE = 'framework:update-failure';
32
    const DELETE_SUCCESS = 'framework:delete-success';
33
    const DELETE_FAILURE = 'framework:delete-failure';
34
35
    const LOG_MSG_CREATE_FAILURE = 'Creating %1$s failed.';
36
    const LOG_MSG_CREATE_SUCCESS = 'Creating %1$s was successful.';
37
    const LOG_MSG_UPDATE_FAILURE = 'Updating %1$s with id "%2$s" failed.';
38
    const LOG_MSG_UPDATE_SUCCESS = 'Updating %1$s with id "%2$s" was successful.';
39
    const LOG_MSG_DELETE_FAILURE = 'Deleting %1$s with id "%2$s" failed.';
40
    const LOG_MSG_DELETE_SUCCESS = 'Deleting %1$s with id "%2$s" was successful.';
41
42
    const ENTITY_TITLE_SINGULAR = '';
43
    const ENTITY_TITLE_PLURAL   = '';
44
45
    /** @var IRepoService */
46
    protected $repoService;
47
48
    /** @var ISession */
49
    protected $session;
50
51
    /**
52
     * ExecuteAbstract constructor.
53
     *
54
     * @param FlashService    $flashService
55
     * @param ITranslator     $translator
56
     * @param UrlGenerator    $urlGenerator
57
     * @param LoggerInterface $logger
58
     * @param IRepoService    $repoService
59
     * @param ISession        $session
60
     */
61
    public function __construct(
62
        FlashService $flashService,
63
        ITranslator $translator,
64
        UrlGenerator $urlGenerator,
65
        LoggerInterface $logger,
66
        IRepoService $repoService,
67
        ISession $session
68
    ) {
69
        parent::__construct($flashService, $translator, $urlGenerator, $logger);
70
71
        $this->repoService = $repoService;
72
        $this->session     = $session;
73
    }
74
75
    /**
76
     * @return Response
77
     * @throws CasbinException
78
     * @throws OrmException
79
     * @throws URLException
80
     * @throws \Throwable
81
     */
82
    public function create(): Response
83
    {
84
        $postData = $this->getPostData();
85
        $fileData = $this->getFileData();
86
87
        $errors = $this->repoService->validateForm(array_merge($postData, $fileData));
88
89
        if (count($errors) > 0) {
90
            $this->flashService->mergeErrorMessages($errors);
91
            $this->logger->info(sprintf(static::LOG_MSG_CREATE_FAILURE, static::ENTITY_SINGULAR), $errors);
92
93
            return $this->redirectToNext();
94
        }
95
96
        try {
97
            $entity = $this->repoService->create($postData, $fileData);
98
99
            $this->logger->info(sprintf(static::LOG_MSG_CREATE_SUCCESS, static::ENTITY_SINGULAR));
100
            $this->flashService->mergeSuccessMessages([$this->getMessage(static::CREATE_SUCCESS)]);
101
        } catch (\Exception $e) {
102
            $this->flashService->mergeErrorMessages([$this->getMessage(static::CREATE_FAILURE)]);
103
            $this->logger->info(
104
                sprintf(static::LOG_MSG_CREATE_FAILURE, static::ENTITY_SINGULAR),
105
                $this->getExceptionContext($e)
106
            );
107
108
            return $this->redirectToNext();
109
        }
110
111
        return $this->redirectToNext($entity);
112
    }
113
114
    /**
115
     * @param string $entityId
116
     *
117
     * @return Response
118
     * @throws CasbinException
119
     * @throws OrmException
120
     * @throws URLException
121
     * @throws \Throwable
122
     */
123
    public function update(string $entityId): Response
124
    {
125
        $postData = $this->getPostData();
126
        $fileData = $this->getFileData();
127
128
        $errors = $this->repoService->validateForm(array_merge($postData, $fileData));
129
130
        try {
131
            $entity = $this->repoService->retrieveEntity($entityId);
132
        } catch (OrmException $e) {
133
            return $this->redirectToNext();
134
        }
135
136
        if (count($errors) > 0) {
137
            $this->logger->info(sprintf(static::LOG_MSG_UPDATE_FAILURE, static::ENTITY_SINGULAR, $entityId), $errors);
138
            $this->flashService->mergeErrorMessages($errors);
139
140
            return $this->redirectToNext($entity);
141
        }
142
143
        try {
144
            $this->repoService->update($entity, $postData, $fileData);
145
            $this->logger->info(sprintf(static::LOG_MSG_UPDATE_SUCCESS, static::ENTITY_SINGULAR, $entityId));
146
            $this->flashService->mergeSuccessMessages([$this->getMessage(static::UPDATE_SUCCESS)]);
147
        } catch (\Exception $e) {
148
            $this->logger->error(
149
                sprintf(static::LOG_MSG_UPDATE_FAILURE, static::ENTITY_SINGULAR, $entityId),
150
                $this->getExceptionContext($e)
151
            );
152
            $this->flashService->mergeErrorMessages([$this->getMessage(static::UPDATE_FAILURE)]);
153
        }
154
155
        return $this->redirectToNext($entity);
156
    }
157
158
    /**
159
     * @param string $entityId
160
     *
161
     * @return Response
162
     * @throws CasbinException
163
     * @throws OrmException
164
     * @throws URLException
165
     * @throws \Throwable
166
     */
167
    public function delete(string $entityId): Response
168
    {
169
        $entity = $this->repoService->retrieveEntity($entityId);
170
171
        try {
172
            $this->repoService->delete($entity);
173
            $this->logger->info(sprintf(static::LOG_MSG_DELETE_SUCCESS, static::ENTITY_SINGULAR, $entityId));
174
            $this->flashService->mergeSuccessMessages([$this->getMessage(static::DELETE_SUCCESS)]);
175
        } catch (\Exception $e) {
176
            $this->logger->error(
177
                sprintf(static::LOG_MSG_DELETE_FAILURE, static::ENTITY_SINGULAR, $entityId),
178
                [static::LOG_CONTEXT_EXCEPTION => $e->getMessage()]
179
            );
180
            $this->flashService->mergeErrorMessages([$this->getMessage(static::DELETE_FAILURE)]);
181
        }
182
183
        return $this->redirectToNext();
184
    }
185
186
    /**
187
     * @return array
188
     */
189
    protected function getPostData(): array
190
    {
191
        $postData = $this->request->getPost()->getAll();
192
193
        return $postData;
194
    }
195
196
    /**
197
     * @return array
198
     */
199
    protected function getFileData(): array
200
    {
201
        $fileData = $this->request->getFiles()->getAll();
202
203
        return $fileData;
204
    }
205
206
    /**
207
     * @param IStringerEntity|null $entity
208
     *
209
     * @return Response
210
     * @throws URLException
211
     */
212
    protected function redirectToNext(?IStringerEntity $entity = null): Response
213
    {
214
        $next = $this->request->getInput(static::INPUT_NEXT, DefaultButtons::BTN_VALUE_NEXT_BACK);
215
216
        $entityId = $entity ? $entity->getId() : null;
217
218
        $url = $this->getUrl($next, $entityId);
219
220
        $response = new RedirectResponse($url);
221
        $response->send();
222
223
        return $response;
224
    }
225
226
    /**
227
     * @param string      $next
228
     * @param string|null $entityId
229
     *
230
     * @return string
231
     * @throws URLException
232
     */
233
    protected function getUrl(string $next, string $entityId = null)
234
    {
235
        switch ($next) {
236
            case DefaultButtons::BTN_VALUE_NEXT_BACK:
237
                return $this->getShowUrl();
238
            case DefaultButtons::BTN_VALUE_NEXT_EDIT:
239
                if (null === $entityId) {
240
                    return $this->getCreateUrl();
241
                }
242
243
                return $this->getEditUrl($entityId);
244
            case DefaultButtons::BTN_VALUE_NEXT_CREATE:
245
                return $this->getCreateUrl();
246
        }
247
248
        return $this->getCreateUrl();
249
    }
250
251
    /**
252
     * @return string
253
     * @throws URLException
254
     */
255
    protected function getCreateUrl(): string
256
    {
257
        $urlName = strtolower(sprintf(static::URL_CREATE, static::ROUTING_PATH));
258
        $url     = $this->urlGenerator->createFromName($urlName);
259
260
        return $url;
261
    }
262
263
    /**
264
     * @return string
265
     * @throws URLException
266
     */
267
    protected function getShowUrl(): string
268
    {
269
        if ($this->session->has(Session::LAST_GRID_URL)) {
270
            return (string)$this->session->get(Session::LAST_GRID_URL);
271
        }
272
273
        $url = $this->urlGenerator->createFromName(static::ROUTING_PATH);
274
275
        return $url;
276
    }
277
278
    /**
279
     * @param string $id
280
     *
281
     * @return string
282
     * @throws URLException
283
     */
284
    protected function getEditUrl(string $id): string
285
    {
286
        $routeName = sprintf(static::URL_EDIT, static::ROUTING_PATH);
287
288
        $url = $this->urlGenerator->createFromName($routeName, $id);
289
290
        return $url;
291
    }
292
293
    /**
294
     * @param string $messageType
295
     *
296
     * @return string
297
     */
298
    protected function getMessage(string $messageType)
299
    {
300
        $entityName = $this->translator->translate(static::ENTITY_TITLE_SINGULAR);
301
302
        return $this->translator->translate($messageType, $entityName);
303
    }
304
}
305