Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
84.09% |
37 / 44 |
|
66.67% |
2 / 3 |
CRAP | |
0.00% |
0 / 1 |
FormCommitController | |
84.09% |
37 / 44 |
|
66.67% |
2 / 3 |
14.79 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
__invoke | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
1 | |||
createResponse | |
82.05% |
32 / 39 |
|
0.00% |
0 / 1 |
12.83 |
1 | <?php |
2 | namespace Apie\Cms\Controllers; |
3 | |
4 | use Apie\Cms\Services\ResponseFactory; |
5 | use Apie\Common\ApieFacade; |
6 | use Apie\Core\Actions\ActionResponse; |
7 | use Apie\Core\Actions\ActionResponseStatus; |
8 | use Apie\Core\BoundedContext\BoundedContextHashmap; |
9 | use Apie\Core\BoundedContext\BoundedContextId; |
10 | use Apie\Core\ContextBuilders\ContextBuilderFactory; |
11 | use Apie\Core\ContextConstants; |
12 | use Apie\Core\Entities\EntityInterface; |
13 | use Apie\Core\Identifiers\UuidV4; |
14 | use Apie\HtmlBuilders\Configuration\ApplicationConfiguration; |
15 | use Apie\Serializer\Exceptions\ValidationException; |
16 | use Psr\Http\Message\ResponseInterface; |
17 | use Psr\Http\Message\ServerRequestInterface; |
18 | use ReflectionClass; |
19 | use Symfony\Component\HttpFoundation\Session\SessionInterface; |
20 | |
21 | class FormCommitController |
22 | { |
23 | public function __construct( |
24 | protected readonly ContextBuilderFactory $contextBuilderFactory, |
25 | private readonly ApieFacade $apieFacade, |
26 | private readonly ApplicationConfiguration $applicationConfiguration, |
27 | private readonly BoundedContextHashmap $boundedContextHashmap, |
28 | private readonly ResponseFactory $responseFactory, |
29 | ) { |
30 | } |
31 | |
32 | public function __invoke(ServerRequestInterface $request): ResponseInterface |
33 | { |
34 | $context = $this->contextBuilderFactory->createFromRequest($request, [ContextConstants::CMS => true]); |
35 | $action = $this->apieFacade->createAction($context); |
36 | $data = ($action)($context, $context->getContext(ContextConstants::RAW_CONTENTS)); |
37 | return $this->createResponse($request, $data); |
38 | } |
39 | |
40 | /** |
41 | * Creates redirect response and stores a few things in the session. It redirects to the most sensible layout. |
42 | * If the action gave an error: |
43 | * - store validation errors and the filled in values in the session |
44 | * - redirect to the same uri again. |
45 | * If the action succeeded: |
46 | * - remove values in the session |
47 | * - redirect to if applicable: |
48 | * - resource/<resource>/<id> |
49 | * - resource/<resource> |
50 | * - last-action-result/<result-id> |
51 | */ |
52 | protected function createResponse(ServerRequestInterface $request, ActionResponse $output): ResponseInterface |
53 | { |
54 | if ($output->result instanceof ResponseInterface) { |
55 | return $output->result; |
56 | } |
57 | $configuration = $this->applicationConfiguration->createConfiguration( |
58 | $output->apieContext, |
59 | $this->boundedContextHashmap, |
60 | new BoundedContextId($output->apieContext->getContext(ContextConstants::BOUNDED_CONTEXT_ID)) |
61 | ); |
62 | |
63 | $redirectUrl = (string) $request->getUri(); |
64 | $session = $output->apieContext->getContext(SessionInterface::class); |
65 | assert($session instanceof SessionInterface); |
66 | if ($output->getStatusCode() < 300) { |
67 | $session->remove('_filled_in'); |
68 | $session->remove('_validation_errors'); |
69 | if ($output->apieContext->hasContext(ContextConstants::RESOURCE_NAME)) { |
70 | $class = new ReflectionClass($output->apieContext->getContext(ContextConstants::RESOURCE_NAME)); |
71 | $redirectUrl = $configuration->getContextUrl('resource/' . $class->getShortName()); |
72 | if ($output->apieContext->hasContext(ContextConstants::RESOURCE_ID) && $output->status !== ActionResponseStatus::DELETED) { |
73 | $redirectUrl = $configuration->getContextUrl( |
74 | 'resource/' . $class->getShortName() . '/' . $output->apieContext->getContext(ContextConstants::RESOURCE_ID) |
75 | ); |
76 | } |
77 | } |
78 | if (isset($output->result) && $output->status !== ActionResponseStatus::DELETED) { |
79 | if ($output->result instanceof EntityInterface) { |
80 | $baseClass = $output->result->getId()::getReferenceFor(); |
81 | $redirectUrl = $configuration->getContextUrl( |
82 | 'resource/' . $baseClass->getShortName() . '/' . $output->result->getId()->toNative() |
83 | ); |
84 | } else { |
85 | $previousResults = $session->get('_output_results', []); |
86 | $uniqueId = UuidV4::createRandom()->toNative(); |
87 | $previousResults[$uniqueId] = $output->result; |
88 | $session->set('_output_results', $previousResults); |
89 | $redirectUrl = $configuration->getContextUrl('last-action-result/' . $uniqueId); |
90 | } |
91 | } |
92 | } |
93 | |
94 | if (isset($output->error) && $output->apieContext->hasContext(SessionInterface::class)) { |
95 | $contents = $output->apieContext->getContext(ContextConstants::RAW_CONTENTS); |
96 | unset($contents['_csrf']); |
97 | $session->set('_filled_in', $contents); |
98 | |
99 | if ( |
100 | $output->error instanceof ValidationException |
101 | ) { |
102 | $session->set('_validation_errors', $output->error->getErrors()->toArray()); |
103 | } else { |
104 | $session->set('_validation_errors', ['' => $output->error->getMessage()]); |
105 | } |
106 | } |
107 | |
108 | return $this->responseFactory->createRedirect($redirectUrl, $output->apieContext); |
109 | } |
110 | } |