diff --git a/src/Entity/CustomerOptions/CustomerOption.php b/src/Entity/CustomerOptions/CustomerOption.php index b703a268..19001872 100644 --- a/src/Entity/CustomerOptions/CustomerOption.php +++ b/src/Entity/CustomerOptions/CustomerOption.php @@ -54,7 +54,7 @@ public function __construct() { $this->initializeTranslationsCollection(); - $this->values = new ArrayCollection(); + $this->values = new ArrayCollection(); $this->groupAssociations = new ArrayCollection(); } @@ -76,12 +76,8 @@ public function setType(?string $type): void } $this->type = $type; - - if (CustomerOptionTypeEnum::isSelect($type)) { - $this->configuration = []; - } else { - $this->configuration = CustomerOptionTypeEnum::getConfigurationArray()[$type]; - } + + $this->configuration = CustomerOptionTypeEnum::getConfigurationArray()[$type]; } /** @@ -94,7 +90,7 @@ public function getType(): string public function getTypeCode(): ?string { - $type = $this->getType(); + $type = $this->getType(); $translations = CustomerOptionTypeEnum::getTranslateArray(); if (array_key_exists($type, $translations)) { return $translations[$type]; diff --git a/src/Enumerations/CustomerOptionTypeEnum.php b/src/Enumerations/CustomerOptionTypeEnum.php index 437db041..98fb8c80 100644 --- a/src/Enumerations/CustomerOptionTypeEnum.php +++ b/src/Enumerations/CustomerOptionTypeEnum.php @@ -118,6 +118,12 @@ public static function getFormTypeArray(): array public static function getConfigurationArray(): array { return [ + self::MULTI_SELECT => [ + 'brille24.form.config.min.choice' => ['type' => 'number', 'value' => 0], + 'brille24.form.config.max.choice' => ['type' => 'number', 'value' => 1000], + ], + self::SELECT => [ + ], self::TEXT => [ 'brille24.form.config.min.length' => ['type' => 'number', 'value' => 0], 'brille24.form.config.max.length' => ['type' => 'number', 'value' => 255], diff --git a/src/Form/Product/ShopCustomerOptionType.php b/src/Form/Product/ShopCustomerOptionType.php index 912c28ae..f9050811 100644 --- a/src/Form/Product/ShopCustomerOptionType.php +++ b/src/Form/Product/ShopCustomerOptionType.php @@ -49,11 +49,12 @@ public function __construct( CurrencyContextInterface $currencyContext, MoneyFormatterInterface $moneyFormatter, LocaleContextInterface $localeContext - ) { - $this->channelContext = $channelContext; + ) + { + $this->channelContext = $channelContext; $this->currencyContext = $currencyContext; - $this->moneyFormatter = $moneyFormatter; - $this->localeContext = $localeContext; + $this->moneyFormatter = $moneyFormatter; + $this->localeContext = $localeContext; } public function buildForm(FormBuilderInterface $builder, array $options): void @@ -69,11 +70,11 @@ public function buildForm(FormBuilderInterface $builder, array $options): void foreach ($customerOptions as $customerOption) { $customerOptionType = $customerOption->getType(); - $fieldName = $customerOption->getCode(); + $fieldName = $customerOption->getCode(); [$class, $formOptions] = CustomerOptionTypeEnum::getFormTypeArray()[$customerOptionType]; - $fieldConfig = $this->getFormConfiguration($formOptions, $customerOption, $product); + $fieldConfig = $this->getFormConfiguration($formOptions, $customerOption, $product); $fieldConfig['mapped'] = $options['mapped']; $builder->add($fieldName, $class, $fieldConfig); @@ -110,9 +111,9 @@ public function getBlockPrefix(): string /** * Gets the settings for the form type based on the type that the form field is for * - * @param array $formOptions + * @param array $formOptions * @param CustomerOptionInterface $customerOption - * @param ProductInterface $product + * @param ProductInterface $product * * @return array */ @@ -120,9 +121,10 @@ private function getFormConfiguration( array $formOptions, CustomerOptionInterface $customerOption, ProductInterface $product - ): array { + ): array + { $defaultOptions = [ - 'label' => $customerOption->getName(), + 'label' => $customerOption->getName(), 'required' => $customerOption->isRequired(), ]; @@ -132,31 +134,30 @@ private function getFormConfiguration( $customerOptionType = $customerOption->getType(); if (CustomerOptionTypeEnum::isSelect($customerOptionType)) { $configuration = [ - 'choices' => $customerOption->getValues()->toArray(), + 'choices' => $customerOption->getValues()->toArray(), 'choice_label' => function (CustomerOptionValueInterface $value) use ($product) { return $this->buildValueString($value, $product); }, 'choice_value' => 'code', ]; - } else { - $constraint = ConstraintCreator::createFromConfiguration( - $customerOptionType, - $customerOption->getConfiguration() - ); + } + $constraint = ConstraintCreator::createFromConfiguration( + $customerOptionType, + array_merge($customerOption->getConfiguration(), $configuration) + ); - if ($constraint !== null) { - $constraint->groups = ['sylius']; - $configuration = ['constraints' => [$constraint]]; - } + if ($constraint !== null) { + $constraint->groups = ['sylius']; + $configuration['constraints'] = [$constraint]; + } - if ($customerOption->isRequired()) { - /** @var NotBlank $requiredConstraint */ - $requiredConstraint = ConstraintCreator::createRequiredConstraint(); - $requiredConstraint->message = 'brille24.form.customer_options.required'; + if ($customerOption->isRequired()) { + /** @var NotBlank $requiredConstraint */ + $requiredConstraint = ConstraintCreator::createRequiredConstraint(); + $requiredConstraint->message = 'brille24.form.customer_options.required'; - $requiredConstraint->groups = ['sylius']; - $configuration['constraints'][] = $requiredConstraint; - } + $requiredConstraint->groups = ['sylius']; + $configuration['constraints'][] = $requiredConstraint; } if ($customerOptionType === CustomerOptionTypeEnum::FILE) { @@ -174,7 +175,7 @@ private function getFormConfiguration( /** * @param CustomerOptionValueInterface $value - * @param ProductInterface $product + * @param ProductInterface $product * * @return string * @@ -199,7 +200,7 @@ private function buildValueString(CustomerOptionValueInterface $value, ProductIn /** @var ChannelInterface $channel */ $channel = $this->channelContext->getChannel(); - $price = $price ?? $value->getPriceForChannel($channel); + $price = $price ?? $value->getPriceForChannel($channel); // No price was found for the current channel, probably because the values weren't updated after adding a new channel if ($price === null) { @@ -217,7 +218,7 @@ private function buildValueString(CustomerOptionValueInterface $value, ProductIn $this->localeContext->getLocaleCode(), $this->moneyFormatter ); - $name = $value->getName(); + $name = $value->getName(); return "{$name} ($valueString)"; } diff --git a/src/Resources/translations/messages.en.yml b/src/Resources/translations/messages.en.yml index d7271f33..fc1466fe 100644 --- a/src/Resources/translations/messages.en.yml +++ b/src/Resources/translations/messages.en.yml @@ -48,10 +48,12 @@ brille24: config: min: length: Minimum length + choice: Minimum number of selected items file_size: Minimum size date: Minimum date number: Minimum number max: + choice: Maximum number of selected items length: Maximum length file_size: Maximum size date: Maximum date diff --git a/src/Resources/views/CustomerOption/_form.html.twig b/src/Resources/views/CustomerOption/_form.html.twig index 476f3efc..c8d3ce2d 100644 --- a/src/Resources/views/CustomerOption/_form.html.twig +++ b/src/Resources/views/CustomerOption/_form.html.twig @@ -16,7 +16,6 @@ {% set customerOptionType = form.type.vars.value %} {% if customerOptionType == 'select' or customerOptionType == 'multi_select' %} {% include 'Brille24SyliusCustomerOptionsPlugin:CustomerOption:_values.html.twig' with {'form': form.values} only %} - {% else %} - {% include 'Brille24SyliusCustomerOptionsPlugin:CustomerOption:_configuration.html.twig' with {'form': form.configuration} only %} {% endif %} + {% include 'Brille24SyliusCustomerOptionsPlugin:CustomerOption:_configuration.html.twig' with {'form': form.configuration} only %} diff --git a/src/Services/ConstraintCreator.php b/src/Services/ConstraintCreator.php index 0f828efe..70acfbc5 100644 --- a/src/Services/ConstraintCreator.php +++ b/src/Services/ConstraintCreator.php @@ -11,13 +11,14 @@ use Symfony\Component\Validator\Constraints\Length; use Symfony\Component\Validator\Constraints\NotBlank; use Symfony\Component\Validator\Constraints\Range; +use Symfony\Component\Validator\Constraints\Choice; class ConstraintCreator { /** * Gets the value from the Customer Option value configuration * - * @param array $configuration + * @param array $configuration * @param string $key * * @return mixed @@ -35,7 +36,7 @@ public static function getValueFromConfiguration(array $configuration, string $k * Creates a constraint form the configuration based on the type of Custom Option * * @param string $type - * @param array $configuration + * @param array $configuration * * @return Constraint|null */ @@ -53,6 +54,14 @@ public static function createFromConfiguration(string $type, array $configuratio ]; return new Length($lengthRange); + case CustomerOptionTypeEnum::MULTI_SELECT: + $choiceNumberRange = [ + 'min' => $getFromConfiguration('brille24.form.config.min.choice'), + 'max' => $getFromConfiguration('brille24.form.config.max.choice'), + 'choices' => $configuration['choices'], + 'multiple' => true, + ]; + return new Choice($choiceNumberRange); case CustomerOptionTypeEnum::FILE: $allowedFileTypes = explode(',', (string) $getFromConfiguration('brille24.form.config.allowed_types')); @@ -83,7 +92,7 @@ public static function createFromConfiguration(string $type, array $configuratio public static function createConditionalConstraint(array $conditions, array $constraints): Constraint { return new ConditionalConstraint([ - 'conditions' => $conditions, + 'conditions' => $conditions, 'constraints' => $constraints, ]); }