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

Add Finder #4

Merged
merged 1 commit into from
Jul 1, 2024
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
127 changes: 127 additions & 0 deletions src/Finder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
<?php

declare(strict_types=1);

namespace MLocati\ComuniItaliani;

class Finder
{
protected Factory $factory;

public function __construct(?Factory $factory = null)
{
$this->factory = $factory ?? new Factory();
}

/**
* Find a territory (Geographical Subdivision, Region, Province, or Municipality) given its ID.
*
* @param int|string|mixed $id int for Geographical Subdivision, string for other territory types.
*/
public function getTerritoryByID($id): ?Territory
{
switch (gettype($id)) {
case 'integer':
return $this->getGeographicalSubdivisionByID($id);
case 'string':
switch (strlen($id)) {
case 2:
return $this->getRegionByID($id);
case 3:
return $this->getProvinceByID($id);
case 6:
return $this->getMunicipalityByID($id);
}
break;
}

return null;
}

/**
* Find a Geographical Subdivision given its ID
*/
public function getGeographicalSubdivisionByID(int $id): ?GeographicalSubdivision
{
foreach ($this->factory->getGeographicalSubdivisions() as $geographicalSubdivision) {
if ($geographicalSubdivision->getID() === $id) {
return $geographicalSubdivision;
}
}

return null;
}

/**
* Find a Region given its ID
*/
public function getRegionByID(string $id): ?Region
{
if (!preg_match('/^[0-9]{2}$/', $id)) {
return null;
}
foreach ($this->factory->getGeographicalSubdivisions() as $geographicalSubdivisions) {
foreach ($geographicalSubdivisions->getRegions() as $region) {
if ($region->getID() === $id) {
return $region;
}
}
}

return null;
}

/**
* Find a Province/UTS given its ID
*
* @param bool $oldIDToo look for $in in historical Province codes too?
*/
public function getProvinceByID(string $id, bool $oldIDToo = false): ?Province
{
if (!preg_match('/^[0-9]{3}$/', $id)) {
return null;
}
foreach ($this->factory->getGeographicalSubdivisions() as $geographicalSubdivisions) {
foreach ($geographicalSubdivisions->getRegions() as $region) {
foreach ($region->getProvinces() as $province) {
foreach ($province->getMunicipalities() as $municipality) {
if ($province->getID() === $id) {
return $province;
}
if ($oldIDToo && $province->getOldID() === $id) {
return $province;
}
}
}
}
}

return null;
}


/**
* Find a Municipality given its ID
*
* @param bool $oldIDToo look for $in in historical Province codes too?
*/
public function getMunicipalityByID(string $id): ?Municipality
{
if (!preg_match('/^[0-9]{6}$/', $id)) {
return null;
}
foreach ($this->factory->getGeographicalSubdivisions() as $geographicalSubdivisions) {
foreach ($geographicalSubdivisions->getRegions() as $region) {
foreach ($region->getProvinces() as $province) {
foreach ($province->getMunicipalities() as $municipality) {
if ($municipality->getID() === $id) {
return $municipality;
}
}
}
}
}

return null;
}
}
230 changes: 230 additions & 0 deletions test/tests/Finder/FindByIDTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,230 @@
<?php

declare(strict_types=1);

namespace MLocati\ComuniItaliani\Test\Finder;

use MLocati\ComuniItaliani\Finder;
use MLocati\ComuniItaliani\Territory;
use MLocati\ComuniItaliani\GeographicalSubdivision;
use MLocati\ComuniItaliani\Region;
use MLocati\ComuniItaliani\Province;
use PHPUnit\Framework\TestCase;

class FindByIDTest extends TestCase
{
private static ?Finder $finder;

public function provideGetTerritoryByIDCases(): array
{
return [
[null, ''],
[[], ''],
[-1, ''],
[1, 'Nord-ovest'],
[PHP_INT_MAX, ''],
['', ''],
['0', ''],
['1', ''],
['AA', ''],
['00', ''],
['01', 'Piemonte'],
['AAA', ''],
['000', ''],
['258', 'Roma'],
['058', ''],
['215', 'Milano'],
['015', ''],
['AAAA', ''],
['0123', ''],
['AAAAA', ''],
['01234', ''],
['AAAAAA', ''],
['000000', ''],
['058091', 'Roma (RM)'],
['258091', ''],
['015146', 'Milano (MI)'],
['215091', ''],
['0123456', ''],
['AAAAAAA', ''],
];
}

/**
* @dataProvider provideGetTerritoryByIDCases
*/
public function testGetTerritoryByID($id, string $expectedName): void
{
$territory = $this->getFinder()->getTerritoryByID($id);
if ($expectedName === '') {
$this->assertNull($territory);
} else {
$this->assertInstanceOf(Territory::class, $territory);
$this->assertSame($expectedName, (string) $territory);
}
}

public function provideGetGeographicalSubdivisionByIDCases(): array
{
return [
[-1, ''],
[1, 'Nord-ovest'],
[PHP_INT_MAX, ''],
];
}

/**
* @dataProvider provideGetGeographicalSubdivisionByIDCases
*/
public function testGetGeographicalSubdivisionByID(int $id, string $expectedName): void
{
$territory = $this->getFinder()->getGeographicalSubdivisionByID($id);
if ($expectedName === '') {
$this->assertNull($territory);
} else {
$this->assertInstanceOf(GeographicalSubdivision::class, $territory);
$this->assertSame($expectedName, (string) $territory);
}
}

public function provideGetRegionByIDCases(): array
{
return [
['', ''],
['0', ''],
['1', ''],
['AA', ''],
['00', ''],
['01', 'Piemonte'],
['AAA', ''],
['000', ''],
['258', ''],
['058', ''],
['215', ''],
['015', ''],
['AAAA', ''],
['0123', ''],
['AAAAA', ''],
['01234', ''],
['AAAAAA', ''],
['000000', ''],
['058091', ''],
['258091', ''],
['015146', ''],
['215091', ''],
['0123456', ''],
['AAAAAAA', ''],
];
}

/**
* @dataProvider provideGetRegionByIDCases
*/
public function testGetRegionByID(string $id, string $expectedName): void
{
$territory = $this->getFinder()->getRegionByID($id);
if ($expectedName === '') {
$this->assertNull($territory);
} else {
$this->assertInstanceOf(Region::class, $territory);
$this->assertSame($expectedName, (string) $territory);
}
}

public function provideGetProvinceByIDCases(): array
{
return [
['', ''],
['0', ''],
['1', ''],
['AA', ''],
['00', ''],
['01', ''],
['AAA', ''],
['000', ''],
['258', 'Roma'],
['058', ''],
['058', 'Roma', true],
['215', 'Milano'],
['015', ''],
['015', 'Milano', true],
['AAAA', ''],
['0123', ''],
['AAAAA', ''],
['01234', ''],
['AAAAAA', ''],
['000000', ''],
['058091', ''],
['258091', ''],
['015146', ''],
['215091', ''],
['0123456', ''],
['AAAAAAA', ''],
];
}

/**
* @dataProvider provideGetProvinceByIDCases
*/
public function testGetProvinceByID(string $id, string $expectedName, bool $oldIDToo = false): void
{
$territory = $this->getFinder()->getProvinceByID($id, $oldIDToo);
if ($expectedName === '') {
$this->assertNull($territory);
} else {
$this->assertInstanceOf(Province::class, $territory);
$this->assertSame($expectedName, (string) $territory);
}
}


public function provideGetMunicipalityByIDCases(): array
{
return [
['', ''],
['0', ''],
['1', ''],
['AA', ''],
['00', ''],
['01', ''],
['AAA', ''],
['000', ''],
['258', ''],
['058', ''],
['215', ''],
['015', ''],
['AAAA', ''],
['0123', ''],
['AAAAA', ''],
['01234', ''],
['AAAAAA', ''],
['000000', ''],
['058091', 'Roma (RM)'],
['258091', ''],
['015146', 'Milano (MI)'],
['215091', ''],
['0123456', ''],
['AAAAAAA', ''],
];
}

/**
* @dataProvider provideGetMunicipalityByIDCases
*/
public function testGetMunicipalityByID(string $id, string $expectedName): void
{
$territory = $this->getFinder()->getMunicipalityByID($id);
if ($expectedName === '') {
$this->assertNull($territory);
} else {
$this->assertNotNull($territory);
$this->assertSame($expectedName, (string) $territory);
}
}


private function getFinder(): Finder
{
return self::$finder ??= new Finder();
}
}