Completed
Push — master ( 1c3343...493201 )
by Fabien
52:23
created

ModulePidService::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
namespace Fab\Vidi\Module;
3
4
/*
5
 * This file is part of the Fab/Vidi project under GPLv2 or later.
6
 *
7
 * For the full copyright and license information, please read the
8
 * LICENSE.md file that was distributed with this source code.
9
 */
10
11
use Fab\Vidi\Tca\Tca;
12
use TYPO3\CMS\Core\Database\ConnectionPool;
13
use TYPO3\CMS\Core\Database\Query\QueryBuilder;
14
use TYPO3\CMS\Core\Utility\GeneralUtility;
15
use TYPO3\CMS\Frontend\Page\PageRepository;
16
17
/**
18
 * Class ModulePidService
19
 */
20
class ModulePidService
21
{
22
    /**
23
     * The data type (table)
24
     *
25
     * @var string
26
     */
27
    protected $dataType = '';
28
29
    /**
30
     * The page record of the configured pid
31
     *
32
     * @var array
33
     */
34
    protected $page = [];
35
36
    /**
37
     * A collection of speaking error messages why the pid is invalid.
38
     *
39
     * @var array
40
     */
41
    protected $errors = [];
42
43
    /**
44
     * ModulePidService constructor.
45
     */
46
    public function __construct()
47
    {
48
        $this->dataType = $this->getModuleLoader()->getDataType();
49
    }
50
51
    /**
52
     * Returns a class instance
53
     *
54
     * @return \Fab\Vidi\Module\ModulePidService|object
55
     */
56
    static public function getInstance()
57
    {
58
        return GeneralUtility::makeInstance(self::class);
59
    }
60
61
    /**
62
     * @return bool
63
     */
64
    public function isConfiguredPidValid(): bool
65
    {
66
        $errors = $this->validateConfiguredPid();
67
        return empty($errors);
68
    }
69
70
    /**
71
     * @return array
72
     */
73
    public function validateConfiguredPid(): array
74
    {
75
        $configuredPid = $this->getConfiguredNewRecordPid();
76
        $this->validateRootLevel($configuredPid);
77
        $this->validatePageExist($configuredPid);
78
        $this->validateDoktype($configuredPid);
79
        return $this->errors;
80
    }
81
82
    /**
83
     * Return the default configured pid.
84
     *
85
     * @return int
86
     */
87
    public function getConfiguredNewRecordPid(): int
88
    {
89
        if (GeneralUtility::_GP(Parameter::PID)) {
90
            $configuredPid = (int)GeneralUtility::_GP(Parameter::PID);
91
        } else {
92
93
            // Get pid from User TSConfig if any.
94
            $tsConfigPath = sprintf('tx_vidi.dataType.%s.storagePid', $this->dataType);
95
            $result = $this->getBackendUser()->getTSConfig($tsConfigPath);
96
            $configuredPid = isset($result['value'])
97
                ? $configuredPid = (int)$result['value']
98
                : $this->getModuleLoader()->getDefaultPid();
99
        }
100
101
        return $configuredPid;
102
    }
103
104
    /**
105
     * Check if pid is 0 and given table is allowed on root level.
106
     *
107
     * @param int $configuredPid
108
     * @return void
109
     */
110
    protected function validateRootLevel(int $configuredPid): void
111
    {
112
        if ($configuredPid > 0) {
113
            return;
114
        }
115
116
        $isRootLevel = (bool)Tca::table()->get('rootLevel');
117
        if (!$isRootLevel) {
118
            $this->errors[] = sprintf(
119
                'You are not allowed to use page id "0" unless you set $GLOBALS[\'TCA\'][\'%1$s\'][\'ctrl\'][\'rootLevel\'] = 1;',
120
                $this->dataType
121
            );
122
        }
123
    }
124
125
    /**
126
     * Check if a page exists for the configured pid
127
     *
128
     * @param int $configuredPid
129
     * @return void
130
     */
131
    protected function validatePageExist(int $configuredPid): void
132
    {
133
        if ($configuredPid === 0) {
134
            return;
135
        }
136
137
        $page = $this->getPage($configuredPid);
138
        if (empty($page)) {
139
            $this->errors[] = sprintf(
140
                'No page found for the configured page id "%s".',
141
                $configuredPid
142
            );
143
        }
144
    }
145
146
    /**
147
     * Check if configured page is a sysfolder and if it is allowed.
148
     *
149
     * @param int $configuredPid
150
     * @return void
151
     */
152
    protected function validateDoktype(int $configuredPid): void
153
    {
154
        if ($configuredPid === 0) {
155
            return;
156
        }
157
158
        $page = $this->getPage($configuredPid);
159
        if (!empty($page)
160
            && (int)$page['doktype'] !== PageRepository::DOKTYPE_SYSFOLDER
161
            && !$this->isTableAllowedOnStandardPages()
162
            && $this->getModuleLoader()->hasComponentInDocHeader(\Fab\Vidi\View\Button\NewButton::class)) {
163
            $this->errors[] = sprintf(
164
                'The page with the id "%s" either has to be of the type "folder" (doktype=254) or the table "%s" has to be allowed on standard pages.',
165
                $configuredPid,
166
                $this->dataType
167
            );
168
        }
169
    }
170
171
    /**
172
     * Check if given table is allowed on standard pages
173
     *
174
     * @return bool
175
     * @see \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::allowTableOnStandardPages()
176
     */
177
    protected function isTableAllowedOnStandardPages(): bool
178
    {
179
        $allowedTables = explode(',', $GLOBALS['PAGES_TYPES']['default']['allowedTables']);
180
        return in_array($this->dataType, $allowedTables, true);
181
    }
182
183
    /**
184
     * Return a pointer to the database.
185
     *
186
     * @return \Fab\Vidi\Database\DatabaseConnection
187
     */
188
    protected function getDatabaseConnection(): \Fab\Vidi\Database\DatabaseConnection
189
    {
190
        return $GLOBALS['TYPO3_DB'];
191
    }
192
193
    /**
194
     * Returns the page record of the configured pid
195
     *
196
     * @param int $configuredPid
197
     * @return array
198
     */
199
    protected function getPage(int $configuredPid): ?array
200
    {
201
        if ($this->page !== null) {
202
            return $this->page;
203
        }
204
205
        $query = $this->getQueryBuilder('pages');
206
        $query->getRestrictions()->removeAll(); // we are in BE context.
207
208
        $page = $query->select('doktype')
209
            ->from('pages')
210
            ->where('deleted = 0',
211
                'uid = ' . $configuredPid)
212
            ->execute()
213
            ->fetch();
214
215
        return is_array($page)
216
            ? $page
217
            : [];
218
    }
219
220
    /**
221
     * @param string $tableName
222
     * @return object|QueryBuilder
223
     */
224
    protected function getQueryBuilder($tableName): QueryBuilder
225
    {
226
        /** @var ConnectionPool $connectionPool */
227
        $connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
228
        return $connectionPool->getQueryBuilderForTable($tableName);
229
    }
230
231
    /**
232
     * Returns an instance of the current Backend User.
233
     *
234
     * @return \TYPO3\CMS\Core\Authentication\BackendUserAuthentication
235
     */
236
    protected function getBackendUser()
237
    {
238
        return $GLOBALS['BE_USER'];
239
    }
240
241
    /**
242
     * Get the Vidi Module Loader.
243
     *
244
     * @return \Fab\Vidi\Module\ModuleLoader|object
245
     */
246
    protected function getModuleLoader()
247
    {
248
        return GeneralUtility::makeInstance(\Fab\Vidi\Module\ModuleLoader::class);
249
    }
250
251
}
252