powderblue/sf-continent-country-type
Adds continent and country form types to your PHP application, letting users pick from grouped, ready-made country lists with no external API calls. Ships sensible defaults, lightweight bundled data, and straightforward integration for forms, filters, and validation.
This is a Symfony Form component package, not a Laravel one. Before anything else, confirm that assumption: it ships ContinentType and CountryType classes extending Symfony's AbstractType. There is no service provider, no facade, no migrations, no publishable config — the composer require step will not register anything in a Laravel app. If you are on Laravel, you are adopting it for the underlying data (continent-grouped country lists / localization) rather than for its form integration, and you will write the Laravel glue yourself (see Gotchas).
Minimal steps for the intended (Symfony) use case:
composer require powderblue/sf-continent-country-type and note the resolved version — pin it explicitly. The last tagged release is 2024-09-13, and the assessment notes a major bump with no release notes, so a caret range can move you onto an undocumented surface on the next composer update.form.type (Symfony does this automatically for classes under your src/ with autoconfigure, but a vendor package needs its own registration — check whether the package ships a bundle or a compiler pass; if not, register them manually in config/services.yaml).CountryType into an existing form:$builder->add('country', CountryType::class, [
'placeholder' => 'Choose a country',
]);
First use case: a registration or address form where you want a country select grouped by continent with a placeholder — the classic "we rebuilt this list by hand three times" problem.
Where to look first: the src/ directory, not the README. Read the ContinentType and CountryType configureOptions() / buildForm() methods to see the full option list (placeholder, preferred_choices, label options) and where the country data actually comes from (bundled PHP array, ICU/Intl, or a data file). That data source determines both bundle size and whether the list is localized.
Treat the types as black-box choice fields. The idiomatic pattern is composition: extend or wrap CountryType rather than copying its option list, so upgrades pick up new countries and locale fixes automatically.
class AddressType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('continent', ContinentType::class, ['placeholder' => 'Select a continent'])
->add('country', CountryType::class, [
'placeholder' => 'Select a country',
'preferred_choices' => ['US', 'GB', 'DE'], // pin your top markets
]);
}
}
Use preferred_choices to solve the long-list problem. ~200 countries in one flat select is poor UX; the package groups by continent, but preferred choices at the top is still the highest-leverage tweak. Drive it from config (config('shop.preferred_countries') in Laravel) so ops can change it without a deploy.
Wire dependent choice fields via FormEvents::PRE_SUBMIT / POST_SUBMIT if you want continent → country filtering. The package gives you a grouped list, not a cascade; filtering by continent is your code. If the country list arrives as ['Europe' => ['FR' => 'France', ...]], build the filtered subset from the same source.
Validation and normalization. Submitted values are country codes — persist the ISO code, not the label. Add a Country constraint or Choice constraint (Symfony's Country constraint validates ISO 3166-1 alpha-2 directly), and normalize on submit with a PRE_SUBMIT listener that uppercases, because users and APIs will send us as often as US.
Localization. Check the constructor dependencies — if the type takes a Locale or TranslatorInterface, pass $request->getLocale() (Symfony) so labels render in the active language. If the country names are a hardcoded English array, you own the translation layer; either wrap the labels or accept English-only.
In Laravel specifically, the honest pattern is: don't use the FormType. Extract the country data (the array or data file inside the package) into your own service, bind it in a service provider, and render a Blade <select> or a Livewire/Filament field from it. This isolates the dependency behind one class and makes the swap cheap.
"powderblue/sf-continent-country-type": "1.2.3"), upgrade deliberately on a branch, and diff src/ between tags — option names and data-file formats are the likely break points.placeholder, preferred_choices, and choice_label behave as vanilla Symfony expects — vendor types frequently redefine or shadow these, and a silently renamed option falls back to a default without erroring. Assert on rendered output in your test suite, not just on form validity.Bundle class or services.yaml, autowiring may not pick up CountryType. The failure mode is a "could not load type" exception at form build time — loud and easy to fix with an explicit form.type tag.dump($form->get('country')->getConfig()->getOption('choices')) after createForm is the fastest way to see exactly what the package built, including grouping and label locales, before touching any of the package internals.How can I help you explore Laravel packages today?