FormAbstract::new()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 19
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 12
dl 0
loc 19
rs 9.8666
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace AbterPhp\Admin\Http\Controllers\Admin;
6
7
use AbterPhp\Admin\Form\Factory\IFormFactory;
8
use AbterPhp\Framework\Constant\Event;
9
use AbterPhp\Framework\Constant\Session;
10
use AbterPhp\Framework\Domain\Entities\IStringerEntity;
11
use AbterPhp\Framework\Events\FormReady;
12
use AbterPhp\Framework\I18n\ITranslator;
13
use AbterPhp\Framework\Orm\IGridRepo;
14
use AbterPhp\Framework\Session\FlashService;
15
use Casbin\Exceptions\CasbinException;
16
use Opulence\Events\Dispatchers\IEventDispatcher;
17
use Opulence\Http\Requests\RequestMethods;
18
use Opulence\Http\Responses\Response;
19
use Opulence\Orm\OrmException;
20
use Opulence\Routing\Urls\URLException;
21
use Opulence\Routing\Urls\UrlGenerator;
22
use Opulence\Sessions\ISession;
23
use Psr\Log\LoggerInterface;
24
use Throwable;
25
26
abstract class FormAbstract extends AdminAbstract
27
{
28
    public const LOG_MSG_LOAD_FAILURE = 'Loading %1$s failed.';
29
30
    public const ENTITY_TITLE_SINGULAR = '';
31
32
    public const VIEW_FORM = 'contents/backend/form';
33
34
    public const VAR_ENTITY = 'entity';
35
    public const VAR_FORM   = 'form';
36
37
    public const TITLE_NEW  = 'framework:titleNew';
38
    public const TITLE_EDIT = 'framework:titleEdit';
39
40
    public const URL_NEW = '%s-new';
41
42
    public const RESOURCE_DEFAULT = '%s-form';
43
    public const RESOURCE_HEADER  = '%s-header-form';
44
    public const RESOURCE_FOOTER  = '%s-footer-form';
45
    public const RESOURCE_TYPE    = 'form';
46
47
    protected IGridRepo $repo;
48
49
    protected ISession $session;
50
51
    protected IFormFactory $formFactory;
52
53
    protected IEventDispatcher $eventDispatcher;
54
55
    /**
56
     * FormAbstract constructor.
57
     *
58
     * @param FlashService     $flashService
59
     * @param LoggerInterface  $logger
60
     * @param ITranslator      $translator
61
     * @param UrlGenerator     $urlGenerator
62
     * @param IGridRepo        $repo
63
     * @param ISession         $session
64
     * @param IFormFactory     $formFactory
65
     * @param IEventDispatcher $eventDispatcher
66
     */
67
    public function __construct(
68
        FlashService $flashService,
69
        LoggerInterface $logger,
70
        ITranslator $translator,
71
        UrlGenerator $urlGenerator,
72
        IGridRepo $repo,
73
        ISession $session,
74
        IFormFactory $formFactory,
75
        IEventDispatcher $eventDispatcher
76
    ) {
77
        parent::__construct($flashService, $logger, $translator, $urlGenerator);
78
79
        $this->repo            = $repo;
80
        $this->session         = $session;
81
        $this->formFactory     = $formFactory;
82
        $this->eventDispatcher = $eventDispatcher;
83
    }
84
85
    /**
86
     * @return Response
87
     * @throws CasbinException
88
     * @throws URLException
89
     * @throws Throwable
90
     */
91
    public function new(): Response
92
    {
93
        $entity = $this->createEntity('');
94
95
        $url   = $this->urlGenerator->createFromName(sprintf(static::URL_NEW, static::ENTITY_PLURAL));
96
        $title = $this->translator->translate(static::TITLE_NEW, static::ENTITY_TITLE_SINGULAR);
97
        $form  = $this->formFactory->create($url, RequestMethods::POST, $this->getShowUrl(), $entity);
98
99
        $form->setTranslator($this->translator);
100
101
        $this->eventDispatcher->dispatch(Event::FORM_READY, new FormReady($form));
102
103
        $this->view = $this->viewFactory->createView(static::VIEW_FORM);
104
        $this->view->setVar(static::VAR_ENTITY, $entity);
105
        $this->view->setVar(static::VAR_FORM, $form);
106
107
        $this->addCustomAssets($entity);
108
109
        return $this->createResponse($title);
110
    }
111
112
    /**
113
     * @param string $entityId
114
     *
115
     * @return Response
116
     * @throws CasbinException
117
     * @throws URLException
118
     * @throws Throwable
119
     */
120
    public function edit(string $entityId): Response
121
    {
122
        $entity = $this->retrieveEntity($entityId);
123
124
        $url   = $this->getEditUrl($entityId);
125
        $title = $this->translator->translate(static::TITLE_EDIT, static::ENTITY_TITLE_SINGULAR, (string)$entity);
126
        $form  = $this->formFactory->create($url, RequestMethods::PUT, $this->getShowUrl(), $entity);
127
128
        $this->eventDispatcher->dispatch(Event::FORM_READY, new FormReady($form));
129
130
        $form->setTranslator($this->translator);
131
132
        $this->view = $this->viewFactory->createView(sprintf(static::VIEW_FORM, strtolower(static::ENTITY_SINGULAR)));
133
        $this->view->setVar(static::VAR_ENTITY, $entity);
134
        $this->view->setVar(static::VAR_FORM, $form);
135
136
        $this->addCustomAssets($entity);
137
138
        return $this->createResponse($title);
139
    }
140
141
    /**
142
     * @param string $entityId
143
     *
144
     * @return IStringerEntity
145
     */
146
    public function retrieveEntity(string $entityId): IStringerEntity
147
    {
148
        $flashService = $this->flashService;
149
150
        try {
151
            /** @var IStringerEntity $entity */
152
            $entity = $this->repo->getById($entityId);
153
        } catch (OrmException $e) {
154
            $errorMessage = $this->getMessage(static::ENTITY_LOAD_FAILURE);
155
156
            $flashService->mergeErrorMessages([$errorMessage]);
157
158
            $this->logger->info(
159
                sprintf(static::LOG_MSG_LOAD_FAILURE, static::ENTITY_SINGULAR),
160
                $this->getExceptionContext($e)
161
            );
162
163
            return $this->createEntity('');
164
        }
165
166
        return $entity;
167
    }
168
169
    /**
170
     * @param string $entityEntityId
171
     *
172
     * @return IStringerEntity
173
     */
174
    abstract protected function createEntity(string $entityEntityId): IStringerEntity;
175
176
    /**
177
     * @return string
178
     * @throws URLException
179
     */
180
    protected function getShowUrl(): string
181
    {
182
        if ($this->session->has(Session::LAST_GRID_URL)) {
183
            return (string)$this->session->get(Session::LAST_GRID_URL);
184
        }
185
186
        return $this->urlGenerator->createFromName(static::ROUTING_PATH);
187
    }
188
189
    /**
190
     * @param string $id
191
     *
192
     * @return string
193
     * @throws URLException
194
     */
195
    protected function getEditUrl(string $id): string
196
    {
197
        $routeName = sprintf(static::URL_EDIT, static::ROUTING_PATH);
198
199
        return $this->urlGenerator->createFromName($routeName, $id);
200
    }
201
202
    /**
203
     * @param string $messageType
204
     *
205
     * @return string
206
     */
207
    protected function getMessage(string $messageType)
208
    {
209
        $entityName = $this->translator->translate(static::ENTITY_TITLE_SINGULAR);
210
211
        return $this->translator->translate($messageType, $entityName);
212
    }
213
}
214