/**
  * @param OptionsResolver $resolver
  * @throws AccessException
  * @throws UndefinedOptionsException
  * @throws MissingFamilyException
  * @throws \UnexpectedValueException
  * @throws ConstraintDefinitionException
  * @throws InvalidOptionsException
  * @throws MissingOptionsException
  */
 public function configureOptions(OptionsResolver $resolver)
 {
     $resolver->setDefaults(['required' => true, 'constraints' => new NotBlank()]);
     $resolver->setRequired(['attribute', 'parent_data']);
     $resolver->setNormalizer('attribute', function (Options $options, $value) {
         return VariantType::normalizeVariantAttribute($value);
     });
     $resolver->setNormalizer('parent_data', function (Options $options, $value) {
         return VariantType::normalizeParentData($options, $value);
     });
     $resolver->setNormalizer('choices', function (Options $options, $value) {
         $attribute = $options['attribute'];
         $families = [];
         /** @var array $variantFamilies */
         $variantFamilies = $attribute->getOptions()['variant_families'];
         foreach ($variantFamilies as $familyCode) {
             $family = $this->familyConfigurationHandler->getFamily($familyCode);
             if (!$family instanceof VariantFamily) {
                 throw new \UnexpectedValueException("Variant families in attribute options must be of type VariantFamily, '{$family->getCode()}' is not a variant");
             }
             $families[ucfirst($family)] = $family;
         }
         return $families;
     });
 }
 /**
  * @param string                     $code
  * @param Registry                   $doctrine
  * @param FilterFactory              $filterFactory
  * @param array                      $configuration
  * @param FamilyConfigurationHandler $familyConfigurationHandler
  *
  * @throws UnexpectedValueException
  */
 public function __construct($code, Registry $doctrine, FilterFactory $filterFactory, array $configuration, FamilyConfigurationHandler $familyConfigurationHandler)
 {
     if (!$familyConfigurationHandler->hasFamily($configuration['family'])) {
         throw new UnexpectedValueException("Unknown family '{$configuration['family']}'");
     }
     $this->family = $familyConfigurationHandler->getFamily($configuration['family']);
     unset($configuration['family']);
     $configuration['entity'] = $this->family->getDataClass();
     parent::__construct($code, $doctrine, $filterFactory, $configuration);
 }
 /**
  * @param OptionsResolver $resolver
  * @throws \Exception
  */
 public function configureOptions(OptionsResolver $resolver)
 {
     $resolver->setDefaults(['choices_as_values' => true, 'choices' => null, 'families' => null]);
     $resolver->setNormalizer('families', function (Options $options, $values) {
         if (null === $values) {
             $values = $this->familyConfigurationHandler->getFamilies();
         }
         $families = [];
         foreach ($values as $value) {
             if (!$value instanceof FamilyInterface) {
                 $value = $this->familyConfigurationHandler->getFamily($value);
             }
             if ($value->isInstantiable()) {
                 $families[$value->getCode()] = $value;
             }
         }
         return $families;
     });
     $resolver->setNormalizer('choices_as_values', function (Options $options, $value) {
         if ($value !== true) {
             throw new \UnexpectedValueException("'choices_as_values' must be true (and is by default)");
         }
         return true;
     });
     $resolver->setNormalizer('choices', function (Options $options, $value) {
         if (null !== $value) {
             throw new \UnexpectedValueException("'choices' options is not supported for family selector, please use 'families' option");
         }
         $choices = [];
         /** @var FamilyInterface[] $families */
         $families = $options['families'];
         foreach ($families as $family) {
             if ($family->isInstantiable()) {
                 $choices[ucfirst($family)] = $family->getCode();
             }
         }
         return $choices;
     });
 }
 /**
  * @param FormView      $view
  * @param FormInterface $form
  * @param array         $options
  * @throws \UnexpectedValueException
  * @throws \LogicException
  * @throws \Sidus\EAVModelBundle\Exception\MissingFamilyException
  */
 public function buildView(FormView $view, FormInterface $form, array $options)
 {
     if (!$form->getData() instanceof DataInterface) {
         throw new \UnexpectedValueException('Form data must be an EAV Data');
     }
     /** @var AttributeInterface $attribute */
     $attribute = $options['attribute'];
     /** @var DataInterface $data */
     $data = $form->getData();
     $view->vars['data'] = $data;
     $variantFamiliesOption = $attribute->getOption('variant_families');
     if (empty($variantFamiliesOption)) {
         throw new \LogicException('Variant attribute must have at least one variant family in the variant_families option');
     }
     $variantFamilies = [];
     foreach ($variantFamiliesOption as $code) {
         $variantFamilies[] = $this->familyConfigurationHandler->getFamily($code);
     }
     $view->vars['variant_families'] = $variantFamilies;
     $view->vars['routes'] = $this->routes;
     $view->vars['variants'] = $data->getValuesData($attribute);
     $view->vars['base_route_parameters'] = ['attribute' => $attribute->getCode(), 'parentId' => $data->getId()];
 }
 /**
  * @param string                        $code
  * @param AttributeConfigurationHandler $attributeConfigurationHandler
  * @param FamilyConfigurationHandler    $familyConfigurationHandler
  * @param ContextManager                $contextManager
  * @param array                         $config
  * @throws UnexpectedValueException
  * @throws MissingFamilyException
  * @throws AccessException
  * @throws InvalidArgumentException
  * @throws UnexpectedTypeException
  */
 public function __construct($code, AttributeConfigurationHandler $attributeConfigurationHandler, FamilyConfigurationHandler $familyConfigurationHandler, ContextManager $contextManager, array $config = null)
 {
     $this->code = $code;
     $this->contextManager = $contextManager;
     if (!empty($config['parent'])) {
         $this->parent = $familyConfigurationHandler->getFamily($config['parent']);
         $this->copyFromFamily($this->parent);
     }
     unset($config['parent']);
     foreach ($config['attributes'] as $attribute) {
         $this->attributes[$attribute] = $attributeConfigurationHandler->getAttribute($attribute);
     }
     unset($config['attributes']);
     if (!empty($config['attributeAsLabel'])) {
         $labelCode = $config['attributeAsLabel'];
         if (!$this->hasAttribute($labelCode)) {
             $message = "Bad configuration for family {$code}: attribute as label '{$labelCode}'";
             $message .= " doesn't exists for this family";
             throw new UnexpectedValueException($message);
         }
         $this->attributeAsLabel = $this->getAttribute($labelCode);
     }
     unset($config['attributeAsLabel']);
     if (!empty($config['attributeAsIdentifier'])) {
         $labelCode = $config['attributeAsIdentifier'];
         $commonMessage = "Bad configuration for family {$code}: attribute as identifier '{$labelCode}'";
         if (!$this->hasAttribute($labelCode)) {
             throw new UnexpectedValueException("{$commonMessage} doesn't exists for this family");
         }
         $this->attributeAsIdentifier = $this->getAttribute($labelCode);
         if (!$this->attributeAsIdentifier->isUnique()) {
             throw new UnexpectedValueException("{$commonMessage} should be unique");
         }
         if (!$this->attributeAsIdentifier->isRequired()) {
             throw new UnexpectedValueException("{$commonMessage} should be required");
         }
         if ($this->attributeAsIdentifier->isMultiple()) {
             throw new UnexpectedValueException("{$commonMessage} should NOT be multiple");
         }
         if (0 !== count($this->attributeAsIdentifier->getContextMask())) {
             throw new UnexpectedValueException("{$commonMessage} should NOT be contextualized");
         }
     }
     unset($config['attributeAsIdentifier']);
     $accessor = PropertyAccess::createPropertyAccessor();
     foreach ($config as $key => $value) {
         $accessor->setValue($this, $key, $value);
     }
 }
 /**
  * @param OptionsResolver $resolver
  *
  * @throws \Exception
  */
 public function configureOptions(OptionsResolver $resolver)
 {
     $resolver->setDefaults(['families' => null]);
     $resolver->setNormalizer('families', function (Options $options, $values) {
         if (null === $values) {
             $values = $this->familyConfigurationHandler->getFamilies();
         }
         $families = [];
         foreach ($values as $value) {
             if (!$value instanceof FamilyInterface) {
                 $value = $this->familyConfigurationHandler->getFamily($value);
             }
             if ($value->isInstantiable()) {
                 $families[$value->getCode()] = $value;
             }
         }
         return $families;
     });
 }
 /**
  * @param OptionsResolver $resolver
  * @throws AccessException
  * @throws UndefinedOptionsException
  * @throws UnexpectedValueException
  * @throws MissingFamilyException
  */
 public function configureOptions(OptionsResolver $resolver)
 {
     $resolver->setDefaults(['class' => $this->dataClass, 'search_fields' => ['v.stringValue'], 'template' => 'SidusEAVModelBundle:Data:data_autocomplete.html.twig', 'family' => null, 'auto_init' => true]);
     $resolver->setNormalizer('family', function (Options $options, $value) {
         if (null === $value) {
             return null;
         }
         if ($value instanceof FamilyInterface) {
             return $value;
         }
         return $this->familyConfigurationHandler->getFamily($value);
     });
     $resolver->setNormalizer('disabled', function (Options $options, $value) {
         if (null === $options['family']) {
             return true;
         }
         return $value;
     });
 }
 /**
  * @param OptionsResolver $resolver
  *
  * @throws AccessException
  * @throws UndefinedOptionsException
  * @throws MissingFamilyException
  * @throws \UnexpectedValueException
  */
 public function configureOptions(OptionsResolver $resolver)
 {
     $resolver->setDefaults(['family' => null, 'data_class' => $this->dataClass]);
     $resolver->setNormalizer('family', function (Options $options, $value) {
         if ($value === null) {
             return null;
         }
         if ($value instanceof FamilyInterface) {
             return $value;
         }
         return $this->familyConfigurationHandler->getFamily($value);
     });
     $resolver->setNormalizer('empty_data', function (Options $options, $value) {
         if ($options['family'] instanceof FamilyInterface) {
             return $options['family']->createData();
         }
         return $value;
     });
     $resolver->setNormalizer('data_class', function (Options $options, $value) {
         if ($options['family'] instanceof FamilyInterface) {
             return $options['family']->getDataClass();
         }
         return $value;
     });
     $resolver->setNormalizer('data', function (Options $options, $value) {
         if (null === $value) {
             return null;
         }
         if (!$value instanceof DataInterface) {
             throw new \UnexpectedValueException("The 'data' option should be a DataInterface");
         }
         if ($options['family'] instanceof FamilyInterface) {
             $dataClass = $options['family']->getDataClass();
             if (!is_a($value, $dataClass)) {
                 throw new \UnexpectedValueException("The 'data' option should be a {$dataClass}");
             }
         }
         return $value;
     });
 }
 /**
  * @param string $value
  * @return FamilyInterface
  * @throws MissingFamilyException
  */
 protected function convertValue($value)
 {
     return $this->familyConfigurationHandler->getFamily($value);
 }