Skip to content

Commit

Permalink
[Improvement]: Define default value on Multiselect Object Type (#15871)
Browse files Browse the repository at this point in the history
* Add default value for Multiselect object type

* Adjust readme for select types

* Remove multi select provider interface where possible

* Make multi select interface optional

* trigger deprecation if multi select provide interface is given

* Update models/DataObject/ClassDefinition/Helper/OptionsProviderResolver.php

Change version 12.0 to 11.1

Co-authored-by: Jacob Dreesen <jacob@hdreesen.de>

* Remove getDefaultValue method from MultiSelectOptionsProviderInterface

* Add trigger for deprecation

Co-authored-by: Jacob Dreesen <jacob@hdreesen.de>

* Revert removed Multiselect condition

* Resolve multiple default values

* Update release version

Co-authored-by: Jacob Dreesen <jacob@hdreesen.de>

* Update release version

Co-authored-by: Jacob Dreesen <jacob@hdreesen.de>

* Refactor getDataForResource()

Co-authored-by: Jacob Dreesen <jacob@hdreesen.de>

* Fix typo

Co-authored-by: Jacob Dreesen <jacob@hdreesen.de>

* Use multiple return types instead of  'mixed' type

Co-authored-by: Jacob Dreesen <jacob@hdreesen.de>

* Update docs

Co-authored-by: Jacob Dreesen <jacob@hdreesen.de>

* apply suggestions to doc

* add changelog

* limit the deprecation trigger to multiselectoption

* remove not neccessary null coalesce

* fix service only covering multiselect

---------

Co-authored-by: Jacob Dreesen <jacob@hdreesen.de>
Co-authored-by: JiaJia Ji <kingjia90@gmail.com>
  • Loading branch information
3 people committed Mar 8, 2024
1 parent 4da5b84 commit b8627f4
Show file tree
Hide file tree
Showing 7 changed files with 90 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,11 @@ services:
public: true
```

Depending on your datatype you have to implement the appropriate interface.

* `Pimcore\Model\DataObject\ClassDefinition\DynamicOptionsProvider\SelectOptionsProviderInterface` for the `Select` data type options,
* `Pimcore\Model\DataObject\ClassDefinition\DynamicOptionsProvider\MultiSelectOptionsProviderInterface` for the Multiselect options
You have to implement the `Pimcore\Model\DataObject\ClassDefinition\DynamicOptionsProvider\SelectOptionsProviderInterface`

Implement the following methods:
* `getOptions` should return a list of valid options in the format indicated below
* `getDefaultValue` (Select data type only) returning the default value
* `getDefaultValue` returning the default value
* `hasStaticOptions` should return whether your options are depending on the object context (i.e. different options for different objects) or not.
This is especially important for the object grid. For object-context depending option there will be no batch assignment mode.
Also, filtering can only be done through a text field instead of the options list.
Expand Down
2 changes: 1 addition & 1 deletion doc/23_Installation_and_Upgrade/09_Upgrade_Notes/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
- Service `Pimcore\Document\Renderer\DocumentRenderer` is deprecated, use `Pimcore\Document\Renderer\DocumentRendererInterface` instead.
#### [Data Objects]:
- Methods `getAsIntegerCast()` and `getAsFloatCast()` of the `Pimcore\Model\DataObject\Data` class are deprecated now.

- `MultiSelectOptionsProviderInterface` is deprecated, please use `SelectOptionsProviderInterface` instead.
-----------------
### General
#### [Localization]
Expand Down
53 changes: 50 additions & 3 deletions models/DataObject/ClassDefinition/Data/Multiselect.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
use Pimcore\Model;
use Pimcore\Model\DataObject;
use Pimcore\Model\DataObject\ClassDefinition\Data;
use Pimcore\Model\DataObject\ClassDefinition\DynamicOptionsProvider\MultiSelectOptionsProviderInterface;
use Pimcore\Model\DataObject\ClassDefinition\DynamicOptionsProvider\SelectOptionsProviderInterface;
use Pimcore\Model\DataObject\ClassDefinition\Service;
use Pimcore\Model\DataObject\Concrete;
use Pimcore\Normalizer\NormalizerInterface;
Expand All @@ -42,6 +44,7 @@ class Multiselect extends Data implements
use DataObject\ClassDefinition\DynamicOptionsProvider\SelectionProviderTrait;
use DataObject\Traits\DataHeightTrait;
use DataObject\Traits\DataWidthTrait;
use DataObject\Traits\DefaultValueTrait;
use OptionsProviderTrait;

/**
Expand Down Expand Up @@ -69,6 +72,11 @@ class Multiselect extends Data implements
*/
public bool $dynamicOptions = false;

/**
* @internal
*/
public ?array $defaultValue = null;

public function getOptions(): ?array
{
return $this->options;
Expand Down Expand Up @@ -114,18 +122,36 @@ public function getRenderType(): ?string
return $this->renderType;
}

public function setDefaultValue(array $defaultValue): static
{
$this->defaultValue = $defaultValue;

return $this;
}

public function getDefaultValue(): ?array
{
return $this->defaultValue;
}

/**
* @see ResourcePersistenceAwareInterface::getDataForResource
*
*
*/
public function getDataForResource(mixed $data, DataObject\Concrete $object = null, array $params = []): ?string
{
if (is_array($data)) {
if (!$this->isEmpty($data) && is_array($data)) {
return implode(',', $data);
}

return null;
$defaultValue = $this->handleDefaultValue($data, $object, $params);

if (is_array($defaultValue)) {
return implode(',', array_map(fn ($v) => $v['value'] ?? $v, $defaultValue));
}

return $defaultValue;
}

/**
Expand Down Expand Up @@ -447,7 +473,6 @@ public function getPhpdocReturnType(): ?string
*/
public function preSave(mixed $containerDefinition, array $params = []): void
{
/** @var DataObject\ClassDefinition\DynamicOptionsProvider\MultiSelectOptionsProviderInterface|null $optionsProvider */
$optionsProvider = DataObject\ClassDefinition\Helper\OptionsProviderResolver::resolveProvider(
$this->getOptionsProviderClass(),
DataObject\ClassDefinition\Helper\OptionsProviderResolver::MODE_MULTISELECT
Expand Down Expand Up @@ -510,4 +535,26 @@ public function getFieldType(): string
{
return 'multiselect';
}

protected function doGetDefaultValue(Concrete $object, array $context = []): mixed
{
/** @var SelectOptionsProviderInterface|MultiSelectOptionsProviderInterface|null $optionsProvider */
$optionsProvider = DataObject\ClassDefinition\Helper\OptionsProviderResolver::resolveProvider(
$this->getOptionsProviderClass(),
DataObject\ClassDefinition\Helper\OptionsProviderResolver::MODE_MULTISELECT
);
if ($optionsProvider instanceof SelectOptionsProviderInterface) {
$context['object'] = $object;
$context['class'] = $object->getClass();

$context['fieldname'] = $this->getName();
if (!isset($context['purpose'])) {
$context['purpose'] = 'layout';
}

return $optionsProvider->getDefaultValue($context, $this);
}

return $this->getDefaultValue();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@

use Pimcore\Model\DataObject\ClassDefinition\Data;

trigger_deprecation('pimcore/pimcore', '11.2', '%s is deprecated. Use %s instead.', MultiSelectOptionsProviderInterface::class, SelectOptionsProviderInterface::class);

/**
* @deprecated use SelectOptionsProviderInterface instead
*/
interface MultiSelectOptionsProviderInterface
{
public function getOptions(array $context, Data $fieldDefinition): array;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,22 @@

use Pimcore\Model\DataObject\ClassDefinition\Data;

interface SelectOptionsProviderInterface extends MultiSelectOptionsProviderInterface
interface SelectOptionsProviderInterface
{
public function getDefaultValue(array $context, Data $fieldDefinition): ?string;
public function getOptions(array $context, Data $fieldDefinition): array;

/**
* Whether options are depending on the object context (i.e. different options for different objects) or not.
* This is especially important for exposing options in the object grid. For options depending on object-context
* there will be no batch assignment mode, and filtering can only be done through a text field instead of the
* options list.
*
*
*/
public function hasStaticOptions(array $context, Data $fieldDefinition): bool;

/**
* @return string|array<string|array{value: string}>|null
*/
public function getDefaultValue(array $context, Data $fieldDefinition): string|array|null;
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,20 @@ class OptionsProviderResolver extends ClassResolver
public static function resolveProvider(?string $providerClass, int $mode): ?object
{
return self::resolve($providerClass, function ($provider) use ($mode) {

if ($provider instanceof MultiSelectOptionsProviderInterface){
trigger_deprecation(
'pimcore/pimcore',
'11.2',
'Implementing %s is deprecated, use %s instead',
MultiSelectOptionsProviderInterface::class,
SelectOptionsProviderInterface::class,
);
}

return ($mode == self::MODE_SELECT && ($provider instanceof SelectOptionsProviderInterface))
|| ($mode == self::MODE_MULTISELECT && ($provider instanceof MultiSelectOptionsProviderInterface));
|| ($mode == self::MODE_MULTISELECT && ($provider instanceof MultiSelectOptionsProviderInterface))
|| ($mode == self::MODE_MULTISELECT && ($provider instanceof SelectOptionsProviderInterface));
});
}
}
3 changes: 2 additions & 1 deletion models/DataObject/Service.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
use Pimcore\Model\DataObject;
use Pimcore\Model\DataObject\ClassDefinition\Data\IdRewriterInterface;
use Pimcore\Model\DataObject\ClassDefinition\Data\LayoutDefinitionEnrichmentInterface;
use Pimcore\Model\DataObject\ClassDefinition\DynamicOptionsProvider\SelectOptionsProviderInterface;
use Pimcore\Model\Element;
use Pimcore\Model\Element\DirtyIndicatorInterface;
use Pimcore\Model\Element\ElementInterface;
Expand Down Expand Up @@ -799,7 +800,7 @@ public static function getOptionsForSelectField(string|Concrete $object, ClassDe
DataObject\ClassDefinition\Helper\OptionsProviderResolver::MODE_MULTISELECT
);

if (!$definition->useConfiguredOptions() && $optionsProvider instanceof DataObject\ClassDefinition\DynamicOptionsProvider\MultiSelectOptionsProviderInterface) {
if (!$definition->useConfiguredOptions() && $optionsProvider instanceof SelectOptionsProviderInterface) {
$_options = $optionsProvider->getOptions(['fieldname' => $definition->getName()], $definition);
} else {
$_options = $definition->getOptions();
Expand Down

0 comments on commit b8627f4

Please sign in to comment.