diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b89172e8..22bbd53b3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -146,3 +146,7 @@ Version 1.5.21 - [CRUD] Forward query parameters when pushing button "save and new" in "create" page; - [Show/hide] Take selects input into account; +Version 1.5.23 +============== + +- [address] allow to add custom fields to addresses diff --git a/Entity/Address.php b/Entity/Address.php index 76ceb8688..63e7b4479 100644 --- a/Entity/Address.php +++ b/Entity/Address.php @@ -44,6 +44,13 @@ class Address */ private $isNoAddress = false; + /** + * A list of metadata, added by customizable fields + * + * @var array + */ + private $customs = []; + public function __construct() { $this->validFrom = new \DateTime(); @@ -183,6 +190,29 @@ class Address return $this; } + /** + * Get customs informations in the address + * + * @return array + */ + public function getCustoms(): array + { + return $this->customs; + } + + /** + * Store custom informations in the address + * + * @param array $customs + * @return $this + */ + public function setCustoms(array $customs): self + { + $this->customs = $customs; + + return $this; + } + /** * Validate the address. * diff --git a/Form/Type/AddressType.php b/Form/Type/AddressType.php index 4a0e222b8..96012054e 100644 --- a/Form/Type/AddressType.php +++ b/Form/Type/AddressType.php @@ -39,6 +39,8 @@ use Symfony\Component\Form\Extension\Core\Type\ChoiceType; * - `null_if_empty` (boolean): replace the address type by null if the street * or the postCode is empty. This is useful when the address is not required and * embedded in another form. + * - `customize_data` (callable): allow to add custom field to the form, which + * will be store in the `customs` property */ class AddressType extends AbstractType { @@ -80,9 +82,19 @@ class AddressType extends AbstractType ]); } + if ($options['customize_data'] !== NULL && is_callable($options['customize_data'])) { + $customsBuilder = $builder->create('customs', NULL, [ + 'compound' => true, + 'label' => false + ]); + \call_user_func($options['customize_data'], $customsBuilder); + $builder->add($customsBuilder); + } + if ($options['null_if_empty'] === TRUE) { $builder->setDataMapper(new AddressDataMapper()); } + } public function configureOptions(OptionsResolver $resolver) @@ -98,6 +110,8 @@ class AddressType extends AbstractType ->setDefined('null_if_empty') ->setDefault('null_if_empty', false) ->setAllowedTypes('null_if_empty', 'bool') + ->setDefined('customize_data') + ->setAllowedTypes('customize_data', 'callable') ; } } diff --git a/Resources/config/doctrine/Address.orm.yml b/Resources/config/doctrine/Address.orm.yml index efba9070a..58a80d671 100644 --- a/Resources/config/doctrine/Address.orm.yml +++ b/Resources/config/doctrine/Address.orm.yml @@ -19,6 +19,9 @@ Chill\MainBundle\Entity\Address: isNoAddress: type: boolean default: false + customs: + type: json + default: [] manyToOne: postcode: targetEntity: Chill\MainBundle\Entity\PostalCode diff --git a/Resources/config/services/templating.yml b/Resources/config/services/templating.yml index 49836e3f9..5b927b7ac 100644 --- a/Resources/config/services/templating.yml +++ b/Resources/config/services/templating.yml @@ -29,4 +29,10 @@ services: Chill\MainBundle\Templating\Entity\ChillEntityRenderExtension: tags: - - { name: twig.extension } \ No newline at end of file + - { name: twig.extension } + + Chill\MainBundle\Templating\Entity\AddressRendering: + arguments: + $twig: '@templating.engine.twig' + tags: + - { name: 'chill.render_entity' } \ No newline at end of file diff --git a/Resources/views/Address/macro.html.twig b/Resources/views/Address/macro.html.twig index fd74ec115..44157ec59 100644 --- a/Resources/views/Address/macro.html.twig +++ b/Resources/views/Address/macro.html.twig @@ -1,20 +1,5 @@ {%- macro _render(address, options) -%} + {{ address|chill_entity_render_box( options|default({}) ) }} {%- set options = { 'with_valid_from' : true }|merge(options|default({})) -%} {%- set options = { 'has_no_address' : false }|merge(options|default({})) -%} -
- {% if options['has_no_address'] == true and address.isNoAddress == true %} -
{{ 'address.consider homeless'|trans }}
- {% endif %} -
- {% if address.streetAddress1 is not empty %}

{{ address.streetAddress1 }}

{% endif %} - {% if address.streetAddress2 is not empty %}

{{ address.streetAddress2 }}

{% endif %} - {% if address.postCode is not empty %} -

{{ address.postCode.code }} {{ address.postCode.name }}

-

{{ address.postCode.country.name|localize_translatable_string }}

- {% endif %} -
- {%- if options['with_valid_from'] == true -%} - {{ 'Since %date%'|trans( { '%date%' : address.validFrom|localizeddate('long', 'none') } ) }} - {%- endif -%} -
{%- endmacro -%} diff --git a/Resources/views/Address/render_box_address.html.twig b/Resources/views/Address/render_box_address.html.twig new file mode 100644 index 000000000..d5f8a478c --- /dev/null +++ b/Resources/views/Address/render_box_address.html.twig @@ -0,0 +1,19 @@ +
+ {% if options['has_no_address'] == true and address.isNoAddress == true %} +
{{ 'address.consider homeless'|trans }}
+ {% endif %} +
+ {% if address.streetAddress1 is not empty %}

{{ address.streetAddress1 }}

{% endif %} + {% if address.streetAddress2 is not empty %}

{{ address.streetAddress2 }}

{% endif %} + {% if address.postCode is not empty %} +

{{ address.postCode.code }} {{ address.postCode.name }}

+

{{ address.postCode.country.name|localize_translatable_string }}

+ {% endif %} +
+{%- if options['with_valid_from'] == true -%} +{{ 'Since %date%'|trans( { '%date%' : address.validFrom|localizeddate('long', 'none') } ) }} +{%- endif -%} +{% for k,v in address.customs %} + {{ ('address.customs.' ~ k)|trans }} : {{ v }} +{% endfor %} +
diff --git a/Resources/views/Form/fields.html.twig b/Resources/views/Form/fields.html.twig index 97e2896dc..b9e31aaf3 100644 --- a/Resources/views/Form/fields.html.twig +++ b/Resources/views/Form/fields.html.twig @@ -182,4 +182,14 @@ {% endif %} +{% endblock %} + +{% block address_widget %} + {% for entry in form %} + {% if entry.vars.name != 'customs' %} + {{ form_row(entry) }} + {% else %} + {{ form_widget(entry) }} + {% endif %} + {% endfor %} {% endblock %} \ No newline at end of file diff --git a/Templating/Entity/AddressRendering.php b/Templating/Entity/AddressRendering.php new file mode 100644 index 000000000..ff3fd5791 --- /dev/null +++ b/Templating/Entity/AddressRendering.php @@ -0,0 +1,84 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +namespace Chill\MainBundle\Templating\Entity; + +use Chill\MainBundle\Entity\Address; +use Symfony\Bundle\TwigBundle\TwigEngine; + +/** + * Render entity `Address` + * + * options: + * + * `with_valid_from`: add validity date to the rendering + * `has_no_address`: add information if the address "is no address" homeless + * + */ +class AddressRendering implements ChillEntityRenderInterface +{ + + /** + * + * @var TwigEngine + */ + protected $twig; + + public function __construct(TwigEngine $twig) + { + $this->twig = $twig; + } + + + public function renderBox($entity, array $options): string + { + $defaultOptions = [ + 'has_no_address' => false, + 'with_valid_from' => false + ]; + + return $this->twig->render('@ChillMain/Address/render_box_address.html.twig', + [ + 'address' => $entity, + 'options' => \array_merge($defaultOptions, $options) + ]); + } + + /** + * + * @param Address $entity + * @param array $options + * @return string + */ + public function renderString($entity, array $options): string + { + return \htmlspecialchars( + $entity->getStreetAddress1().', '. + $entity->getStreetAddress2().', '. + $entity->getPostcode()->getCode().' '. + $entity->getPostcode()->getName() + ); + } + + public function supports($entity, array $options): bool + { + return $entity instanceof Address; + } +}