Passed
Pull Request — master (#146)
by Romain
03:47
created

GracefulProvider::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
rs 10
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\Backend\FormEngine\DataProvider;
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\Backend\Form\FormDataProviderInterface;
25
use TYPO3\CMS\Core\Utility\ArrayUtility;
26
use TYPO3\CMS\Core\Utility\GeneralUtility;
27
28
/**
29
 * This provider 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 provider, if something breaks during the execution of the
38
 * child provider, the error is caught in order to prevent showing the fatal
39
 * error to the user; instead, a message is displayed with some information about
40
 * the exception.
41
 */
42
abstract class GracefulProvider implements FormDataProviderInterface
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 array $result
65
     * @return array
66
     * @throws Throwable
67
     */
68
    final public function addData(array $result)
69
    {
70
        if ($this->definitionService->getValidationResult()->hasErrors()) {
71
            return $result;
72
        }
73
74
        try {
75
            return $this->process($result);
76
        } catch (Throwable $exception) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
77
        } catch (Exception $exception) {
78
            // @PHP7
79
        }
80
81
        if ($exception) {
82
            if (GeneralUtility::_GET('showException')) {
83
                throw $exception;
84
            }
85
86
            ArrayUtility::mergeRecursiveWithOverrule(
87
                $GLOBALS['TCA'][$result['tableName']],
88
                $this->getDefinitionErrorTca($exception)
89
            );
90
        }
91
92
        return $result;
93
    }
94
95
    /**
96
     * @param array $result
97
     * @return array
98
     */
99
    abstract protected function process(array $result);
100
101
    /**
102
     * @param Throwable $exception
103
     * @return array
104
     */
105
    private function getDefinitionErrorTca($exception)
106
    {
107
        return [
108
            'types' => [
109
                '0' => [
110
                    'showitem' => 'error_message',
111
                ],
112
            ],
113
            'columns' => [
114
                'error_message' => [
115
                    'config' => [
116
                        'type' => 'user',
117
                        'userFunc' => static::class . '->getErrorMessage',
118
                        'parameters' => [
119
                            'exception' => $exception,
120
                        ]
121
                    ],
122
                ],
123
            ],
124
        ];
125
    }
126
127
    /**
128
     * @param array $arguments
129
     * @return string
130
     */
131
    public function getErrorMessage($arguments)
132
    {
133
        $view = $this->viewService->getStandaloneView('Backend/TCA/ErrorMessage');
134
135
        $frameSrc = GeneralUtility::getIndpEnv('REQUEST_URI') . '&showException=1';
136
137
        $view->assign('frameSrc', $frameSrc);
138
        $view->assign('exception', $arguments['parameters']['exception']);
139
140
        return $view->render();
141
    }
142
}
143