159 lines
4.5 KiB
PHP

<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\CustomFieldsBundle\CustomFields;
use Chill\CustomFieldsBundle\Entity\CustomField;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
use Symfony\Component\Form\Extension\Core\Type\NumberType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Validator\Constraints\GreaterThanOrEqual;
use Symfony\Component\Validator\Constraints\LessThanOrEqual;
use Twig\Environment;
/**
* Create a custom field number.
*
* This number may have a min and max value, and a precision.
*/
class CustomFieldNumber extends AbstractCustomField
{
final public const MAX = 'max';
/**
* key for the minimal value of the field.
*/
final public const MIN = 'min';
final public const POST_TEXT = 'post_text';
final public const SCALE = 'scale';
public function __construct(
private readonly Environment $templating,
private readonly TranslatableStringHelper $translatableStringHelper
) {
}
public function buildForm(FormBuilderInterface $builder, CustomField $customField)
{
$options = $customField->getOptions();
// select the type depending to the SCALE
$type = (0 === $options[self::SCALE] || null === $options[self::SCALE]) ?
IntegerType::class : NumberType::class;
// 'integer' : 'number';
$fieldOptions = $this->prepareFieldOptions($customField, $type);
$builder->add($customField->getSlug(), $type, $fieldOptions);
}
public function buildOptionsForm(FormBuilderInterface $builder)
{
return $builder
->add(self::MIN, NumberType::class, [
'scale' => 2,
'label' => 'Greater or equal than',
'required' => false,
])
->add(self::MAX, NumberType::class, [
'scale' => 2,
'label' => 'Lesser or equal than',
'required' => false,
])
->add(self::SCALE, IntegerType::class, [
'scale' => 0,
'label' => 'Precision',
'constraints' => [
new GreaterThanOrEqual(['value' => 0]),
],
])
->add(self::POST_TEXT, TextType::class, [
'label' => 'Text after the field',
]);
}
public function deserialize($serialized, CustomField $customField)
{
return $serialized;
}
public function getName()
{
return 'Number field';
}
public function render($value, CustomField $customField, $documentType = 'html')
{
$template = '@ChillCustomFields/CustomFieldsRendering/number.'
.$documentType.'.twig';
$options = $customField->getOptions();
return $this->templating
->render($template, [
'number' => $value,
'scale' => $options[self::SCALE],
'post' => $options[self::POST_TEXT],
]);
}
public function serialize($value, CustomField $customField)
{
return $value;
}
/**
* prepare the options'form field.
*
* @param string $type
*
* @return mixed[]
*/
private function prepareFieldOptions(CustomField $customField, $type)
{
$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 GreaterThanOrEqual(['value' => $options[self::MIN]]);
}
if (null !== $options[self::MAX]) {
$fieldOptions['constraints'][] = new LessThanOrEqual(['value' => $options[self::MAX]]);
}
// add precision to options if required
if ('number' === $type) {
$fieldOptions['scale'] = $options[self::SCALE];
}
if (!empty($options[self::POST_TEXT])) {
$fieldOptions['post_text'] = $options[self::POST_TEXT];
}
return $fieldOptions;
}
}