From df8f1d8622d3c518f9da1a8f0e9fc1b0b809b7bd Mon Sep 17 00:00:00 2001 From: Michele Locati Date: Mon, 1 Jul 2024 15:30:47 +0200 Subject: [PATCH] Add Finder --- src/Finder.php | 127 ++++++++++++++++ test/tests/Finder/FindByIDTest.php | 230 +++++++++++++++++++++++++++++ 2 files changed, 357 insertions(+) create mode 100644 src/Finder.php create mode 100644 test/tests/Finder/FindByIDTest.php diff --git a/src/Finder.php b/src/Finder.php new file mode 100644 index 0000000..7826e69 --- /dev/null +++ b/src/Finder.php @@ -0,0 +1,127 @@ +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; + } +} diff --git a/test/tests/Finder/FindByIDTest.php b/test/tests/Finder/FindByIDTest.php new file mode 100644 index 0000000..8d73b9a --- /dev/null +++ b/test/tests/Finder/FindByIDTest.php @@ -0,0 +1,230 @@ +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(); + } +}