Skip to content

Commit daf1356

Browse files
committed
[FEATURE] JSON split loader supports comma-separated paths
.. for the extension configuration options "backend_layouts_folder" and "content_elements_folder".
1 parent c8048cc commit daf1356

6 files changed

Lines changed: 162 additions & 20 deletions

File tree

Build/phpstan/phpstan-baseline.neon

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1230,6 +1230,11 @@ parameters:
12301230
count: 1
12311231
path: ../../Tests/Unit/Loader/JsonSplitLoaderTest.php
12321232

1233+
-
1234+
message: "#^Method MASK\\\\Mask\\\\Tests\\\\Unit\\\\Loader\\\\JsonSplitLoaderTest\\:\\:getExpectedConfigurationArray2\\(\\) return type has no value type specified in iterable type array\\.$#"
1235+
count: 1
1236+
path: ../../Tests/Unit/Loader/JsonSplitLoaderTest.php
1237+
12331238
-
12341239
message: "#^Method MASK\\\\Mask\\\\Test\\\\Utility\\\\OverrideFieldsUtilityTest\\:\\:restructuringFieldsWorks\\(\\) has parameter \\$expected with no value type specified in iterable type array\\.$#"
12351240
count: 1
@@ -1284,4 +1289,3 @@ parameters:
12841289
message: "#^Method MASK\\\\Mask\\\\Tests\\\\Unit\\\\TemplatePathUtilityTest\\:\\:getTemplatePathDataProvider\\(\\) return type has no value type specified in iterable type iterable\\.$#"
12851290
count: 1
12861291
path: ../../Tests/Unit/Utility/TemplatePathUtilityTest.php
1287-

Classes/Loader/JsonSplitLoader.php

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
use MASK\Mask\Definition\TcaFieldDefinition;
2828
use MASK\Mask\Enumeration\FieldType;
2929
use MASK\Mask\Migrations\MigrationManager;
30+
use MASK\Mask\Utility\TemplatePathUtility;
3031
use Symfony\Component\Finder\Finder;
3132
use TYPO3\CMS\Core\Configuration\Features;
3233
use TYPO3\CMS\Core\Utility\ArrayUtility;
@@ -63,17 +64,21 @@ public function load(): TableDefinitionCollection
6364
$this->tableDefinitionCollection = new TableDefinitionCollection();
6465
$definitionArray = [];
6566

66-
$contentElementsFolder = $this->validateFolderPath('tt_content');
67-
if (file_exists($contentElementsFolder)) {
68-
$definitionArray = $this->mergeElementDefinitions($definitionArray, $contentElementsFolder);
67+
$contentElementsFolders = $this->validateFolderPaths('tt_content');
68+
foreach ($contentElementsFolders as $contentElementsFolder) {
69+
if (file_exists($contentElementsFolder)) {
70+
$definitionArray = $this->mergeElementDefinitions($definitionArray, $contentElementsFolder);
71+
}
6972
}
7073

7174
// If optional backendLayoutsFolder is not empty, validate the path.
72-
$backendLayoutsFolder = $this->getAbsolutePath('pages');
73-
if ($backendLayoutsFolder !== '') {
74-
$backendLayoutsFolder = $this->validateFolderPath('pages');
75-
if (file_exists($backendLayoutsFolder)) {
76-
$definitionArray = $this->mergeElementDefinitions($definitionArray, $backendLayoutsFolder);
75+
$backendLayoutsFolders = $this->getAbsolutePaths('pages');
76+
if (count($backendLayoutsFolders)) {
77+
$backendLayoutsFolders = $this->validateFolderPaths('pages');
78+
foreach ($backendLayoutsFolders as $backendLayoutsFolder) {
79+
if (file_exists($backendLayoutsFolder)) {
80+
$definitionArray = $this->mergeElementDefinitions($definitionArray, $backendLayoutsFolder);
81+
}
7782
}
7883
}
7984

@@ -91,32 +96,38 @@ public function write(TableDefinitionCollection $tableDefinitionCollection): voi
9196
{
9297
// Write content elements and backend layouts (if a folder is defined).
9398
$this->writeElementsForTable($tableDefinitionCollection, 'tt_content');
94-
if ($this->getAbsolutePath('pages') !== '') {
99+
if (count($this->getAbsolutePaths('pages'))) {
95100
$this->writeElementsForTable($tableDefinitionCollection, 'pages');
96101
}
97102

98103
// Save new definition in memory.
99104
$this->tableDefinitionCollection = $tableDefinitionCollection;
100105
}
101106

102-
protected function validateFolderPath(string $table): string
107+
/**
108+
* @return string[]
109+
*/
110+
protected function validateFolderPaths(string $table): array
103111
{
104-
$path = $this->getAbsolutePath($table);
105-
if ($path === '' && isset($this->maskExtensionConfiguration[self::FOLDER_KEYS[$table]]) && $this->maskExtensionConfiguration[self::FOLDER_KEYS[$table]] !== '') {
106-
throw new \InvalidArgumentException('Expected ' . self::FOLDER_KEYS[$table] . ' to be a correct file system path. The value "' . $path . '" was given.', 1639218892);
112+
$paths = $this->getAbsolutePaths($table);
113+
if (count($paths) === 0 && isset($this->maskExtensionConfiguration[self::FOLDER_KEYS[$table]]) && $this->maskExtensionConfiguration[self::FOLDER_KEYS[$table]] !== '') {
114+
throw new \InvalidArgumentException('Expected ' . self::FOLDER_KEYS[$table] . ' to be a correct file system path. The value "" was given.', 1639218892);
107115
}
108116

109-
return $path;
117+
return $paths;
110118
}
111119

112120
protected function getPath(string $table): string
113121
{
114122
return $this->maskExtensionConfiguration[self::FOLDER_KEYS[$table]] ?? '';
115123
}
116124

117-
protected function getAbsolutePath(string $table): string
125+
/**
126+
* @return string[]
127+
*/
128+
protected function getAbsolutePaths(string $table): array
118129
{
119-
return GeneralUtility::getFileAbsFileName($this->getPath($table));
130+
return TemplatePathUtility::getAbsolutePaths($this->getPath($table));
120131
}
121132

122133
protected function mergeElementDefinitions(array &$definitionArray, string $folder): array
@@ -138,7 +149,7 @@ protected function writeElementsForTable(TableDefinitionCollection $tableDefinit
138149
}
139150

140151
$overrideSharedFields = $this->features->isFeatureEnabled('overrideSharedFields');
141-
$absolutePath = $this->validateFolderPath($table);
152+
$absolutePath = $this->validateFolderPaths($table)[0];
142153

143154
if (!file_exists($absolutePath)) {
144155
GeneralUtility::mkdir_deep($absolutePath);

Classes/Utility/TemplatePathUtility.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,4 +65,19 @@ public static function getTemplatePath(
6565
}
6666
return $path . $fileName . $fileExtension;
6767
}
68+
69+
/**
70+
* Split a string of comma-separated paths and make them absolute.
71+
* Remove empty paths.
72+
*
73+
* @return string[]
74+
*/
75+
public static function getAbsolutePaths(string $commaSeparatedPaths): array
76+
{
77+
$paths = GeneralUtility::trimExplode(',', $commaSeparatedPaths);
78+
foreach ($paths as $key => $path) {
79+
$paths[$key] = GeneralUtility::getFileAbsFileName($path);
80+
}
81+
return array_filter($paths);
82+
}
6883
}

Resources/Private/Language/locallang_mask.xlf

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@
2222
<source>File with project-specific mask configuration (JsonLoader)</source>
2323
</trans-unit>
2424
<trans-unit id="ext_conf_template-content-elements-folder">
25-
<source>Folder in which to store content element definitions (JsonSplitLoader)</source>
25+
<source>Folder in which to store content element definitions (JsonSplitLoader): Multiple folders comma-separated</source>
2626
</trans-unit>
2727
<trans-unit id="ext_conf_template-backend-layouts-folder">
28-
<source>Folder in which to store backend layout definitions (JsonSplitLoader)</source>
28+
<source>Folder in which to store backend layout definitions (JsonSplitLoader): Multiple folders comma-separated</source>
2929
</trans-unit>
3030
<trans-unit id="ext_conf_template-override_shared_fields">
3131
<source>Override shared fields per content element.:Careful! As soon as this option is enabled and you save content elements, the fields are not synced anymore and this action can not be undone! Please back up your Mask element definitions before.</source>
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
{
2+
"tt_content": {
3+
"elements": {
4+
"f": {
5+
"key": "f",
6+
"label": "F",
7+
"description": "",
8+
"shortLabel": "",
9+
"color": "#000000",
10+
"icon": "",
11+
"columns": [
12+
"header",
13+
"tx_mask_file"
14+
],
15+
"columnsOverride": [],
16+
"labels": [
17+
"Header",
18+
"File"
19+
],
20+
"descriptions": [
21+
"",
22+
"only images are allowed"
23+
],
24+
"sorting": 2
25+
}
26+
},
27+
"sql": {
28+
"tx_mask_file": {
29+
"tt_content": {
30+
"tx_mask_file": "int(11) unsigned DEFAULT '0' NOT NULL"
31+
}
32+
}
33+
},
34+
"tca": {
35+
"tx_mask_file": {
36+
"config": {
37+
"appearance": {
38+
"fileUploadAllowed": 1
39+
}
40+
},
41+
"type": "file",
42+
"key": "file",
43+
"fullKey": "tx_mask_file",
44+
"imageoverlayPalette": 1
45+
},
46+
"header": {
47+
"coreField": 1,
48+
"type": "string",
49+
"key": "header",
50+
"fullKey": "header"
51+
}
52+
},
53+
"palettes": []
54+
}
55+
}

Tests/Unit/Loader/JsonSplitLoaderTest.php

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,30 @@ public function load(): void
5454
self::assertEquals($this->getExpectedConfigurationArray(), $jsonSplitLoader->load()->toArray(false));
5555
}
5656

57+
/**
58+
* @test
59+
*/
60+
public function loadCommaSeparated(): void
61+
{
62+
$this->registerPackageManager();
63+
$jsonSplitLoader = new JsonSplitLoader(
64+
[
65+
'content_elements_folder' => 'EXT:mask/Tests/Unit/Fixtures/Configuration/ContentElements,EXT:mask/Tests/Unit/Fixtures/Configuration/ContentElements2',
66+
'backend_layouts_folder' => 'EXT:mask/Tests/Unit/Fixtures/Configuration/BackendLayouts',
67+
],
68+
new MigrationManager([]),
69+
new Features()
70+
);
71+
72+
self::assertEquals(
73+
array_merge_recursive(
74+
$this->getExpectedConfigurationArray(),
75+
$this->getExpectedConfigurationArray2()
76+
),
77+
$jsonSplitLoader->load()->toArray(false)
78+
);
79+
}
80+
5781
/**
5882
* @test
5983
*/
@@ -1110,6 +1134,39 @@ protected function getExpectedConfigurationArray(): array
11101134
];
11111135
}
11121136

1137+
protected function getExpectedConfigurationArray2(): array
1138+
{
1139+
return [
1140+
'tt_content' => [
1141+
'elements' => [
1142+
'f' => [
1143+
'key' => 'f',
1144+
'label' => 'F',
1145+
'description' => '',
1146+
'shortLabel' => '',
1147+
'color' => '#000000',
1148+
'icon' => '',
1149+
'columns' => [
1150+
'header',
1151+
'tx_mask_file',
1152+
],
1153+
'labels' => [
1154+
'Header',
1155+
'File',
1156+
],
1157+
'descriptions' => [
1158+
'',
1159+
'only images are allowed',
1160+
],
1161+
'sorting' => 2,
1162+
'colorOverlay' => '',
1163+
'iconOverlay' => '',
1164+
],
1165+
],
1166+
],
1167+
];
1168+
}
1169+
11131170
/**
11141171
* @test
11151172
*/

0 commit comments

Comments
 (0)