Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add a feature to change country display format in form #95

Merged
merged 6 commits into from
Dec 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]
- Add a feature to change country display format in form

## [3.5.0] - 2021-10-23

Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,12 @@ This produces the preferred choices of 'Jersey' and 'United Kingdom', and regula
By default the `country_choices` is empty, which means all countries are included, as is `preferred_country_choices`.
The option `country_placeholder` can be specified to create a placeholder option on above the whole list.

The option `country_display_type` can be specified to change the country dropdown label format. There are two formats available :
| display type | Result |
| ----------------------------------| -----------------------|
| `display_country_full` (default) | United Kingdom (+44) |
| `display_country_short` | GB +44 |

### Validating phone numbers

ℹ️ _Using a Symfony or PHP version that does not support attributes? This bundle also supports validation as annotation.
Expand Down
26 changes: 23 additions & 3 deletions src/Form/Type/PhoneNumberType.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ class PhoneNumberType extends AbstractType
public const WIDGET_SINGLE_TEXT = 'single_text';
public const WIDGET_COUNTRY_CHOICE = 'country_choice';

public const DISPLAY_COUNTRY_FULL = 'display_country_full';
public const DISPLAY_COUNTRY_SHORT = 'display_country_short';

/**
* {@inheritdoc}
*/
Expand Down Expand Up @@ -60,13 +63,15 @@ public function buildForm(FormBuilderInterface $builder, array $options)
}

$countryChoices = [];
$intlCountries = Countries::getNames();

foreach (Countries::getNames() as $region => $name) {
if (false === isset($countries[$region])) {
foreach ($countries as $regionCode => $countryCode) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this change? It's not equivalent to what was here before. Therefore it potentially breaks the compatibility.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The results is almost the same. I made this change to keep the order given in the countries configuration entry.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I'm not mistaken, the performances are not the same this way because before the data was loaded and browsed only once in the buffer of the component while now we have it as many times as countries support x2 (exists & getName)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right ! Not sure its a big deal. Let me check :)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would not be so convinced. I would like to have a verification on this before

Copy link
Collaborator

@Nek- Nek- Dec 2, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The performance overhead is actually small. But I'm surprised there's indeed a topic here. That said, a solution can be quickly found here:

if (!Countries::exists($regionCode))

could be changed easily with

$intlCountries = Countries::getNames();
// and later
if (!isset($intlCountries[$regionCode]))

(and Countries::getName($regionCode) by $intlCountries[$regionCode])

if (!isset($intlCountries[$regionCode])) {
continue;
}

$countryChoices[sprintf('%s (+%s)', $name, $countries[$region])] = $region;
$label = $this->formatDisplayChoice($options['country_display_type'], $intlCountries[$regionCode], $regionCode, $countryCode);
$countryChoices[$label] = $regionCode;
}

$transformerChoices = array_values($countryChoices);
Expand Down Expand Up @@ -128,6 +133,7 @@ public function configureOptions(OptionsResolver $resolver)
'by_reference' => false,
'error_bubbling' => false,
'country_choices' => [],
'country_display_type' => self::DISPLAY_COUNTRY_FULL,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like a break, we currently use short format, isn't it?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nop, currently we use "France (+33)" the "FULL" format

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my bad

'country_placeholder' => false,
'preferred_country_choices' => [],
'country_options' => [],
Expand All @@ -139,6 +145,11 @@ public function configureOptions(OptionsResolver $resolver)
self::WIDGET_COUNTRY_CHOICE,
]);

$resolver->setAllowedValues('country_display_type', [
self::DISPLAY_COUNTRY_FULL,
self::DISPLAY_COUNTRY_SHORT,
]);

$resolver->setAllowedTypes('country_options', 'array');
$resolver->setAllowedTypes('number_options', 'array');
}
Expand All @@ -158,4 +169,13 @@ public function getBlockPrefix()
{
return 'phone_number';
}

private function formatDisplayChoice(string $displayType, string $regionName, string $regionCode, string $countryCode): string
{
if (self::DISPLAY_COUNTRY_SHORT === $displayType) {
return sprintf('%s +%s', $regionCode, $countryCode);
}

return sprintf('%s (+%s)', $regionName, $countryCode);
}
}
43 changes: 42 additions & 1 deletion tests/Form/Type/PhoneNumberTypeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,9 @@ public function countryChoiceChoicesProvider()
return [
[
[],
\count(PhoneNumberUtil::getInstance()->getSupportedRegions()),
// 3 regions have an already used label "TA", "AC" and XK
// @see https://fr.wikipedia.org/wiki/ISO_3166-2#cite_note-UPU-1
242,
[
$this->createChoiceView('United Kingdom (+44)', 'GB'),
],
Expand All @@ -167,6 +169,45 @@ public function countryChoiceChoicesProvider()
];
}

/**
* @dataProvider countryChoiceFormatProvider
*/
public function testCountryChoiceFormat(string $displayType, array $expectedChoices)
{
$options['widget'] = PhoneNumberType::WIDGET_COUNTRY_CHOICE;
$options['country_display_type'] = $displayType;
$form = $this->factory->create(PhoneNumberType::class, null, $options);

$view = $form->createView();
$choices = $view['country']->vars['choices'];

foreach ($expectedChoices as $expectedChoice) {
$this->assertContainsEquals($expectedChoice, $choices);
}
}

/**
* 0 => Display type
* 2 => Expected choices.
*/
public function countryChoiceFormatProvider()
{
return [
[
PhoneNumberType::DISPLAY_COUNTRY_FULL,
[
$this->createChoiceView('United Kingdom (+44)', 'GB'),
],
],
[
PhoneNumberType::DISPLAY_COUNTRY_SHORT,
[
$this->createChoiceView('GB +44', 'GB'),
],
],
];
}

/**
* @dataProvider countryChoicePlaceholderProvider
*
Expand Down