diff --git a/README.md b/README.md index 8096203..5df53a8 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ composer require mlocati/comuni-italiani This library provides the following Italian Administrative divisions: -- **Geographical Subdivisions** (*ripartizioni geografiche*) +- **Geographical Subdivisions** (*ripartizioni geografiche*) For example "Nord-ovest", "Centro", "Sud" - **Regions** (*regioni*) For example "Piemonte", "Lazio", "Campania" @@ -80,7 +80,7 @@ This library provides the following data: - the second level of the current Nomenclature of Territorial Units for Statistics (NUTS2) (example: `'ITC1'`) - the third level of the current Nomenclature of Territorial Units for Statistics (NUTS3) (example: `'ITC11'`) -### Retrieving territories +### Retrieving Territories You can have a list of all the Geographical Subdivisions, Regions, Provinces/UTS, and Municipalities using the `Factory` class. @@ -110,7 +110,7 @@ $province = $finder->getProvinceByID('201'); $municipality = $finder->getMunicipalityByID('001272'); ``` -### Finding territories by name +### Finding Territories by Name You can use the `Finder` class to find Geographical Subdivisions, Regions, Provinces/UTS, and Municipalities by name. @@ -146,3 +146,26 @@ $regions = $finder->findRegionsByName('ampania', true); $provinces = $finder->findProvincesByName('ozen', true); $municipalities = $finder->findMunicipalitiesByName('oma ombard', true); ``` + +### Testing Hierarchy + +Given two territories, you can check if they are the same by using the `isSame()` method: + +```php +if ($territory1->isSame($territory2)) { + echo 'Same territory'; +} +``` + +For Geographical Subdivisions, Regions, and Provinces/UTS (which are containers of other territories) you can also use the `contains()` and `isSameOrContains()` methods. + +```php +// $region is an instance of Region here +if ($region->contains($territory)) { + echo "{$region} contains {$terrtory}"; +} + +if ($region->isSameOrContains($territory)) { + echo "{$region} is same (or contains) {$terrtory}"; +} +``` diff --git a/src/GeographicalSubdivision.php b/src/GeographicalSubdivision.php index a9f4a73..f93b784 100644 --- a/src/GeographicalSubdivision.php +++ b/src/GeographicalSubdivision.php @@ -9,6 +9,8 @@ */ final class GeographicalSubdivision implements TerritoryWithChildren { + use Service\TerritoryWithChildrenTrait; + private array $data; private ?array $regions = null; diff --git a/src/Municipality.php b/src/Municipality.php index d141a0c..42d7785 100644 --- a/src/Municipality.php +++ b/src/Municipality.php @@ -9,6 +9,8 @@ */ final class Municipality implements Territory { + use Service\TerritoryTrait; + private array $data; private Province $province; diff --git a/src/Province.php b/src/Province.php index 2c6c0b6..a72fa40 100644 --- a/src/Province.php +++ b/src/Province.php @@ -9,6 +9,8 @@ */ final class Province implements TerritoryWithChildren { + use Service\TerritoryWithChildrenTrait; + private array $data; private Region $region; diff --git a/src/Region.php b/src/Region.php index b74950a..37e87c2 100644 --- a/src/Region.php +++ b/src/Region.php @@ -9,6 +9,8 @@ */ final class Region implements TerritoryWithChildren { + use Service\TerritoryWithChildrenTrait; + private array $data; private GeographicalSubdivision $geographicalSubdivision; diff --git a/src/Service/MultibyteTrait.php b/src/Service/MultibyteTrait.php index 704575d..b7b20e4 100644 --- a/src/Service/MultibyteTrait.php +++ b/src/Service/MultibyteTrait.php @@ -4,6 +4,9 @@ namespace MLocati\ComuniItaliani\Service; +/** + * @internal + */ trait MultibyteTrait { protected static function getMultibyteToAsciiMap(): array diff --git a/src/Service/SorterTrait.php b/src/Service/SorterTrait.php index a833cee..edeffaa 100644 --- a/src/Service/SorterTrait.php +++ b/src/Service/SorterTrait.php @@ -7,6 +7,9 @@ use Collator; use MLocati\ComuniItaliani\Territory; +/** + * @internal + */ trait SorterTrait { use MultibyteTrait; diff --git a/src/Service/TerritoryTrait.php b/src/Service/TerritoryTrait.php new file mode 100644 index 0000000..35ad55a --- /dev/null +++ b/src/Service/TerritoryTrait.php @@ -0,0 +1,23 @@ +getID() === $territory->getID(); + } +} diff --git a/src/Service/TerritoryWithChildrenTrait.php b/src/Service/TerritoryWithChildrenTrait.php new file mode 100644 index 0000000..66d2a9d --- /dev/null +++ b/src/Service/TerritoryWithChildrenTrait.php @@ -0,0 +1,45 @@ +getChildren() as $child) { + if ($child instanceof TerritoryWithChildren) { + if ($child->isSameOrContains($territory)) { + return true; + } + } elseif ($child->isSame($territory)) { + return true; + } + } + + return false; + } + + /** + * {@inheritdoc} + * + * @see \MLocati\ComuniItaliani\TerritoryWithChildren::isSameOrContains() + */ + public function isSameOrContains(Territory $territory): bool + { + return $this->isSame($territory) || $this->contains($territory); + } +} diff --git a/src/Territory.php b/src/Territory.php index de3ecd2..ab01de3 100644 --- a/src/Territory.php +++ b/src/Territory.php @@ -26,6 +26,11 @@ public function getParent(): ?TerritoryWithChildren; */ public function getName(): string; + /** + * Check if a territory instance is the same as this. + */ + public function isSame(Territory $territory): bool; + /** * Get a string representation that uniquely represents the territory. */ diff --git a/src/TerritoryWithChildren.php b/src/TerritoryWithChildren.php index f59774a..93ba9e8 100644 --- a/src/TerritoryWithChildren.php +++ b/src/TerritoryWithChildren.php @@ -15,4 +15,14 @@ interface TerritoryWithChildren extends Territory * @return \MLocati\ComuniItaliani\Territory[] */ public function getChildren(): array; + + /** + * Check if this territory contains another territory. + */ + public function contains(Territory $territory): bool; + + /** + * Check if this territory contains another territory, or if it's the same as this. + */ + public function isSameOrContains(Territory $territory): bool; } diff --git a/test/tests/HierarchyTest.php b/test/tests/HierarchyTest.php new file mode 100644 index 0000000..5ceaca1 --- /dev/null +++ b/test/tests/HierarchyTest.php @@ -0,0 +1,42 @@ +testHierarchyFor($factory1->getGeographicalSubdivisions()[0], $factory2->getGeographicalSubdivisions()[0]); + } + + private function testHierarchyFor(Territory $territory, Territory $equalsNotSame): void + { + $this->assertNotSame($territory, $equalsNotSame); + $this->assertTrue($territory->isSame($territory)); + $this->assertTrue($territory->isSame($equalsNotSame)); + if ($territory instanceof TerritoryWithChildren) { + $this->assertFalse($territory->contains($territory)); + $this->assertFalse($territory->contains($equalsNotSame)); + $this->assertTrue($territory->isSameOrContains($territory)); + $this->assertTrue($territory->isSameOrContains($equalsNotSame)); + $child = $territory->getChildren()[0]; + $this->assertFalse($child->isSame($territory)); + $this->assertFalse($territory->isSame($child)); + if ($child instanceof TerritoryWithChildren) { + $this->assertFalse($child->contains($territory)); + $this->assertFalse($child->isSameOrContains($territory)); + $this->testHierarchyFor($child, $equalsNotSame->getChildren()[0]); + } + } + } +}