Skip to content

Commit

Permalink
Add isSame, isContainedIn, contains, isSameOrContains, isSameOrContai…
Browse files Browse the repository at this point in the history
…nedIn methods (#7)
  • Loading branch information
mlocati authored Jul 2, 2024
1 parent a5e6f61 commit 30e6ade
Show file tree
Hide file tree
Showing 12 changed files with 220 additions and 3 deletions.
40 changes: 37 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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.

Expand Down Expand Up @@ -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.

Expand Down Expand Up @@ -146,3 +146,37 @@ $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';
}
```

You can also check if a territory is contained in another territory:

```php
if ($territory1->isContainedIn($territory2)) {
echo "{$territory1} is contained in {$territory2}";
}
if ($territory1->isSameOrContainedIn($territory2)) {
echo "{$territory1} is contained in {$territory2} (or they are the same)";
}
```

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}";
}
```
2 changes: 2 additions & 0 deletions src/GeographicalSubdivision.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
*/
final class GeographicalSubdivision implements TerritoryWithChildren
{
use Service\TerritoryWithChildrenTrait;

private array $data;

private ?array $regions = null;
Expand Down
2 changes: 2 additions & 0 deletions src/Municipality.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
*/
final class Municipality implements Territory
{
use Service\TerritoryTrait;

private array $data;

private Province $province;
Expand Down
2 changes: 2 additions & 0 deletions src/Province.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
*/
final class Province implements TerritoryWithChildren
{
use Service\TerritoryWithChildrenTrait;

private array $data;

private Region $region;
Expand Down
2 changes: 2 additions & 0 deletions src/Region.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
*/
final class Region implements TerritoryWithChildren
{
use Service\TerritoryWithChildrenTrait;

private array $data;

private GeographicalSubdivision $geographicalSubdivision;
Expand Down
3 changes: 3 additions & 0 deletions src/Service/MultibyteTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

namespace MLocati\ComuniItaliani\Service;

/**
* @internal
*/
trait MultibyteTrait
{
protected static function getMultibyteToAsciiMap(): array
Expand Down
3 changes: 3 additions & 0 deletions src/Service/SorterTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
use Collator;
use MLocati\ComuniItaliani\Territory;

/**
* @internal
*/
trait SorterTrait
{
use MultibyteTrait;
Expand Down
44 changes: 44 additions & 0 deletions src/Service/TerritoryTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

declare(strict_types=1);

namespace MLocati\ComuniItaliani\Service;

use MLocati\ComuniItaliani\Territory;
use MLocati\ComuniItaliani\TerritoryWithChildren;

/**
* @internal
*/
trait TerritoryTrait
{
/**
* {@inheritdoc}
*
* @see \MLocati\ComuniItaliani\Territory::isSame()
*/
public function isSame(Territory $territory): bool
{
return $this->getID() === $territory->getID();
}

/**
* {@inheritdoc}
*
* @see \MLocati\ComuniItaliani\Territory::isContainedIn()
*/
public function isContainedIn(Territory $territory): bool
{
return $territory instanceof TerritoryWithChildren && $territory->contains($this);
}

/**
* {@inheritdoc}
*
* @see \MLocati\ComuniItaliani\Territory::isContainedIn()
*/
public function isSameOrContainedIn(Territory $territory): bool
{
return $this->isSame($territory) || $this->isContainedIn($territory);
}
}
46 changes: 46 additions & 0 deletions src/Service/TerritoryWithChildrenTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

declare(strict_types=1);

namespace MLocati\ComuniItaliani\Service;

use MLocati\ComuniItaliani\Territory;
use MLocati\ComuniItaliani\TerritoryWithChildren;

/**
* @internal
*/
trait TerritoryWithChildrenTrait
{
use TerritoryTrait;

/**
* {@inheritdoc}
*
* @see \MLocati\ComuniItaliani\TerritoryWithChildren::contains()
*/
public function contains(Territory $territory): bool
{
foreach ($this->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);
}
}
15 changes: 15 additions & 0 deletions src/Territory.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,21 @@ public function getParent(): ?TerritoryWithChildren;
*/
public function getName(): string;

/**
* Check if a territory instance is the same as this.
*/
public function isSame(Territory $territory): bool;

/**
* Check if this territory is a child/grandchild/great-grandchild/... of another territory.
*/
public function isContainedIn(Territory $territory): bool;

/**
* Check if this territory is a child/grandchild/great-grandchild/... of another territory, of if they are the same
*/
public function isSameOrContainedIn(Territory $territory): bool;

/**
* Get a string representation that uniquely represents the territory.
*/
Expand Down
10 changes: 10 additions & 0 deletions src/TerritoryWithChildren.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
54 changes: 54 additions & 0 deletions test/tests/HierarchyTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

declare(strict_types=1);

namespace MLocati\ComuniItaliani\Test;

use PHPUnit\Framework\TestCase;
use MLocati\ComuniItaliani\Factory;
use MLocati\ComuniItaliani\Territory;
use MLocati\ComuniItaliani\TerritoryWithChildren;

class HierarchyTest extends TestCase
{
public function testHierarchy(): void
{
$factory1 = new Factory();
$factory2 = new Factory();

$this->testHierarchyFor($factory1->getGeographicalSubdivisions()[0], $factory2->getGeographicalSubdivisions()[0]);
}

private function testHierarchyFor(Territory $territory, Territory $equalsNotSame, ?Territory $ascending = null): void
{
$this->assertNotSame($territory, $equalsNotSame);
$this->assertTrue($territory->isSame($territory));
$this->assertTrue($territory->isSame($equalsNotSame));
$this->assertFalse($territory->isContainedIn($territory));
$this->assertTrue($territory->isSameOrContainedIn($territory));
if ($ascending !== null) {
$this->assertTrue($ascending->contains($territory));
}
if ($territory instanceof TerritoryWithChildren) {
if ($ascending !== null) {
$this->assertFalse($territory->contains($ascending));
}
$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));
$this->assertTrue($child->isContainedIn($territory));
$this->assertTrue($child->isSameOrContainedIn($territory));
$this->assertTrue($territory->contains($child));
$this->assertTrue($territory->isSameOrContains($child));
if ($child instanceof TerritoryWithChildren) {
$this->assertFalse($child->contains($territory));
$this->assertFalse($child->isSameOrContains($territory));
$this->testHierarchyFor($child, $equalsNotSame->getChildren()[0], $ascending ?? $territory);
}
}
}
}

0 comments on commit 30e6ade

Please sign in to comment.