Skip to content

Commit b40f54c

Browse files
lukmzigmcop1
andauthored
[Data Object Editor] Invalid localized fields context (#985)
* fix: context object can be null * Apply php-cs-fixer changes * create abstract data for context if there is none present * Always create a new FieldContextData object for each type inside fc * Apply php-cs-fixer changes * Added support for localized fields in block * Apply php-cs-fixer changes * Adapted support for localized fields in block container --------- Co-authored-by: Marco Perberschlager <marco.perberschlager@pimcore.com> Co-authored-by: mcop1 <89011527+mcop1@users.noreply.github.com>
1 parent f82206e commit b40f54c

5 files changed

Lines changed: 96 additions & 35 deletions

File tree

src/DataObject/Data/Adapter/BlockAdapter.php

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
use Exception;
2020
use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\DataNormalizerInterface;
21+
use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Model\BlockData;
2122
use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Model\FieldContextData;
2223
use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\SearchPreviewDataInterface;
2324
use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\SetterDataInterface;
@@ -110,12 +111,21 @@ public function normalize(
110111
private function createFieldContextData(
111112
Concrete $element,
112113
Data $fieldDefinition,
114+
int $index,
113115
?FieldContextData $contextData = null
114116
): FieldContextData {
115117
$object = $contextData?->getContextObject() ?? $element;
118+
$data = $object->get($fieldDefinition->getName())[$index] ?? [];
116119

117120
return new FieldContextData(
118-
$object->get($fieldDefinition->getName()),
121+
new BlockData(
122+
$data,
123+
[
124+
'containerType' => 'block',
125+
'classId' => $element->getClassId(),
126+
'fieldname' => $fieldDefinition->getName(),
127+
]
128+
),
119129
$contextData?->getLanguage()
120130
);
121131
}
@@ -132,13 +142,14 @@ private function processBlockData(
132142
?FieldContextData $contextData = null,
133143
): array {
134144
$resultBlockData = [];
135-
foreach ($blockData as $rawBlockElement) {
145+
foreach ($blockData as $index => $rawBlockElement) {
136146
$resultElement = $this->processBlockElement(
137147
$element,
138148
$user,
139149
$fieldDefinition,
140150
$rawBlockElement,
141151
$isPatch,
152+
$index,
142153
$contextData,
143154
);
144155
$resultBlockData[] = $resultElement;
@@ -156,11 +167,12 @@ private function processBlockElement(
156167
Block $fieldDefinition,
157168
array $rawBlockElement,
158169
bool $isPatch,
170+
int $index,
159171
?FieldContextData $contextData = null
160172
): array {
161173
$resultElement = [];
162174
$fieldDefinitions = $fieldDefinition->getFieldDefinitions();
163-
$fieldContextData = $this->createFieldContextData($element, $fieldDefinition, $contextData);
175+
$fieldContextData = $this->createFieldContextData($element, $fieldDefinition, $index, $contextData);
164176

165177
foreach ($fieldDefinitions as $elementName => $fd) {
166178
$adapter = $this->dataAdapterService->tryDataAdapter($fd->getFieldType());

src/DataObject/Data/Adapter/FieldCollectionsAdapter.php

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -76,27 +76,31 @@ public function getDataForSetter(
7676

7777
$fcData = $data[$key];
7878
$values = [];
79-
$count = 0;
8079

8180
foreach ($fcData as $index => $collectionRaw) {
81+
$contextData = $this->createFieldContextData(
82+
$element,
83+
$fieldDefinition,
84+
$index,
85+
$collectionRaw[self::TYPE_KEY],
86+
$contextData
87+
);
88+
8289
$collectionData = $this->processCollectionRaw(
8390
$element,
8491
$user,
8592
$fieldDefinition,
8693
$collectionRaw,
8794
$isPatch,
88-
$this->createFieldContextData($element, $fieldDefinition, $index, $contextData),
95+
$contextData,
8996
);
9097

91-
$collection = $this->createCollection(
92-
$element,
93-
$fieldDefinition,
94-
$collectionRaw[self::TYPE_KEY],
95-
$collectionData,
96-
$count
97-
);
98-
$values[] = $collection;
99-
$count++;
98+
$contextObject = $contextData->getContextObject();
99+
if (!$contextObject instanceof AbstractData) {
100+
continue;
101+
}
102+
$contextObject->setValues($collectionData);
103+
$values[] = $contextObject;
100104
}
101105

102106
return new Fieldcollection($values, $fieldDefinition->getName());
@@ -141,14 +145,12 @@ private function createFieldContextData(
141145
Concrete $element,
142146
Data $fieldDefinition,
143147
int $index,
148+
string $type,
144149
?FieldContextData $contextData = null,
145150
): FieldContextData {
146-
$object = $contextData?->getContextObject() ?? $element;
151+
$fieldCollectionData = $this->createCollection($element, $fieldDefinition, $type, [], $index);
147152

148-
return new FieldContextData(
149-
$object->get($fieldDefinition->getName())?->get($index),
150-
$contextData?->getLanguage()
151-
);
153+
return new FieldContextData($fieldCollectionData, $contextData?->getLanguage());
152154
}
153155

154156
/**

src/DataObject/Data/Adapter/LocalizedFieldsAdapter.php

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,11 @@
1717
namespace Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Adapter;
1818

1919
use Exception;
20+
use InvalidArgumentException;
2021
use Pimcore\Bundle\StaticResolverBundle\Lib\ToolResolverInterface;
2122
use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\DataInheritanceInterface;
2223
use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\DataNormalizerInterface;
24+
use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Model\BlockData;
2325
use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Model\FieldContextData;
2426
use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\SearchPreviewDataInterface;
2527
use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\SetterDataInterface;
@@ -29,7 +31,6 @@
2931
use Pimcore\Bundle\StudioBackendBundle\DataObject\Service\InheritanceServiceInterface;
3032
use Pimcore\Bundle\StudioBackendBundle\DataObject\Util\Trait\ValidateObjectDataTrait;
3133
use Pimcore\Bundle\StudioBackendBundle\Exception\Api\DatabaseException;
32-
use Pimcore\Bundle\StudioBackendBundle\Exception\Api\InvalidArgumentException;
3334
use Pimcore\Bundle\StudioBackendBundle\Exception\Api\NotFoundException;
3435
use Pimcore\Bundle\StudioBackendBundle\Security\Service\LanguageServiceInterface;
3536
use Pimcore\Bundle\StudioBackendBundle\Security\Service\SecurityServiceInterface;
@@ -86,7 +87,6 @@ public function getDataForSetter(
8687

8788
$languageData = $this->getAllowedLanguages($element, $user, $data[$key]);
8889
$localizedField = $this->getLocalizedField($contextData, $element);
89-
$localizedField->setObject($element);
9090

9191
foreach ($languageData as $name => $localizedData) {
9292
foreach ($localizedData as $language => $fieldData) {
@@ -292,17 +292,27 @@ private function getPreviewLanguage(Localizedfield $value): ?string
292292
*/
293293
private function getLocalizedField(?FieldContextData $contextData, Concrete $element): Localizedfield
294294
{
295+
$contextObject = $contextData?->getContextObject();
296+
$localizedField = null;
297+
295298
if ($contextData === null) {
296-
$localizedField = $this->getValidFieldValue($element, self::LOCALIZED_FIELDS_KEY);
297-
if (!$localizedField instanceof Localizedfield) {
298-
return new Localizedfield();
299-
}
299+
$localizedField = $this->getValidFieldValue($element, self::LOCALIZED_FIELDS_KEY);
300+
}
300301

301-
return $localizedField;
302+
if ($contextObject !== null) {
303+
$localizedField = $contextData->getFieldValueFromContextObject(self::LOCALIZED_FIELDS_KEY);
304+
if (!$localizedField && $contextObject instanceof BlockData) {
305+
$localizedField = new Localizedfield();
306+
$localizedField->setContext(
307+
$contextObject->getContextData()
308+
);
309+
}
302310
}
303311

304-
if ($contextData->getContextObject() !== null) {
305-
return $contextData->getFieldValueFromContextObject(self::LOCALIZED_FIELDS_KEY);
312+
if ($localizedField) {
313+
$localizedField->setObject($element);
314+
315+
return $localizedField;
306316
}
307317

308318
throw new InvalidArgumentException('Invalid context provided.');
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
/**
5+
* Pimcore
6+
*
7+
* This source file is available under two different licenses:
8+
* - GNU General Public License version 3 (GPLv3)
9+
* - Pimcore Commercial License (PCL)
10+
* Full copyright and license information is available in
11+
* LICENSE.md which is distributed with this source code.
12+
*
13+
* @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.org)
14+
* @license http://www.pimcore.org/license GPLv3 and PCL
15+
*/
16+
17+
namespace Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Model;
18+
19+
/**
20+
* @internal
21+
*/
22+
final readonly class BlockData
23+
{
24+
public function __construct(
25+
private array $blockData,
26+
private array $contextData
27+
) {
28+
}
29+
30+
public function getBlockData(): array
31+
{
32+
return $this->blockData;
33+
}
34+
35+
public function getContextData(): array
36+
{
37+
return $this->contextData;
38+
}
39+
}

src/DataObject/Data/Model/FieldContextData.php

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,14 @@
2424
use Pimcore\Model\DataObject\Fieldcollection\Data\AbstractData as FieldCollectionData;
2525
use Pimcore\Model\DataObject\Objectbrick;
2626
use Pimcore\Model\DataObject\Objectbrick\Data\AbstractData;
27-
use function is_array;
2827

2928
/**
3029
* @internal
3130
*/
3231
final readonly class FieldContextData
3332
{
3433
public function __construct(
35-
private AbstractData|array|FieldCollectionData|Classificationstore|null $contextObject = null,
34+
private AbstractData|BlockData|FieldCollectionData|Classificationstore|null $contextObject = null,
3635
private ?string $language = null,
3736
private ?int $classificationStoreGroupId = null,
3837
private ?int $classificationStoreKeyId = null,
@@ -44,7 +43,7 @@ public function getLanguage(): ?string
4443
return $this->language;
4544
}
4645

47-
public function getContextObject(): FieldCollectionData|array|AbstractData|Classificationstore|null
46+
public function getContextObject(): FieldCollectionData|BlockData|AbstractData|Classificationstore|null
4847
{
4948
return $this->contextObject;
5049
}
@@ -70,7 +69,7 @@ public function getFieldValueFromContextObject(string $fieldName): mixed
7069
$contextObject instanceof AbstractData, $contextObject instanceof FieldCollectionData =>
7170
$contextObject->get($fieldName, $this->language),
7271
$contextObject instanceof Classificationstore => $this->getDataFromClassificationStore($contextObject),
73-
is_array($contextObject) => $this->getDataFromBlock($fieldName, $contextObject),
72+
$contextObject instanceof BlockData => $this->getDataFromBlock($fieldName, $contextObject->getBlockData()),
7473
default => null,
7574
};
7675
}
@@ -116,9 +115,8 @@ private function createFieldContextData(
116115
private function getDataFromBlock(string $fieldName, array $blockData): mixed
117116
{
118117
foreach ($blockData as $value) {
119-
$fieldValue = $value[$fieldName] ?? null;
120-
if ($fieldValue instanceof BlockElement) {
121-
return $fieldValue->getData();
118+
if ($value instanceof BlockElement && $value->getName() === $fieldName) {
119+
return $value->getData();
122120
}
123121
}
124122

0 commit comments

Comments
 (0)