GracefulProcessor   A
last analyzed

Complexity

Total Complexity 7

Size/Duplication

Total Lines 92
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 32
dl 0
loc 92
rs 10
c 0
b 0
f 0
wmc 7

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A process() 0 18 4
A getErrorMessage() 0 10 1
A getDefinitionErrorTca() 0 15 1
1
<?php
2
declare(strict_types=1);
3
4
/*
5
 * Copyright (C)
6
 * Nathan Boiron <[email protected]>
7
 * Romain Canon <[email protected]>
8
 *
9
 * This file is part of the TYPO3 NotiZ project.
10
 * It is free software; you can redistribute it and/or modify it
11
 * under the terms of the GNU General Public License, either
12
 * version 3 of the License, or any later version.
13
 *
14
 * For the full copyright and license information, see:
15
 * http://www.gnu.org/licenses/gpl-3.0.html
16
 */
17
18
namespace CuyZ\Notiz\Core\Notification\TCA\Processor;
19
20
use CuyZ\Notiz\Core\Definition\DefinitionService;
21
use CuyZ\Notiz\Service\Container;
22
use CuyZ\Notiz\Service\ViewService;
23
use Throwable;
24
use TYPO3\CMS\Core\SingletonInterface;
25
use TYPO3\CMS\Core\Utility\ArrayUtility;
26
use TYPO3\CMS\Core\Utility\GeneralUtility;
27
28
/**
29
 * This processor must be used to complete the TCA of entity notifications, for
30
 * parts that require complex logic that may be failing under certain
31
 * circumstances (meaning an exception can be thrown for any reason).
32
 *
33
 * The goal is to apply this kind of logic after the TCA tree has been generated
34
 * and put in cache, because if something fails it would crash for the whole
35
 * backend.
36
 *
37
 * Using this graceful processor, if something breaks during the execution of
38
 * the child processor, the error is caught in order to prevent showing the
39
 * fatal error to the user; instead, a message is displayed with some
40
 * information about the exception.
41
 */
42
abstract class GracefulProcessor implements SingletonInterface
43
{
44
    /**
45
     * @var DefinitionService
46
     */
47
    protected $definitionService;
48
49
    /**
50
     * @var ViewService
51
     */
52
    private $viewService;
53
54
    /**
55
     * Manual dependency injection.
56
     */
57
    public function __construct()
58
    {
59
        $this->definitionService = Container::get(DefinitionService::class);
60
        $this->viewService = Container::get(ViewService::class);
61
    }
62
63
    /**
64
     * @param string $tableName
65
     * @throws Throwable
66
     */
67
    final public function process(string $tableName)
68
    {
69
        if ($this->definitionService->getValidationResult()->hasErrors()) {
70
            return;
71
        }
72
73
        $exception = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $exception is dead and can be removed.
Loading history...
74
75
        try {
76
            $this->doProcess($tableName);
77
        } catch (Throwable $exception) {
78
            if (GeneralUtility::_GET('showException')) {
79
                throw $exception;
80
            }
81
82
            ArrayUtility::mergeRecursiveWithOverrule(
83
                $GLOBALS['TCA'][$tableName],
84
                $this->getDefinitionErrorTca($exception)
85
            );
86
        }
87
    }
88
89
    /**
90
     * @param string $tableName
91
     */
92
    abstract protected function doProcess(string $tableName);
93
94
    /**
95
     * @param Throwable $exception
96
     * @return array
97
     */
98
    private function getDefinitionErrorTca(Throwable $exception): array
99
    {
100
        return [
101
            'types' => [
102
                '0' => [
103
                    'showitem' => 'error_message',
104
                ],
105
            ],
106
            'columns' => [
107
                'error_message' => [
108
                    'config' => [
109
                        'type' => 'user',
110
                        'userFunc' => static::class . '->getErrorMessage',
111
                        'parameters' => [
112
                            'exception' => $exception,
113
                        ]
114
                    ],
115
                ],
116
            ],
117
        ];
118
    }
119
120
    /**
121
     * @param array $arguments
122
     * @return string
123
     */
124
    public function getErrorMessage($arguments): string
125
    {
126
        $view = $this->viewService->getStandaloneView('Backend/TCA/ErrorMessage');
127
128
        $frameSrc = GeneralUtility::getIndpEnv('REQUEST_URI') . '&showException=1';
129
130
        $view->assign('frameSrc', $frameSrc);
131
        $view->assign('exception', $arguments['parameters']['exception']);
132
133
        return $view->render();
134
    }
135
}
136