templating = $templating; $this->translatableStringHelper = $translatableStringHelper; } public function buildForm(FormBuilderInterface $builder, CustomField $customField) { $fieldOptions = $this->prepareFieldOptions($customField); $builder->add( $builder ->create( $customField->getSlug(), ChillDateType::class, $fieldOptions ) ->addModelTransformer( new CustomFieldDataTransformer($this, $customField) ) ); } public function buildOptionsForm(FormBuilderInterface $builder) { $validatorFunction = static function ($value, ExecutionContextInterface $context) { try { $date = new DateTime($value); } catch (Exception $e) { $context->buildViolation('The expression "%expression%" is invalid', [ '%expression%' => $value, ]) ->addViolation(); } }; return $builder ->add(self::MIN, TextType::class, [ 'label' => 'Greater or equal than (expression like 1 day ago, 2 years ago, +1 month, today, tomorrow, or date with format YYYY-mm-dd)', 'required' => false, 'constraints' => [new Callback($validatorFunction)], ]) ->add(self::MAX, TextType::class, [ 'label' => 'Lesser or equal than (expression like 1 day ago, 2 years ago, +1 month, today, tomorrow, or date with format YYYY-mm-dd)', 'required' => false, 'constraints' => [new Callback($validatorFunction)], ]) ->add(self::FORMAT, ChoiceType::class, [ 'label' => 'Format', 'choices' => [ 'medium' => 'medium', 'long' => 'long', 'short' => 'short', ], ]); } public function deserialize($serialized, CustomField $customField) { if (empty($serialized)) { return null; } return DateTime::createFromFormat(self::DATE_FORMAT, $serialized); } public function getName() { return 'Date field'; } public function render($value, CustomField $customField, $documentType = 'html') { switch ($documentType) { case 'csv': $date = $this->deserialize($value, $customField); if (null === $date) { return null; } return $date->format('Y-m-d'); default: $template = 'ChillCustomFieldsBundle:CustomFieldsRendering:date.' . $documentType . '.twig'; return $this->templating ->render($template, [ 'value' => $this->deserialize($value, $customField), 'format' => $customField->getOptions()[self::FORMAT], ]); } } public function serialize($date, CustomField $customField) { if (null === $date) { return null; } return $date->format(self::DATE_FORMAT); } /** * prepare the options'form field. * * @return mixed[] */ private function prepareFieldOptions(CustomField $customField) { $options = $customField->getOptions(); /** * @var mixed[] the formField options */ $fieldOptions = []; // add required $fieldOptions['required'] = false; //add label $fieldOptions['label'] = $this->translatableStringHelper->localize($customField->getName()); // add constraints if required if (null !== $options[self::MIN]) { $fieldOptions['constraints'][] = new Callback( static function ($timestamp, ExecutionContextInterface $context) use ($options) { if (null === $timestamp) { return; } $value = DateTime::createFromFormat(self::DATE_FORMAT, $timestamp); $after = new DateTime($options[self::MIN]); if ($value < $after) { $context ->buildViolation('This date must be after or equal to %date%', [ '%date%' => $after->format('d-m-Y'), ]) ->addViolation(); } } ); } if (null !== $options[self::MAX]) { $fieldOptions['constraints'][] = new Callback( static function ($timestamp, ExecutionContextInterface $context) use ($options) { if (null === $timestamp) { return; } $value = DateTime::createFromFormat(self::DATE_FORMAT, $timestamp); $before = new DateTime($options[self::MAX]); if ($value > $before) { $context ->buildViolation('This date must be before or equal to %date%', [ '%date%' => $before->format('d-m-Y'), ]) ->addViolation(); } } ); } return $fieldOptions; } }