/**
  * @inheritdoc
  */
 public function buildValuesForm(FormInterface $form, FamilyInterface $family, DataInterface $data = null, array $options = [])
 {
     $family = $data->getFamily();
     foreach ($family->getAttributes() as $attribute) {
         if (!$attribute->getGroup()) {
             // First only the attributes with no group
             $this->addAttribute($form, $attribute, $family);
         }
     }
     foreach ($family->getAttributes() as $attribute) {
         if ($attribute->getGroup()) {
             // Then only the one with a group
             $tabName = '__tab_' . $family->getCode() . '_' . $attribute->getGroup();
             if (!$form->has($tabName)) {
                 $tabOptions = ['label' => $this->getGroupLabel($family, $attribute->getGroup()), 'inherit_data' => true];
                 $icon = $this->getGroupIcon($family, $attribute->getGroup());
                 if ($icon) {
                     $tabOptions['icon'] = $icon;
                 }
                 $form->add($tabName, TabType::class, $tabOptions);
             }
             $this->addAttribute($form->get($tabName), $attribute, $family);
         }
     }
 }
 /**
  * @param DataInterface $data
  * @param string        $familyCode
  *
  * @throws WrongFamilyException
  */
 public static function assertFamily(DataInterface $data, $familyCode)
 {
     if ($data->getFamilyCode() === $familyCode) {
         return;
     }
     $backtrace = debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT, 2);
     $function = $backtrace[1]['class'] . '::' . $backtrace[1]['function'];
     $m = "Argument 1 passed to {$function} must be of family {$familyCode}, {$data->getFamilyCode()} given";
     throw new self('WrongFamilyException: ' . $m, 0, E_RECOVERABLE_ERROR, $backtrace[0]['file'], $backtrace[0]['line'], []);
 }
 /**
  * @param FormInterface   $form
  * @param FamilyInterface $family
  * @param DataInterface   $data
  * @param array           $options
  * @throws \Exception
  */
 public function buildValuesForm(FormInterface $form, FamilyInterface $family, DataInterface $data = null, array $options = [])
 {
     if ($family instanceof VariantFamily) {
         $form->add('axles', AxlesType::class, ['disabled' => $data->getId() ? true : false]);
         $axles = $form->get('axles');
         foreach ($family->getAxles() as $attribute) {
             $this->addAttribute($axles, $attribute, $family, $data, ['required' => true, 'constraints' => [new NotBlank()]]);
         }
     }
     parent::buildValuesForm($form, $family, $data, $options);
 }
 /**
  * @param DataInterface      $data
  * @param AttributeInterface $attribute
  * @param array              $context
  * @return ValueInterface
  * @throws UnexpectedValueException
  */
 public function createValue(DataInterface $data, AttributeInterface $attribute, array $context = null)
 {
     $valueClass = $this->getValueClass();
     /** @var ValueInterface $value */
     $value = new $valueClass($data, $attribute);
     $data->addValue($value);
     if ($value instanceof ContextualValueInterface && count($attribute->getContextMask())) {
         /** @var ContextualValueInterface $value */
         if (!$context) {
             $context = $this->getContext();
         }
         foreach ($attribute->getContextMask() as $key) {
             $value->setContextValue($key, $context[$key]);
         }
     }
     return $value;
 }
 /**
  * @param ExecutionContextInterface $context
  * @param AttributeInterface        $attribute
  * @param DataInterface             $data
  *
  * @throws Exception
  */
 protected function validateRules(ExecutionContextInterface $context, AttributeInterface $attribute, DataInterface $data)
 {
     if ($attribute->isMultiple()) {
         $valueData = $data->getValuesData($attribute);
     } else {
         $valueData = $data->getValueData($attribute);
     }
     $loader = new BaseLoader();
     foreach ($attribute->getValidationRules() as $validationRule) {
         foreach ($validationRule as $item => $options) {
             $constraint = $loader->newConstraint($item, $options);
             $violations = $context->getValidator()->validate($valueData, $constraint, $context->getGroup());
             /** @var ConstraintViolationInterface $violation */
             foreach ($violations as $violation) {
                 /** @noinspection DisconnectedForeachInstructionInspection */
                 $path = $attribute->getCode();
                 if ($attribute->getType()->isEmbedded()) {
                     if (!$attribute->isMultiple()) {
                         $path .= '.';
                     }
                     $path .= $violation->getPropertyPath();
                 }
                 if ($violation->getMessage()) {
                     $context->buildViolation($violation->getMessage())->atPath($path)->setInvalidValue($valueData)->addViolation();
                 } else {
                     $this->buildAttributeViolation($context, $attribute, strtolower($item), $valueData, $path);
                 }
             }
         }
     }
 }