Skip to content

Commit 23fc32c

Browse files
committed
Merge remote-tracking branch 'origin/1.7' into 2.2
# Conflicts: # public/js/pimcore/element/helpers/gridColumnConfig.js
2 parents cc9957b + b491617 commit 23fc32c

File tree

8 files changed

+147
-87
lines changed

8 files changed

+147
-87
lines changed

public/js/pimcore/element/helpers/gridColumnConfig.js

Lines changed: 60 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -435,34 +435,63 @@ pimcore.element.helpers.gridColumnConfig = {
435435

436436
editor.fieldConfig.width = 300;
437437

438-
const formPanel = Ext.create('Ext.form.Panel', {
439-
xtype: "form",
440-
border: false,
441-
items: [editor.getLayoutEdit()],
442-
bodyStyle: "padding: 10px;",
443-
buttons: [
444-
{
445-
text: t("clear_relation_filter"),
446-
iconCls: "pimcore_icon_filter_condition pimcore_icon_overlay_delete",
447-
handler: function () {
448-
this.filterByRelationWindow.close();
449-
this.grid.store.filters.removeByKey("x-gridfilter-"+fieldInfo.dataIndex);
450-
}.bind(this)
451-
},
452-
{
453-
text: t("apply_filter"),
454-
iconCls: "pimcore_icon_filter pimcore_icon_overlay_add",
455-
handler: function () {
456-
if (formPanel.isValid() && typeof fieldInfo.getRelationFilter === "function") {
457-
this.grid.filters.getStore().addFilter(
458-
fieldInfo.getRelationFilter(fieldInfo.dataIndex, editor)
459-
);
460-
this.filterByRelationWindow.close();
461-
}
462-
}.bind(this)
438+
const activeFilter = this.grid.getStore().getFilters().items;
439+
440+
for (let filter of activeFilter) {
441+
if (filter.dataIndex !== fieldInfo.dataIndex) {
442+
continue;
463443
}
464-
]
465-
});
444+
editor.data = filter.getValue()
445+
.split(",")
446+
.map(v => ({ id: Number.parseInt(v.trim()) }))
447+
.filter(v => !Number.isNaN(v.id));
448+
editor.store.loadData(items, false);
449+
break;
450+
}
451+
452+
const formPanel = Ext.create('Ext.form.Panel', {
453+
xtype: "form",
454+
border: false,
455+
items: [editor.getLayoutEdit()],
456+
bodyStyle: "padding: 10px;",
457+
buttons: [
458+
{
459+
text: t("clear_relation_filter"),
460+
iconCls: "pimcore_icon_filter_condition pimcore_icon_overlay_delete",
461+
handler: function () {
462+
this.filterByRelationWindow.close();
463+
this.grid.store.filters.removeByKey("x-gridfilter-"+fieldInfo.dataIndex);
464+
}.bind(this)
465+
},
466+
{
467+
text: t("apply_filter"),
468+
iconCls: "pimcore_icon_filter pimcore_icon_overlay_add",
469+
handler: function () {
470+
if (formPanel.isValid() && typeof fieldInfo.getRelationFilter === "function") {
471+
try {
472+
// Sync editor store with its current value (if applicable)
473+
const value = editor.getValue();
474+
let items = [];
475+
if (Array.isArray(value)) {
476+
items = value;
477+
} else if (value) {
478+
items = [value];
479+
}
480+
editor.store.loadData(items, false);
481+
482+
this.grid.filters.getStore().addFilter(
483+
fieldInfo.getRelationFilter(fieldInfo.dataIndex, editor)
484+
);
485+
this.filterByRelationWindow.close();
486+
} catch (e) {
487+
console.error("Error applying relation filter:", e);
488+
pimcore.helpers.showNotification(t("error"), e.message || e, "error");
489+
}
490+
}
491+
}.bind(this)
492+
}
493+
]
494+
});
466495

467496
const title = t("filter_by_relation_field") + " " + fieldInfo.text;
468497
let width = 700;
@@ -970,6 +999,10 @@ pimcore.element.helpers.gridColumnConfig = {
970999
params["only_direct_children"] = this.checkboxOnlyDirectChildren.getValue();
9711000
}
9721001

1002+
if (typeof this.selectObjectType !=='undefined') {
1003+
params['filter_by_object_type'] = this.selectObjectType.getValue();
1004+
}
1005+
9731006
//only unreferenced filter
9741007
if (this.checkboxOnlyUnreferenced) {
9751008
params["only_unreferenced"] = this.checkboxOnlyUnreferenced.getValue();

public/js/pimcore/object/class.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,12 @@ pimcore.object.klass = Class.create({
1616

1717
forbiddenNames: [
1818
"abstract", "class", "data", "folder", "list", "permissions", "resource", "concrete", "interface",
19-
"service", "fieldcollection", "localizedfield", "objectbrick", "default"
19+
"service", "fieldcollection", "localizedfield", "objectbrick", "default",
20+
"abstractobject", "classdefinition", "classdefinitioninterface", "classificationstore",
21+
"definitionmodifier", "importdataserviceinterface", "lazyloadedfieldsinterface", "listing",
22+
"objectawarefieldinterface", "ownerawarefieldinterface", "pregetvaluehookinterface",
23+
"selectoptionsinterface"
2024
],
21-
2225
initialize: function () {
2326

2427
this.getTabPanel();

public/js/pimcore/object/classificationstore/groupsPanel.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,13 @@ pimcore.object.classificationstore.groupsPanel = Class.create({
399399
this.relationsPanel.setTitle(t("relations") + " - " + t("group") + " " + record.data.id + " - " + groupName);
400400
this.relationsPanel.enable();
401401
this.relationsStore.getProxy().setExtraParam("groupId", groupId);
402-
this.relationsStore.reload();
402+
403+
// reset paging params
404+
this.relationsStore.reload({
405+
page: 1,
406+
start: 0
407+
});
408+
403409
this.relationsGrid.show();
404410
}
405411
}.bind(this)

src/Controller/Admin/DataObject/ClassificationstoreController.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1475,7 +1475,14 @@ private function getTranslatedSearchFilterTerms(string $searchTerm): array
14751475
if ($user instanceof User) {
14761476
$translationListing = new Listing();
14771477
$translationListing->setDomain(Translation::DOMAIN_ADMIN);
1478-
$translationListing->setCondition('language=? AND text LIKE ?', [$user->getLanguage(), '%'.$searchTerm.'%']);
1478+
$translationListing->setCondition(
1479+
$translationListing->quoteIdentifier('language') . ' = ? AND ' .
1480+
$translationListing->quoteIdentifier('text') . ' LIKE ?',
1481+
[
1482+
$user->getLanguage(),
1483+
'%' . $searchTerm . '%',
1484+
]
1485+
);
14791486

14801487
foreach ($translationListing as $translation) {
14811488
$terms[] = $translation->getKey();

src/DependencyInjection/PimcoreAdminExtension.php

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,13 @@
1313

1414
namespace Pimcore\Bundle\AdminBundle\DependencyInjection;
1515

16-
use Pimcore;
1716
use Pimcore\Bundle\CoreBundle\DependencyInjection\ConfigurationHelper;
18-
use Pimcore\Bundle\SimpleBackendSearchBundle\PimcoreSimpleBackendSearchBundle;
1917
use Pimcore\Config\LocationAwareConfigRepository;
2018
use Symfony\Component\Config\FileLocator;
2119
use Symfony\Component\DependencyInjection\ContainerBuilder;
2220
use Symfony\Component\DependencyInjection\Extension\Extension;
2321
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
2422
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
25-
use Symfony\Component\Yaml\Yaml;
2623

2724
/**
2825
* @internal
@@ -51,33 +48,6 @@ public function load(array $configs, ContainerBuilder $container): void
5148
$loader->load('event_listeners.yaml');
5249
$loader->load('export.yaml');
5350

54-
// Check if PimcoreSimpleBackendSearchBundle is installed and load to replace the search data provider services
55-
try {
56-
$bundle = Pimcore::getKernel()->getBundle('PimcoreSimpleBackendSearchBundle');
57-
$configFile = $bundle->getPath() . '/config/admin-classic.yaml';
58-
59-
$yaml = Yaml::parseFile($configFile);
60-
61-
$tmpFile = tempnam(sys_get_temp_dir(), 'services_');
62-
63-
try {
64-
file_put_contents(
65-
$tmpFile,
66-
Yaml::dump(['services' => $yaml['services']])
67-
);
68-
69-
$loader = new YamlFileLoader($container, new FileLocator(dirname($tmpFile)));
70-
71-
$loader->load(basename($configFile));
72-
} finally {
73-
if (is_file($tmpFile)) {
74-
unlink($tmpFile);
75-
}
76-
}
77-
} catch (\Exception $e) {
78-
// no simple backend search bundle installed
79-
}
80-
8151
// Merge
8252
//Set Config for GDPR data providers to container parameters
8353
$container->setParameter('pimcore.gdpr-data-extrator.dataobjects', $config['gdpr_data_extractor']['dataObjects']);

src/Helper/GridHelperService.php

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -829,6 +829,7 @@ public function prepareAssetListingForGrid(array $allParams, User $adminUser): M
829829
$filters = json_decode($filterJson, true);
830830
foreach ($filters as $filter) {
831831
$operator = '=';
832+
$notSubselect = '';
832833

833834
$filterDef = explode('~', $filter['property']);
834835
$filterField = $filterDef[0];
@@ -874,7 +875,10 @@ public function prepareAssetListingForGrid(array $allParams, User $adminUser): M
874875
$operator = 'IN';
875876
} elseif ($filterType == 'boolean') {
876877
$operator = '=';
877-
$filter['value'] = (int) $filter['value'];
878+
if ((int) $filter['value'] === 0) {
879+
$notSubselect = 'NOT';
880+
}
881+
$filter['value'] = 1;
878882
}
879883
// system field
880884
$value = $filter['value'] ?? '';
@@ -907,7 +911,12 @@ public function prepareAssetListingForGrid(array $allParams, User $adminUser): M
907911
$language = $filterDef[1];
908912
}
909913
$language = str_replace(['none', 'default'], '', $language);
910-
$conditionFilters[] = 'id IN (SELECT cid FROM assets_metadata WHERE `name` = ' . $db->quote($filterField) . ' AND `data` ' . $operator . ' ' . $value . ' AND `language` = ' . $db->quote($language). ')';
914+
$conditionFilters[] =
915+
'id ' . $notSubselect .
916+
' IN (SELECT cid FROM assets_metadata WHERE `name` = ' . $db->quote($filterField) .
917+
' AND `data` ' . $operator . ' ' . $value .
918+
' AND `language` = ' . $db->quote($language).
919+
')';
911920
}
912921
}
913922
}

src/Security/ContentSecurityPolicyHandler.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ public function configureOptions(OptionsResolver $resolver): void
7979
self::DEFAULT_OPT => self::SELF,
8080
self::IMG_OPT => '* data: blob:',
8181
self::MEDIA_OPT => self::SELF . ' data:',
82-
self::SCRIPT_OPT => self::SELF . " 'nonce-" . $this->getNonce() . "' 'unsafe-inline' 'unsafe-eval'",
82+
self::SCRIPT_OPT => self::SELF . " 'nonce-" . $this->getNonce() . "' 'unsafe-eval'",
8383
self::STYLE_OPT => self::SELF . " 'unsafe-inline'",
8484
self::FRAME_OPT => self::SELF . ' data:',
8585
self::FRAME_ANCHESTORS => self::SELF,

src/Service/GridData/DataObject.php

Lines changed: 55 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use Pimcore\Model;
1818
use Pimcore\Model\DataObject\AbstractObject;
1919
use Pimcore\Model\DataObject\ClassDefinition;
20+
use Pimcore\Model\DataObject\ClassDefinition\Data;
2021
use Pimcore\Model\DataObject\Classificationstore;
2122
use Pimcore\Model\DataObject\Concrete;
2223
use Pimcore\Model\DataObject\Objectbrick;
@@ -182,21 +183,27 @@ public static function getData(AbstractObject $object, ?array $fields = null, ?s
182183
}
183184

184185
// because the key for the classification store has not a direct getter, you have to check separately if the data is inheritable
185-
if (str_starts_with($key, '~')) {
186-
$curClassAttributeValue = $data[$key] ?? null;
187-
$isValueEmpty = is_array($curClassAttributeValue) ? empty($curClassAttributeValue['value'] ?? null) : empty($curClassAttributeValue);
188-
189-
if ($isValueEmpty) {
190-
$type = $keyParts[1];
191-
192-
if ($type === 'classificationstore') {
193-
if (!empty($inheritedData = self::getInheritedData($object, $key, $requestedLanguage))) {
194-
$data[$dataKey] = $inheritedData['value'];
195-
$data['inheritedFields'][$dataKey] = ['inherited' => $inheritedData['parent']->getId() != $object->getId(), 'objectid' => $inheritedData['parent']->getId()];
196-
}
186+
if (
187+
str_starts_with($key, '~') &&
188+
($keyParts[1] ?? null) === 'classificationstore'
189+
) {
190+
$fieldDef = self::getClassificationStoreFieldDefinition($key);
191+
$value = self::normalizeValue($data[$key]);
192+
193+
if ($fieldDef->isEmpty($value)) {
194+
$inheritedData = static::getInheritedData($object, $key, $requestedLanguage);
195+
196+
if (!empty($inheritedData)) {
197+
$parent = $inheritedData['parent'];
198+
$data[$dataKey] = $inheritedData['value'];
199+
$data['inheritedFields'][$dataKey] = [
200+
'inherited' => $parent->getId() !== $object->getId(),
201+
'objectid' => $parent->getId(),
202+
];
197203
}
198204
}
199205
}
206+
200207
if ($needLocalizedPermissions) {
201208
if (!$user->isAdmin()) {
202209
$locale = \Pimcore::getContainer()->get(LocaleServiceInterface::class)->findLocale();
@@ -355,17 +362,9 @@ protected static function getInheritedData(Concrete $object, string $key, string
355362
return [];
356363
}
357364

358-
$inheritedValue = self::getStoreValueForObject($parent, $key, $requestedLanguage);
359-
if (
360-
(!is_array($inheritedValue) && $inheritedValue !== null) ||
361-
(
362-
is_array($inheritedValue) &&
363-
(
364-
array_is_list($inheritedValue) || //for table field types
365-
!empty($inheritedValue['value'] ?? null)
366-
)
367-
)
368-
) {
365+
$inheritedValue = self::normalizeValue(self::getStoreValueForObject($parent, $key, $requestedLanguage));
366+
367+
if (!static::getClassificationStoreFieldDefinition($key)->isEmpty($inheritedValue)) {
369368
return [
370369
'parent' => $parent,
371370
'value' => $inheritedValue,
@@ -374,4 +373,37 @@ protected static function getInheritedData(Concrete $object, string $key, string
374373

375374
return self::getInheritedData($parent, $key, $requestedLanguage);
376375
}
376+
377+
/**
378+
* The actual data could be a plain array for tables,
379+
* an associative array for RGB or Quantity Value where the value is a key.
380+
*
381+
*/
382+
private static function normalizeValue(mixed $data): mixed
383+
{
384+
if (is_array($data)) {
385+
if (array_is_list($data)) {
386+
return $data;
387+
}
388+
if (array_key_exists('value', $data)) {
389+
return $data['value'];
390+
}
391+
}
392+
393+
return $data;
394+
}
395+
396+
protected static function getClassificationStoreFieldDefinition(string $key): Data
397+
{
398+
$keyParts = explode('~', $key);
399+
$groupKeyId = explode('-', $keyParts[3]);
400+
401+
$keyid = (int) $groupKeyId[1];
402+
403+
$keyConfig = Model\DataObject\Classificationstore\KeyConfig::getById($keyid);
404+
$type = $keyConfig->getType();
405+
$definition = json_decode($keyConfig->getDefinition(), true);
406+
407+
return \Pimcore\Model\DataObject\Classificationstore\Service::getFieldDefinitionFromJson($definition, $type);
408+
}
377409
}

0 commit comments

Comments
 (0)