Completed
Push — master ( 86d3fe...d815fa )
by Tim
10:20
created

useTableNameFileBase()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 5
ccs 0
cts 4
cp 0
rs 9.4285
cc 2
eloc 3
nc 2
nop 0
crap 6
1
<?php
2
/**
3
 * SmartObjectInformationService.php.
4
 */
5
namespace HDNET\Autoloader\Service;
6
7
use HDNET\Autoloader\DataSet;
8
use HDNET\Autoloader\Mapper;
9
use HDNET\Autoloader\Utility\ArrayUtility;
10
use HDNET\Autoloader\Utility\ClassNamingUtility;
11
use HDNET\Autoloader\Utility\ExtendedUtility;
12
use HDNET\Autoloader\Utility\IconUtility;
13
use HDNET\Autoloader\Utility\ModelUtility;
14
use HDNET\Autoloader\Utility\ReflectionUtility;
15
use HDNET\Autoloader\Utility\TranslateUtility;
16
use TYPO3\CMS\Core\Utility\GeneralUtility;
17
18
/**
19
 * SmartObjectInformationService.
20
 */
21
class SmartObjectInformationService
22
{
23
    /**
24
     * Get a instance of this object.
25
     *
26
     * @return \HDNET\Autoloader\Service\SmartObjectInformationService
27
     */
28
    public static function getInstance()
29
    {
30
        return GeneralUtility::makeInstance(self::class);
31
    }
32
33
    /**
34
     * Get database information.
35
     *
36
     * @param $modelClassName
37
     *
38
     * @return string
39
     */
40
    public function getDatabaseInformation($modelClassName)
41
    {
42
        $tableName = ModelUtility::getTableName($modelClassName);
43
        $custom = $this->getCustomDatabaseInformation($modelClassName);
44
45
        // disable complete table generation
46
        // for extending existing tables
47
        if ('' !== ModelUtility::getTableNameByModelReflectionAnnotation($modelClassName)) {
48
            return $this->generateSqlQuery($tableName, $custom);
49
        }
50
51
        return $this->generateCompleteSqlQuery($modelClassName, $tableName, $custom);
52
    }
53
54
    /**
55
     * Get the custom Model field TCA structure.
56
     *
57
     * @param       $modelClassName
58
     * @param array $searchFields
59
     *
60
     * @return array
61
     */
62
    public function getCustomModelFieldTca($modelClassName, &$searchFields = [])
63
    {
64
        $modelInformation = ClassNamingUtility::explodeObjectModelName($modelClassName);
65
        $extensionName = GeneralUtility::camelCaseToLowerCaseUnderscored($modelInformation['extensionName']);
66
        $tableName = ModelUtility::getTableName($modelClassName);
67
        $customFieldInfo = $this->getCustomModelFields($modelClassName);
68
        $searchFields = [];
69
        $customFields = [];
70
        foreach ($customFieldInfo as $info) {
71
            $key = $tableName . '.' . $info['name'];
72
73
            if($this->useTableNameFileBase()) {
74
                // Without prefix !
75
                $key = $info['name'];
76
            }
77
78
            try {
79
                TranslateUtility::assureLabel($key, $extensionName, $info['name'], null, $tableName);
80
                $label = TranslateUtility::getLllOrHelpMessage($key, $extensionName, $tableName);
81
            } catch (\Exception $ex) {
82
                $label = $info['name'];
83
            }
84
85
            /** @var Mapper $mapper */
86
            $mapper = ExtendedUtility::create(Mapper::class);
87
            $field = $mapper->getTcaConfiguration(trim($info['var'], '\\'), $info['name'], $label);
88
89
            // RTE
90
            if ($info['rte']) {
91
                $field['config']['type'] = 'text';
92
                $field['config']['enableRichtext'] = '1';
93
                $field['config']['richtextConfiguration'] = 'default';
94
                $field['defaultExtras'] = 'richtext:rte_transform[flag=rte_enabled|mode=ts_css]';
95
            }
96
97
            $searchFields[] = $info['name'];
98
            $customFields[$info['name']] = $field;
99
        }
100
101
        return $customFields;
102
    }
103
104
    /**
105
     * Check if table name file base is used
106
     *
107
     * @return bool
108
     */
109
    protected function useTableNameFileBase()
110
    {
111
        $configuration = unserialize((string)$GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['autoloader']);
112
        return isset($configuration['enableLanguageFileOnTableBase']) ? (bool)$configuration['enableLanguageFileOnTableBase'] : false;
113
    }
114
115
    /**
116
     * Pre build TCA information for the given model.
117
     *
118
     * @param string $modelClassName
119
     *
120
     * @return array
121
     */
122
    public function getTcaInformation($modelClassName)
123
    {
124
        $modelInformation = ClassNamingUtility::explodeObjectModelName($modelClassName);
125
        $extensionName = GeneralUtility::camelCaseToLowerCaseUnderscored($modelInformation['extensionName']);
126
        $reflectionTableName = ModelUtility::getTableNameByModelReflectionAnnotation($modelClassName);
127
        $tableName = ModelUtility::getTableNameByModelName($modelClassName);
128
129
        $searchFields = [];
130
        $customFields = $this->getCustomModelFieldTca($modelClassName, $searchFields);
131
132
        if ('' !== $reflectionTableName) {
133
            $customConfiguration = [
134
                'columns' => $customFields,
135
            ];
136
            $base = is_array($GLOBALS['TCA'][$reflectionTableName]) ? $GLOBALS['TCA'][$reflectionTableName] : [];
137
138
            return ArrayUtility::mergeRecursiveDistinct($base, $customConfiguration);
139
        }
140
141
        $excludes = ModelUtility::getSmartExcludesByModelName($modelClassName);
142
143
        $dataSet = $this->getDataSet();
144
        $dataImplementations = $dataSet->getAllAndExcludeList($excludes);
145
        $baseTca = $dataSet->getTcaInformation($dataImplementations, $tableName);
146
147
        // title
148
        $fields = array_keys($customFields);
149
        $labelField = 'title';
150
        if (!in_array($labelField, $fields)) {
151
            $labelField = $fields[0];
152
        }
153
        try {
154
            TranslateUtility::assureLabel($tableName, $extensionName, null, null, $tableName);
155
        } catch (\Exception $ex) {
156
            // Do not handle the error of the assureLabel method
157
        }
158
        if (!is_array($baseTca['columns'])) {
159
            $baseTca['columns'] = [];
160
        }
161
        $baseTca['columns'] = ArrayUtility::mergeRecursiveDistinct($baseTca['columns'], $customFields);
162
163
        // items
164
        $showitem = $fields;
165
        if (!in_array('language', $excludes)) {
166
            $showitem[] = '--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:language,--palette--;;language';
167
        }
168
169
        if (!in_array('workspaces', $excludes)) {
170
            $baseTca['ctrl']['shadowColumnsForNewPlaceholders'] .= ',' . $labelField;
171
        }
172
173
        $languagePrefix = 'LLL:EXT:frontend/Resources/Private/Language/';
174
        if (!in_array('enableFields', $excludes)) {
175
            $showitem[] = '--div--;' . $languagePrefix . 'locallang_ttc.xlf:tabs.access';
176
            $showitem[] = '--palette--;' . $languagePrefix . 'locallang_tca.xlf:pages.palettes.access;access';
177
        }
178
        $showitem[] = '--div--;' . $languagePrefix . 'locallang_ttc.xlf:tabs.extended';
179
180
        $overrideTca = [
181
            'ctrl' => [
182
                'title' => $this->getTcaTitle($tableName, $extensionName),
183
                'label' => $labelField,
184
                'tstamp' => 'tstamp',
185
                'crdate' => 'crdate',
186
                'cruser_id' => 'cruser_id',
187
                'dividers2tabs' => true,
188
                'sortby' => 'sorting',
189
                'delete' => 'deleted',
190
                'searchFields' => implode(',', $searchFields),
191
                'iconfile' => IconUtility::getByModelName($modelClassName, true),
192
            ],
193
            'interface' => [
194
                'showRecordFieldList' => implode(',', array_keys($baseTca['columns'])),
195
            ],
196
            'types' => [
197
                '1' => ['showitem' => implode(',', $showitem)],
198
            ],
199
            'palettes' => [
200
                'access' => ['showitem' => 'starttime, endtime, --linebreak--, hidden, editlock, --linebreak--, fe_group'],
201
            ],
202
        ];
203
204
        return ArrayUtility::mergeRecursiveDistinct($baseTca, $overrideTca);
205
    }
206
207
    /**
208
     * Get custom database information for the given model.
209
     *
210
     * @param string $modelClassName
211
     *
212
     * @return array
213
     */
214
    protected function getCustomDatabaseInformation($modelClassName)
215
    {
216
        $fieldInformation = $this->getCustomModelFields($modelClassName);
217
        $fields = [];
218
        foreach ($fieldInformation as $info) {
219
            if ('' === $info['db']) {
220
                $info['db'] = $this->getDatabaseMappingByVarType($info['var']);
221
            } else {
222
                try {
223
                    $info['db'] = $this->getDatabaseMappingByVarType($info['db']);
224
                } catch (\Exception $ex) {
225
                    // Do not handle the getDatabaseMappingByVarType by db, Fallback is the var call
226
                }
227
            }
228
            $fields[] = $info['name'] . ' ' . $info['db'];
229
        }
230
231
        return $fields;
232
    }
233
234
    /**
235
     * Get the right mapping.
236
     *
237
     * @param $var
238
     *
239
     * @throws \HDNET\Autoloader\Exception
240
     *
241
     * @return string
242
     */
243
    protected function getDatabaseMappingByVarType($var)
244
    {
245
        /** @var Mapper $mapper */
246
        $mapper = ExtendedUtility::create(Mapper::class);
247
248
        return $mapper->getDatabaseDefinition($var);
249
    }
250
251
    /**
252
     * Get custom database information for the given model.
253
     *
254
     * @param string $modelClassName
255
     *
256
     * @return array
257
     */
258
    protected function getCustomModelFields($modelClassName)
259
    {
260
        $properties = ReflectionUtility::getPropertiesTaggedWith($modelClassName, 'db');
261
        $fields = [];
262
        foreach ($properties as $property) {
263
            /** @var \TYPO3\CMS\Extbase\Reflection\PropertyReflection $property */
264
            $var = '';
265
            if ($property->isTaggedWith('var')) {
266
                $var = $property->getTagValues('var');
267
                $var = $var[0];
268
            }
269
270
            $dbInformation = $property->getTagValues('db');
271
            $fields[] = [
272
                'name' => GeneralUtility::camelCaseToLowerCaseUnderscored($property->getName()),
273
                'db' => trim($dbInformation[0]),
274
                'var' => trim($var),
275
                'rte' => (bool) $property->isTaggedWith('enableRichText'),
276
            ];
277
        }
278
279
        return $fields;
280
    }
281
282
    /**
283
     * Generate SQL Query.
284
     *
285
     * @param string $tableName
286
     * @param array  $fields
287
     *
288
     * @return string
289
     */
290
    protected function generateSqlQuery($tableName, array $fields)
291
    {
292
        if (empty($fields)) {
293
            return '';
294
        }
295
296
        return LF . 'CREATE TABLE ' . $tableName . ' (' . LF . implode(',' . LF, $fields) . LF . ');' . LF;
297
    }
298
299
    /**
300
     * Generate complete SQL Query.
301
     *
302
     * @param string $modelClassName
303
     * @param string $tableName
304
     * @param array  $custom
305
     *
306
     * @return string
307
     */
308
    protected function generateCompleteSqlQuery($modelClassName, $tableName, array $custom)
309
    {
310
        $fields = [];
311
        $fields[] = 'uid int(11) NOT NULL auto_increment';
312
        $fields[] = 'pid int(11) DEFAULT \'0\' NOT NULL';
313
        $fields[] = 'tstamp int(11) unsigned DEFAULT \'0\' NOT NULL';
314
        $fields[] = 'crdate int(11) unsigned DEFAULT \'0\' NOT NULL';
315
        $fields[] = 'cruser_id int(11) unsigned DEFAULT \'0\' NOT NULL';
316
        $fields[] = 'deleted tinyint(4) unsigned DEFAULT \'0\' NOT NULL';
317
        $fields[] = 'sorting int(11) DEFAULT \'0\' NOT NULL';
318
319
        foreach ($custom as $field) {
320
            $fields[] = $field;
321
        }
322
323
        $excludes = ModelUtility::getSmartExcludesByModelName($modelClassName);
324
        $dataSet = $this->getDataSet();
325
        $dataImplementations = $dataSet->getAllAndExcludeList($excludes);
326
327
        // add data set fields
328
        $fields = array_merge($fields, $dataSet->getDatabaseSqlInformation($dataImplementations, $tableName));
329
330
        // default keys
331
        $fields[] = 'PRIMARY KEY (uid)';
332
        $fields[] = 'KEY parent (pid)';
333
334
        // add custom keys set by @key annotations
335
        $classReflection = ReflectionUtility::createReflectionClass($modelClassName);
336
        if ($classReflection->isTaggedWith('key')) {
337
            $additionalKeys = $classReflection->getTagValues('key');
338
            array_walk($additionalKeys, function (&$item) {
339
                $item = 'KEY ' . $item;
340
            });
341
            $fields = array_merge($fields, $additionalKeys);
342
        }
343
344
        // add data set keys
345
        $fields = array_merge($fields, $dataSet->getDatabaseSqlKeyInformation($dataImplementations, $tableName));
346
347
        return $this->generateSqlQuery($tableName, $fields);
348
    }
349
350
    /**
351
     * Get the data set object.
352
     *
353
     * @return \HDNET\Autoloader\DataSet
354
     */
355
    protected function getDataSet()
356
    {
357
        return GeneralUtility::makeInstance(DataSet::class);
358
    }
359
360
    /**
361
     * @param string $tableName
362
     * @param string $extensionName
363
     *
364
     * @return string
365
     */
366
    protected function getTcaTitle($tableName, $extensionName)
367
    {
368
        return TranslateUtility::getLllOrHelpMessage($tableName, $extensionName, $tableName);
369
    }
370
}
371