Passed
Push — master ( f85738...3d85c1 )
by Peter
04:52
created

ExecuteAbstract   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 241
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 20
eloc 97
dl 0
loc 241
rs 10
c 0
b 0
f 0

9 Methods

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