Passed
Push — master ( 9fba3d...a339bf )
by Romain
03:49
created

GracefulProcessor::getDefinitionErrorTca()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 15
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 11
nc 1
nop 1
dl 0
loc 15
rs 9.9
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * Copyright (C) 2018
5
 * Nathan Boiron <[email protected]>
6
 * Romain Canon <[email protected]>
7
 *
8
 * This file is part of the TYPO3 NotiZ project.
9
 * It is free software; you can redistribute it and/or modify it
10
 * under the terms of the GNU General Public License, either
11
 * version 3 of the License, or any later version.
12
 *
13
 * For the full copyright and license information, see:
14
 * http://www.gnu.org/licenses/gpl-3.0.html
15
 */
16
17
namespace CuyZ\Notiz\Core\Notification\TCA\Processor;
18
19
use CuyZ\Notiz\Core\Definition\DefinitionService;
20
use CuyZ\Notiz\Service\Container;
21
use CuyZ\Notiz\Service\ViewService;
22
use Exception;
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($tableName)
68
    {
69
        if ($this->definitionService->getValidationResult()->hasErrors()) {
70
            return;
71
        }
72
73
        $exception = null;
74
75
        try {
76
            $this->doProcess($tableName);
77
        } catch (Throwable $exception) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
78
        } catch (Exception $exception) {
79
            // @PHP7
80
        }
81
82
        if ($exception) {
83
            if (GeneralUtility::_GET('showException')) {
84
                throw $exception;
85
            }
86
87
            ArrayUtility::mergeRecursiveWithOverrule(
88
                $GLOBALS['TCA'][$tableName],
89
                $this->getDefinitionErrorTca($exception)
90
            );
91
        }
92
    }
93
94
    /**
95
     * @param string $tableName
96
     */
97
    abstract protected function doProcess($tableName);
98
99
    /**
100
     * @param Throwable $exception
101
     * @return array
102
     */
103
    private function getDefinitionErrorTca($exception)
104
    {
105
        return [
106
            'types' => [
107
                '0' => [
108
                    'showitem' => 'error_message',
109
                ],
110
            ],
111
            'columns' => [
112
                'error_message' => [
113
                    'config' => [
114
                        'type' => 'user',
115
                        'userFunc' => static::class . '->getErrorMessage',
116
                        'parameters' => [
117
                            'exception' => $exception,
118
                        ]
119
                    ],
120
                ],
121
            ],
122
        ];
123
    }
124
125
    /**
126
     * @param array $arguments
127
     * @return string
128
     */
129
    public function getErrorMessage($arguments)
130
    {
131
        $view = $this->viewService->getStandaloneView('Backend/TCA/ErrorMessage');
132
133
        $frameSrc = GeneralUtility::getIndpEnv('REQUEST_URI') . '&showException=1';
134
135
        $view->assign('frameSrc', $frameSrc);
136
        $view->assign('exception', $arguments['parameters']['exception']);
137
138
        return $view->render();
139
    }
140
}
141