achentonpambo / angola-data
Províncias e municípios de Angola para aplicações PHP. Core sem dependências, com integração opcional para Laravel.
Requires
- php: ^8.2
- ext-json: *
- ext-mbstring: *
Requires (Dev)
- orchestra/testbench: ^9.0 || ^10.0
- phpstan/phpstan: ^2.0
- phpunit/phpunit: ^11.0 || ^12.0
- squizlabs/php_codesniffer: ^3.10
Suggests
- illuminate/support: Necessário apenas para usar a integração Laravel (ServiceProvider e Facade).
Provides
None
Conflicts
None
Replaces
None
README
Províncias e municípios de Angola para aplicações PHP.
O Core é PHP puro, sem dependências de framework. A integração com Laravel é opcional e limita-se a registar o Core no container.
- 21 províncias e 326 municípios (divisão administrativa pós-reforma de 2024)
- Sem base de dados, sem Eloquent, sem migrations, sem API REST
- Objetos imutáveis e totalmente tipados
- O dataset é lido do disco no máximo uma vez por instância
Instalação
composer require achentonpambo/angola-data
Requer PHP 8.2 ou superior, com as extensões json e mbstring.
Em Laravel, o ServiceProvider e a Facade são registados automaticamente por package discovery — não é preciso configurar nada.
PHP puro
<?php require 'vendor/autoload.php'; use AchentonPambo\AngolaData\AngolaData; $angola = new AngolaData(); foreach ($angola->provinces() as $province) { echo $province->name . PHP_EOL; }
$luanda = $angola->province('LUA'); echo $luanda->name; // Luanda echo $luanda->capital; // Luanda
$municipalities = $angola->municipalitiesByProvince('LUA'); foreach ($municipalities as $municipality) { echo $municipality->name . PHP_EOL; }
Há exemplos completos e executáveis em examples/php/.
Laravel
Via Facade:
use AchentonPambo\AngolaData\Facades\AngolaData; $provinces = AngolaData::provinces(); $luanda = AngolaData::province('LUA'); $municipalities = AngolaData::municipalities();
Via dependency injection — o Core está registado como singleton, por isso o dataset é lido uma única vez por request:
use AchentonPambo\AngolaData\AngolaData; public function index(AngolaData $angola) { return $angola->provinces(); }
Os modelos implementam JsonSerializable, pelo que podem ser devolvidos
diretamente numa resposta JSON. Ver examples/laravel/example.php.
Provinces
$angola->provinces(); // list<Province>, ordenadas por nome $angola->province('LUA'); // Province|null $angola->provinceExists('LUA'); // bool $angola->provinceCount(); // int
Province é um objeto imutável:
$province->id; // 'LUA' $province->name; // 'Luanda' $province->capital; // 'Luanda' $province->municipalities; // list<Municipality> $province->municipalityCount(); // int $province->toArray(); // array
Os ids de província seguem a norma ISO 3166-2:AO onde esta existe
(LUA, BGU, HUI, ...). A pesquisa por id ignora maiúsculas/minúsculas e
espaços à volta, e LDA é aceite como alias de LUA.
Municipalities
$angola->municipalities(); // list<Municipality> $angola->municipality('LUA-001'); // Municipality|null $angola->municipalitiesByProvince('LUA'); // list<Municipality> $angola->municipalityExists('LUA-001'); // bool $angola->municipalityCount(); // int
$municipality->id; // 'LUA-001' $municipality->name; // 'Belas' $municipality->provinceId; // 'LUA' $municipality->toArray(); // ['id' => ..., 'name' => ..., 'province_id' => ...]
Os ids de município são {PROVÍNCIA}-{NNN}, sequenciais por ordem alfabética
dentro de cada província.
Search
$results = $angola->search('belas');
[
[
'type' => 'municipality',
'id' => 'LUA-001',
'name' => 'Belas',
'province_id' => 'LUA',
],
]
A pesquisa:
- procura em províncias e municípios (províncias primeiro);
- é parcial (
'mbanza'encontra'Mbanza Kongo'); - ignora maiúsculas/minúsculas e acentos (
'huila'encontra'Huíla'); - devolve
[]para um termo vazio ou sem correspondência.
Nos resultados do tipo province, province_id é null.
Tratamento de erros
| Situação | Comportamento |
|---|---|
province('INVALID') |
devolve null |
municipality('INVALID') |
devolve null |
municipalitiesByProvince('INVALID') |
devolve [] |
search('...') sem resultados |
devolve [] |
| dataset em falta, ilegível, JSON inválido ou malformado | lança InvalidDatasetException |
Ou seja: consultas nunca lançam exceções; só problemas de integridade do
dataset o fazem. AchentonPambo\AngolaData\Exceptions\InvalidDatasetException
estende RuntimeException.
Data source
$angola->dataVersion(); // '2025.1' $angola->source(); // ['organization' => ..., 'dataset' => ..., 'year' => ..., 'source_url' => ...]
O dataset vive num único ficheiro JSON, data/angola.json,
e reflete a divisão político-administrativa em vigor após a reforma de 2024,
que elevou o país a 21 províncias (criação de Icolo e Bengo, Cuando, Cubango e
Moxico Leste).
Estado dos dados. Esta é uma compilação comunitária. Os nomes de províncias, capitais e municípios ainda não foram conferidos linha a linha contra o Diário da República / Ministério da Administração do Território, e algumas províncias podem listar entradas que são comunas ou distritos urbanos e não municípios de pleno direito. O campo
source.notesdo dataset regista este estado. Correções documentadas com a respetiva fonte oficial são muito bem-vindas — ver CONTRIBUTING.md.
Os códigos de província seguem a ISO 3166-2:AO onde esta existe. As quatro
províncias criadas em 2024 ainda não têm código ISO atribuído; usam códigos
provisórios definidos por este package (ICB, CDO, CBG, MXL), assinalados
no dataset com "iso_3166_2": null.
Dataset version
A versão do dataset é independente da versão do package e segue o formato
ANO.SEQUÊNCIA (por exemplo 2025.1, 2025.2, 2026.1):
- o ano identifica a divisão administrativa representada;
- a sequência incrementa a cada correção ou atualização dos dados nesse ano.
Uma alteração de dados que mude ids existentes é tratada como breaking change do
package e sai numa nova versão major. Correções de nomes e adições saem em
versões minor ou patch. Consulta sempre dataVersion() quando persistires ids.
Fonte alternativa de dados
Podes fornecer o teu próprio ficheiro, mantendo a mesma API:
use AchentonPambo\AngolaData\AngolaData; use AchentonPambo\AngolaData\Data\JsonDataSource; $angola = new AngolaData(new JsonDataSource('/caminho/para/o/meu/angola.json'));
Ou implementar AchentonPambo\AngolaData\Contracts\DataSourceInterface para ler os
dados de outro sítio (cache, base de dados, API interna).
Em Laravel, basta reatribuir o binding no teu AppServiceProvider:
$this->app->singleton(DataSourceInterface::class, fn () => new JsonDataSource($path));
Qualidade
composer test # PHPUnit composer analyse # PHPStan (nível 8) composer cs # PSR-12 composer check # os três acima
Contributing
Contribuições são bem-vindas, sobretudo correções aos dados acompanhadas da fonte oficial. Ver CONTRIBUTING.md.
License
MIT. Ver LICENSE.