diff --git a/README.md b/README.md index 42589645431..43ed2b28b8a 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ Pimcore - Open Source Data & Experience Management Platform: PIM, MDM, CDP, DAM, ## Contribute **Bug fixes:** please create a pull request including a step by step description to reproduce the problem **Contribute features:** contact the core-team on our [Gitter channel](https://gitter.im/pimcore/pimcore) before you start developing -**Security vulnerabilities:** please use [this form](https://pimcorehq.wufoo.com/forms/pimcore-security-report/) +**Security vulnerabilities:** please see our [security policy](https://github.com/pimcore/pimcore/security/policy) For details, please have a look at our [contributing guide](CONTRIBUTING.md). diff --git a/SECURITY.md b/SECURITY.md index 6b6917f5cf4..c06106cefcd 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -5,6 +5,7 @@ If you think that you have found a security issue, don’t use the bug tracker and don’t publish it publicly. Instead, all security issues must be reported via 📫 to [security-issue@pimcore.com](mailto:security-issue@pimcore.com). +Additionally, we also check issues reported via [huntr.dev](https://huntr.dev/repos/pimcore/pimcore/). ## Resolving Process diff --git a/bundles/AdminBundle/Controller/Admin/DataObject/DataObjectController.php b/bundles/AdminBundle/Controller/Admin/DataObject/DataObjectController.php index e0b912b7532..4ae31ca8672 100644 --- a/bundles/AdminBundle/Controller/Admin/DataObject/DataObjectController.php +++ b/bundles/AdminBundle/Controller/Admin/DataObject/DataObjectController.php @@ -515,7 +515,7 @@ static function (Task $task) { } if ($currentLayoutId === null && count($validLayouts) > 0) { - $currentLayoutId = $validLayouts[0]->getId(); + $currentLayoutId = reset($validLayouts)->getId(); } if (!empty($validLayouts)) { diff --git a/bundles/AdminBundle/Controller/Admin/Document/PageController.php b/bundles/AdminBundle/Controller/Admin/Document/PageController.php index a776855aae8..bbe19199898 100644 --- a/bundles/AdminBundle/Controller/Admin/Document/PageController.php +++ b/bundles/AdminBundle/Controller/Admin/Document/PageController.php @@ -30,6 +30,7 @@ use Pimcore\Model\Redirect; use Pimcore\Model\Schedule\Task; use Pimcore\Templating\Renderer\EditableRenderer; +use Pimcore\Tool\Frontend; use Symfony\Component\HttpFoundation\BinaryFileResponse; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; @@ -293,8 +294,25 @@ public function checkPrettyUrlAction(Request $request): JsonResponse ]); if ($list->getTotalCount() > 0) { - $success = false; - $message[] = 'URL path already exists.'; + $checkDocument = Document::getById($docId); + $checkSite = Frontend::getSiteForDocument($checkDocument); + $checkSiteId = empty($checkSite) ? 0 : $checkSite->getId(); + + foreach ($list as $document) { + if (empty($document)) { + continue; + } + + $site = Frontend::getSiteForDocument($document); + $siteId = empty($site) ? 0 : $site->getId(); + + if ($siteId === $checkSiteId) { + $success = false; + $message[] = 'URL path already exists.'; + + break; + } + } } return $this->adminJson([ diff --git a/bundles/AdminBundle/Controller/Admin/UserController.php b/bundles/AdminBundle/Controller/Admin/UserController.php index fc6dfb62559..ee709030091 100644 --- a/bundles/AdminBundle/Controller/Admin/UserController.php +++ b/bundles/AdminBundle/Controller/Admin/UserController.php @@ -21,12 +21,14 @@ use Pimcore\Bundle\AdminBundle\HttpFoundation\JsonResponse; use Pimcore\Controller\KernelControllerEventInterface; use Pimcore\Logger; +use Pimcore\Model\Asset; use Pimcore\Model\DataObject; use Pimcore\Model\Element; use Pimcore\Model\User; use Pimcore\Tool; use Scheb\TwoFactorBundle\Security\TwoFactor\Provider\Google\GoogleAuthenticatorInterface; use Symfony\Component\HttpFoundation\BinaryFileResponse; +use Symfony\Component\HttpFoundation\File\UploadedFile; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBagInterface; @@ -797,6 +799,15 @@ public function uploadImageAction(Request $request) throw $this->createAccessDeniedHttpException('Only admin users are allowed to modify admin users'); } + //Check if uploaded file is an image + $avatarFile = $request->files->get('Filedata'); + + $assetType = Asset::getTypeFromMimeMapping($avatarFile->getMimeType(), $avatarFile); + + if (!$avatarFile instanceof UploadedFile || $assetType !== 'image') { + throw new \Exception('Unsupported file format.'); + } + $userObj->setImage($_FILES['Filedata']['tmp_name']); // set content-type to text/html, otherwise (when application/json is sent) chrome will complain in diff --git a/bundles/AdminBundle/Controller/Searchadmin/SearchController.php b/bundles/AdminBundle/Controller/Searchadmin/SearchController.php index 7988bcf9ae9..5d7c7da863c 100644 --- a/bundles/AdminBundle/Controller/Searchadmin/SearchController.php +++ b/bundles/AdminBundle/Controller/Searchadmin/SearchController.php @@ -50,8 +50,11 @@ class SearchController extends AdminController * @return JsonResponse * * @todo: $conditionTypeParts could be undefined + * * @todo: $conditionSubtypeParts could be undefined + * * @todo: $conditionClassnameParts could be undefined + * * @todo: $data could be undefined */ public function findAction(Request $request, EventDispatcherInterface $eventDispatcher, GridHelperService $gridHelperService) diff --git a/bundles/AdminBundle/Resources/public/js/pimcore/object/classes/class.js b/bundles/AdminBundle/Resources/public/js/pimcore/object/classes/class.js index 103d8575116..f7c7fd40fdd 100644 --- a/bundles/AdminBundle/Resources/public/js/pimcore/object/classes/class.js +++ b/bundles/AdminBundle/Resources/public/js/pimcore/object/classes/class.js @@ -1360,9 +1360,6 @@ pimcore.object.classes.klass = Class.create({ } }, - - - removeChild: function (tree, record) { if (this.id != 0) { if (this.currentNode == record.data.editor) { @@ -1382,7 +1379,7 @@ pimcore.object.classes.klass = Class.create({ if (node.data.editor) { if (typeof node.data.editor.getData == "function") { data = node.data.editor.getData(); - + data.invalidFieldError = null; data.name = trim(data.name); // field specific validation @@ -1426,6 +1423,10 @@ pimcore.object.classes.klass = Class.create({ var invalidFieldsText = t("class_field_name_error") + ": '" + data.name + "'"; + if (data.invalidFieldError) { + invalidFieldsText = invalidFieldsText + " (" + data.invalidFieldError + ")"; + } + if(node.data.editor.invalidFieldNames){ invalidFieldsText = t("reserved_field_names_error") +(implode(',',node.data.editor.forbiddenNames)); diff --git a/bundles/AdminBundle/Resources/public/js/pimcore/object/classes/data/advancedManyToManyObjectRelation.js b/bundles/AdminBundle/Resources/public/js/pimcore/object/classes/data/advancedManyToManyObjectRelation.js index 628dd1f9dcd..c14ff3fb9ed 100644 --- a/bundles/AdminBundle/Resources/public/js/pimcore/object/classes/data/advancedManyToManyObjectRelation.js +++ b/bundles/AdminBundle/Resources/public/js/pimcore/object/classes/data/advancedManyToManyObjectRelation.js @@ -110,6 +110,7 @@ pimcore.object.classes.data.advancedManyToManyObjectRelation = Class.create(pimc name: 'allowedClassId', value: this.datax.allowedClassId, forceSelection:true, + allowBlank: false, listeners: { change: function(field, classNamevalue, oldValue) { this.datax.allowedClassId = classNamevalue; @@ -118,7 +119,6 @@ pimcore.object.classes.data.advancedManyToManyObjectRelation = Class.create(pimc } }.bind(this) } - }); this.specificPanel.add(this.classCombo); @@ -386,6 +386,22 @@ pimcore.object.classes.data.advancedManyToManyObjectRelation = Class.create(pimc return this.datax; }, + isValid: function ($super) { + if(!$super()) { + return false; + } + + const data = this.getData(); + const allowedClassId = trim(data.allowedClassId); + + if (!allowedClassId || allowedClassId === "null" || allowedClassId.length < 1) { + this.datax.invalidFieldError = t("mandatory_field_empty") + " - " + t('objectsMetadata_allowed_class'); + return false; + } + + return true; + }, + applyData: function ($super){ $super(); return this.getData(); diff --git a/bundles/AdminBundle/Resources/public/js/pimcore/object/tags/advancedManyToManyObjectRelation.js b/bundles/AdminBundle/Resources/public/js/pimcore/object/tags/advancedManyToManyObjectRelation.js index 22e2e5b7b96..c0c863af004 100644 --- a/bundles/AdminBundle/Resources/public/js/pimcore/object/tags/advancedManyToManyObjectRelation.js +++ b/bundles/AdminBundle/Resources/public/js/pimcore/object/tags/advancedManyToManyObjectRelation.js @@ -45,19 +45,29 @@ pimcore.object.tags.advancedManyToManyObjectRelation = Class.create(pimcore.obje var visibleFields = Ext.isString(this.fieldConfig.visibleFields) ? this.fieldConfig.visibleFields.split(",") : []; this.visibleFields = visibleFields; - fields.push("id"); - fields.push("index"); - fields.push("inheritedFields"); - fields.push("metadata"); + fields.push({name: "id"}); + fields.push({name: "index"}); + fields.push({name: "inheritedFields"}); + fields.push({name: "metadata"}); var i; for (i = 0; i < visibleFields.length; i++) { - fields.push(visibleFields[i]); + fields.push({name: visibleFields[i]}); } for (i = 0; i < this.fieldConfig.columns.length; i++) { - fields.push(this.fieldConfig.columns[i].key); + let defaultValue = null; + switch(this.fieldConfig.columns[i].type.toLowerCase()){ + case "bool": + defaultValue = this.fieldConfig.columns[i].value ? (this.fieldConfig.columns[i].value).toLowerCase() == "true" : null; + break; + case "text": + case "number": + defaultValue = this.fieldConfig.columns[i].value; + break; + } + fields.push({name: this.fieldConfig.columns[i].key, defaultValue: defaultValue}); } var modelName = 'ObjectsMultipleRelations'; diff --git a/bundles/AdminBundle/Resources/public/js/pimcore/object/tags/advancedManyToManyRelation.js b/bundles/AdminBundle/Resources/public/js/pimcore/object/tags/advancedManyToManyRelation.js index 602ad11508b..93c5ea984be 100644 --- a/bundles/AdminBundle/Resources/public/js/pimcore/object/tags/advancedManyToManyRelation.js +++ b/bundles/AdminBundle/Resources/public/js/pimcore/object/tags/advancedManyToManyRelation.js @@ -40,20 +40,31 @@ pimcore.object.tags.advancedManyToManyRelation = Class.create(pimcore.object.tag var fields = []; - fields.push("id"); - fields.push("path"); - fields.push("inheritedFields"); - fields.push("metadata"); - fields.push("type"); - fields.push("subtype"); + fields.push({name: "id"}); + fields.push({name:"path"}); + fields.push({name:"inheritedFields"}); + fields.push({name:"metadata"}); + fields.push({name:"type"}); + fields.push({name:"subtype"}); var i; for (i = 0; i < this.fieldConfig.columns.length; i++) { - fields.push(this.fieldConfig.columns[i].key); + let defaultValue = null; + switch(this.fieldConfig.columns[i].type.toLowerCase()){ + case "bool": + case "columnbool": + defaultValue = this.fieldConfig.columns[i].value ? (this.fieldConfig.columns[i].value).toLowerCase() == "true" : null; + break; + case "text": + case "number": + defaultValue = this.fieldConfig.columns[i].value; + break; + } + fields.push({name: this.fieldConfig.columns[i].key, defaultValue: defaultValue}); } - fields.push("rowId"); + fields.push({name: "rowId"}); var modelName = 'ObjectsMultihrefMetadataEntry'; if (!Ext.ClassManager.isCreated(modelName)) { diff --git a/bundles/AdminBundle/Resources/public/js/pimcore/settings/profile/panel.js b/bundles/AdminBundle/Resources/public/js/pimcore/settings/profile/panel.js index 31f41d1457a..247c3f69d19 100644 --- a/bundles/AdminBundle/Resources/public/js/pimcore/settings/profile/panel.js +++ b/bundles/AdminBundle/Resources/public/js/pimcore/settings/profile/panel.js @@ -250,6 +250,9 @@ pimcore.settings.profile.panel = Class.create({ Ext.getCmp("pimcore_profile_delete_image_" + this.currentUser.id).setVisible(true); pimcore.helpers.reloadUserImage(this.currentUser.id); this.currentUser.hasImage = true; + }.bind(this), + function () { + Ext.MessageBox.alert(t('error'), t("unsupported_filetype")); }.bind(this) ); }.bind(this) diff --git a/bundles/AdminBundle/Resources/public/js/pimcore/settings/user/user/settings.js b/bundles/AdminBundle/Resources/public/js/pimcore/settings/user/user/settings.js index 7cff290a69d..56dacbba324 100644 --- a/bundles/AdminBundle/Resources/public/js/pimcore/settings/user/user/settings.js +++ b/bundles/AdminBundle/Resources/public/js/pimcore/settings/user/user/settings.js @@ -177,6 +177,9 @@ pimcore.settings.user.user.settings = Class.create({ Ext.getCmp("pimcore_user_delete_image_" + this.currentUser.id).setVisible(true); pimcore.helpers.reloadUserImage(this.currentUser.id); this.currentUser.hasImage = true; + }.bind(this), + function () { + Ext.MessageBox.alert(t('error'), t("unsupported_filetype")); }.bind(this) ); }.bind(this) diff --git a/composer.json b/composer.json index 3fdadfda736..6178c9be6e2 100644 --- a/composer.json +++ b/composer.json @@ -28,7 +28,7 @@ "docs": "https://pimcore.com/docs/latest/" }, "require": { - "php": "^8.0", + "php": "~8.0.0 || ~8.1.0", "ext-SimpleXML": "*", "ext-dom": "*", "ext-exif": "*", diff --git a/doc/Development_Documentation/23_Installation_and_Upgrade/01_System_Requirements.md b/doc/Development_Documentation/23_Installation_and_Upgrade/01_System_Requirements.md index 6ace9d10d72..ab771c98e3b 100644 --- a/doc/Development_Documentation/23_Installation_and_Upgrade/01_System_Requirements.md +++ b/doc/Development_Documentation/23_Installation_and_Upgrade/01_System_Requirements.md @@ -14,7 +14,7 @@ For production, we highly recommend a *nix based system. - Nginx -### PHP >= 8.0 +### PHP >=8.0 <8.2 Both **mod_php** and **FCGI (FPM)** are supported. #### Required Settings and Modules & Extensions diff --git a/doc/Development_Documentation/23_Installation_and_Upgrade/07_Updating_Pimcore/10_V6_to_V10.md b/doc/Development_Documentation/23_Installation_and_Upgrade/07_Updating_Pimcore/10_V6_to_V10.md index 74c8ca47b75..11e7ecaaf01 100644 --- a/doc/Development_Documentation/23_Installation_and_Upgrade/07_Updating_Pimcore/10_V6_to_V10.md +++ b/doc/Development_Documentation/23_Installation_and_Upgrade/07_Updating_Pimcore/10_V6_to_V10.md @@ -1,11 +1,11 @@ # Upgrading Pimcore from Version 6.x to Version 10 ## System Requirement changes - - PHP >= 8.0 + - PHP >=8.0 <8.2 - Apache >= 2.4 - Composer >= 2.0 -> As Pimcore 6.x works only with PHP < 8.0 and Pimcore 10 works only with PHP >= 8.0, a switch of PHP version is needed during the upgrade process. +> As Pimcore 6.x works only with PHP < 8.0 and Pimcore 10 works only with PHP >=8.0 <8.2, a switch of PHP version is needed during the upgrade process. ## Database Requirement changes - MariaDB >= 10.3 @@ -159,10 +159,10 @@ mv var/config/custom-logo.* var/admin/custom-logo.image ## SWITCH COMPOSER AND PHP VERSION, AND DO THE UPDATE! - Ensure Composer is updated to version >= 2.0 -- Switch PHP version to PHP >= 8.0 +- Switch PHP version to PHP >=8.0 <8.2 - Run composer update (`COMPOSER_MEMORY_LIMIT=-1 composer update`) -## CHANGES TO DO AFTER THE UPDATE! (TO DO WITH PHP >= 8.0) +## CHANGES TO DO AFTER THE UPDATE! (TO DO WITH PHP >=8.0 <8.2) ### Verify migrations execution By default, Composer update runs Pimcore migrations automatically, however it is better to check if all migrations are executed for smooth transition. diff --git a/models/DataObject/ClassDefinition/Data/Slider.php b/models/DataObject/ClassDefinition/Data/Slider.php index c241dfca2f0..aa9a6431c11 100644 --- a/models/DataObject/ClassDefinition/Data/Slider.php +++ b/models/DataObject/ClassDefinition/Data/Slider.php @@ -420,6 +420,11 @@ public function isEqual($oldValue, $newValue): bool return false; } + public function isEmpty(mixed $data): bool + { + return !is_numeric($data); + } + /** * {@inheritdoc} */ diff --git a/models/DataObject/Fieldcollection/Data/AbstractData.php b/models/DataObject/Fieldcollection/Data/AbstractData.php index f75d252c7c1..10984dfc1d2 100644 --- a/models/DataObject/Fieldcollection/Data/AbstractData.php +++ b/models/DataObject/Fieldcollection/Data/AbstractData.php @@ -18,11 +18,13 @@ use Pimcore\Model; use Pimcore\Model\DataObject\ClassDefinition\Data\LazyLoadingSupportInterface; use Pimcore\Model\DataObject\Concrete; +use Pimcore\Model\DataObject\Localizedfield; +use Pimcore\Model\DataObject\ObjectAwareFieldInterface; /** * @method Dao getDao() */ -abstract class AbstractData extends Model\AbstractModel implements Model\DataObject\LazyLoadedFieldsInterface, Model\Element\ElementDumpStateInterface, Model\Element\DirtyIndicatorInterface +abstract class AbstractData extends Model\AbstractModel implements Model\DataObject\LazyLoadedFieldsInterface, Model\Element\ElementDumpStateInterface, Model\Element\DirtyIndicatorInterface, ObjectAwareFieldInterface { use Model\Element\ElementDumpStateTrait; use Model\DataObject\Traits\LazyLoadedRelationTrait; @@ -119,6 +121,10 @@ public function setObject(?Concrete $object) $this->objectId = $object ? $object->getId() : null; $this->object = $object; + if (property_exists($this, 'localizedfields') && $this->localizedfields instanceof Localizedfield) { + $this->localizedfields->setObject($object, false); + } + return $this; } diff --git a/models/DataObject/Objectbrick/Data/AbstractData.php b/models/DataObject/Objectbrick/Data/AbstractData.php index 04069e33c3b..5565999bf7d 100644 --- a/models/DataObject/Objectbrick/Data/AbstractData.php +++ b/models/DataObject/Objectbrick/Data/AbstractData.php @@ -20,13 +20,15 @@ use Pimcore\Model\DataObject\ClassDefinition\Data\LazyLoadingSupportInterface; use Pimcore\Model\DataObject\Concrete; use Pimcore\Model\DataObject\Exception\InheritanceParentNotFoundException; +use Pimcore\Model\DataObject\Localizedfield; +use Pimcore\Model\DataObject\ObjectAwareFieldInterface; /** * @method Dao getDao() * @method void save(Concrete $object, $params = []) * @method array getRelationData($field, $forOwner, $remoteClassId) */ -abstract class AbstractData extends Model\AbstractModel implements Model\DataObject\LazyLoadedFieldsInterface, Model\Element\ElementDumpStateInterface, Model\Element\DirtyIndicatorInterface +abstract class AbstractData extends Model\AbstractModel implements Model\DataObject\LazyLoadedFieldsInterface, Model\Element\ElementDumpStateInterface, Model\Element\DirtyIndicatorInterface, ObjectAwareFieldInterface { use Model\DataObject\Traits\LazyLoadedRelationTrait; use Model\Element\ElementDumpStateTrait; @@ -198,6 +200,10 @@ public function setObject(?Concrete $object) $this->objectId = $object ? $object->getId() : null; $this->object = $object; + if (property_exists($this, 'localizedfields') && $this->localizedfields instanceof Localizedfield) { + $this->localizedfields->setObject($object, false); + } + return $this; } diff --git a/models/DataObject/Service.php b/models/DataObject/Service.php index 8c55f83ed96..76ace7bc24f 100644 --- a/models/DataObject/Service.php +++ b/models/DataObject/Service.php @@ -996,7 +996,7 @@ public static function rewriteIds($object, $rewriteConfig, $params = []) /** * @param Concrete $object * - * @return DataObject\ClassDefinition\CustomLayout[] + * @return array */ public static function getValidLayouts(Concrete $object) { diff --git a/models/Element/Service.php b/models/Element/Service.php index 784b4ed4405..216e8c4d94f 100644 --- a/models/Element/Service.php +++ b/models/Element/Service.php @@ -34,6 +34,7 @@ use Pimcore\Model\DataObject\AbstractObject; use Pimcore\Model\DataObject\ClassDefinition\Data; use Pimcore\Model\DataObject\Concrete; +use Pimcore\Model\DataObject\ObjectAwareFieldInterface; use Pimcore\Model\Dependency; use Pimcore\Model\Document; use Pimcore\Model\Element\DeepCopy\MarshalMatcher; @@ -875,6 +876,12 @@ public static function renewReferences($data, $initial = true, $key = null) if ($data instanceof Model\AbstractModel) { $properties = $data->getObjectVars(); foreach ($properties as $name => $value) { + //do not renew object reference of ObjectAwareFieldInterface - as object might point to a + //specific version of the object and must not be reloaded with DB version of object + if (($data instanceof ObjectAwareFieldInterface || $data instanceof DataObject\Localizedfield) && $name === 'object') { + continue; + } + $data->setObjectVar($name, self::renewReferences($value, false, $name), true); } } else { diff --git a/tests/Model/DataType/ObjectAwareFieldsTest.php b/tests/Model/DataType/ObjectAwareFieldsTest.php new file mode 100644 index 00000000000..8b8c3630316 --- /dev/null +++ b/tests/Model/DataType/ObjectAwareFieldsTest.php @@ -0,0 +1,125 @@ +getLatestVersion(); + $this->assertNotNull($latestVersion, 'Latest version could not be loaded.'); + + $latestObjectVersion = $latestVersion->loadData(); + $this->assertNotNull($latestObjectVersion, 'Object from latest version could not be loaded.'); + + $this->assertNotEquals($databaseObject->getInput(), $latestObjectVersion->getInput(), 'Object versions are not different'); + + return [$databaseObject, $latestObjectVersion]; + } + + public function testLocalizedField(): void + { + /** + * @var Unittest $object + */ + $object = TestHelper::createEmptyObject(); + + $object->setInput('1'); + $object->setLinput('some localized input'); + $object->save(); + + //create new unpublished version of object + $object = Concrete::getById($object->getId(), true); + $object->setInput($object->getInput() + 1); + $object->saveVersion(); + + list($databaseObject, $latestObjectVersion) = $this->reloadObject($object->getId()); + + $this->assertEquals($latestObjectVersion->getLocalizedfields()->getObject()->getInput(), $latestObjectVersion->getInput(), 'Object reference in localized field is not right.'); + } + + public function testLocalizedFieldInFieldCollection(): void + { + /** + * @var Unittest $object + */ + $object = TestHelper::createEmptyObject(); + + $object->setInput('1'); + + $items = new Fieldcollection(); + $item = new FieldCollection\Data\Unittestfieldcollection(); + $item->setLinput('textEN', 'en'); + $items->add($item); + $object->setFieldcollection($items); + $object->save(); + + //create new unpublished version of object + $object = Concrete::getById($object->getId(), true); + $object->getFieldcollection(); + $object->setInput($object->getInput() + 1); + $object->saveVersion(); + + list($databaseObject, $latestObjectVersion) = $this->reloadObject($object->getId()); + + $fieldCollectionItems = $latestObjectVersion->getFieldcollection()->getItems(); + foreach ($fieldCollectionItems as $item) { + $this->assertEquals($item->getObject()->getInput(), $latestObjectVersion->getInput(), 'Object reference in field collection is not right.'); + $this->assertEquals($item->getLocalizedFields()->getObject()->getInput(), $latestObjectVersion->getInput(), 'Object reference in localized field in field collection is not right.'); + } + } + + public function testLocalizedFieldInObjectBrick(): void + { + /** + * @var LazyLoading $object + */ + $object = $this->createDataObject(); + $brick = new LazyLoadingLocalizedTest($object); + $brick->setLInput(uniqid()); + $object->getBricks()->setLazyLoadingLocalizedTest($brick); + $object->setInput('1'); + + $object->save(); + + //create new unpublished version of object + $object = Concrete::getById($object->getId(), true); + $object->getBricks(); + $object->setInput($object->getInput() + 1); + $object->saveVersion(); + + list($databaseObject, $latestObjectVersion) = $this->reloadObject($object->getId()); + + $brickItems = $latestObjectVersion->getBricks()->getItems(); + foreach ($brickItems as $item) { + $this->assertEquals($item->getObject()->getInput(), $latestObjectVersion->getInput(), 'Object reference in object brick is not right.'); + $this->assertEquals($item->getLocalizedFields()->getObject()->getInput(), $latestObjectVersion->getInput(), 'Object reference in localized field in object brick is not right.'); + } + } +} diff --git a/tests/_support/Helper/Model.php b/tests/_support/Helper/Model.php index 73f5d911a32..848d72f6ec8 100644 --- a/tests/_support/Helper/Model.php +++ b/tests/_support/Helper/Model.php @@ -82,6 +82,7 @@ public function setupPimcoreClass_LazyLoading($name = 'LazyLoading', $filename = $rootPanel = (new \Pimcore\Model\DataObject\ClassDefinition\Layout\Tabpanel())->setName('Layout'); $rootPanel->addChild($panel); + $panel->addChild($this->createDataChild('input')); $panel->addChild($this->createDataChild('manyToManyObjectRelation', 'objects') ->setClasses(['RelationTest']) );