diff --git a/src/Benzina/ProjectsPumpTrait.php b/src/Benzina/ProjectsPumpTrait.php index a3c9abf..ededdc3 100644 --- a/src/Benzina/ProjectsPumpTrait.php +++ b/src/Benzina/ProjectsPumpTrait.php @@ -5,9 +5,9 @@ namespace App\Benzina; trait ProjectsPumpTrait { /** - * Cleans the project location field to obtain better and more cacheable search queries. + * Cleans the project location field to obtain highly cacheable and improved search queries. * Based on analysis of the Goteo v3 `project.project_location` values. - * + * * @param int $detailLevel Desired number of remaining components in output address */ public static function cleanProjectLocation(string $location, int $detailLevel = 3): string @@ -23,7 +23,7 @@ trait ProjectsPumpTrait // Remove secondary conjoined places from locations // e.g: "España y el mundo" -> "España" - foreach ([' / ', ' | ', ' - ', ' y ', ' and '] as $conjoinment) { + foreach ([' / ', ' | ', ' - ', ' y ', ' and ', ' & '] as $conjoinment) { if (\str_contains($location, $conjoinment)) { $location = \explode($conjoinment, $location)[0]; } @@ -41,13 +41,30 @@ trait ProjectsPumpTrait // Clean non desired location pieces $location = \explode(',', $location); - $location = \array_map(fn($l) => trim($l), $location); + $location = \array_map(function ($l) { + $l = trim($l); + + // Normalize typos and name variations + foreach (self::COMMON_VARIATIONS as $standard => $variations) { + if (in_array(\mb_strtoupper($l), $variations)) { + $l = $standard; + } + } + + return $l; + }, $location); $location = \array_filter($location, function ($l) { - if (empty($l)) return false; - + if (empty($l)) { + return false; + } + // Skip numeric only pieces: coordinates, street numbers, etc - if (\preg_match('/^[-\d.]*$/', $l)) return false; - if (\str_contains($l, 'º')) return false; + if (\preg_match('/^[-\d.]*$/', $l)) { + return false; + } + if (\str_contains($l, 'º')) { + return false; + } return true; }); @@ -59,6 +76,28 @@ trait ProjectsPumpTrait return \mb_strtoupper(\trim($location)); } + /** + * @var array The standard preferred name and a list of possible variations and misspellings + */ + private const COMMON_VARIATIONS = [ + 'ESPAÑA' => ['ESPANYA', 'ESPANHA', 'ESPAGNE', 'SPAGNA', 'SPANIEN', 'SPAIN'], + 'CATALUÑA' => ['CATALUNYA', 'PAÏSOS CATALANS'], + 'ANDALUCÍA' => ['ANDALUCIA', 'ANDALUSIA'], + 'FRANCIA' => ['FRANCE'], + 'ITALIA' => ['ITALY'], + 'ALEMANIA' => ['GERMANY'], + 'CÁDIZ' => ['CADIZ'], + 'VALENCIA' => ['VALÈNCIA', 'PROVINCIA DE VALENCIA'], + 'ALICANTE' => ['ALACANT'], + 'CÁCERES' => ['CACERES'], + 'BALEARES' => ['BALEAREN', 'ISLAS BALEARES', 'ILLES BALEARS', 'BALEARIC ISLANDS'], + 'GALICIA' => ['GALIZA'], + 'BILBAO' => ['BILBO'], + 'LLEIDA' => ['LÉRIDA'], + 'BARCELONA' => ['PROVINCIA DE BARCELONA'], + 'MURCIA' => ['REGIÓN DE MURCIA'], + ]; + private const PROJECT_KEYS = [ 'id', 'name', diff --git a/tests/Benzina/ProjectsPumpTraitTest.php b/tests/Benzina/ProjectsPumpTraitTest.php index 1b6e2e4..44ae4bb 100644 --- a/tests/Benzina/ProjectsPumpTraitTest.php +++ b/tests/Benzina/ProjectsPumpTraitTest.php @@ -37,7 +37,7 @@ class ProjectsPumpTraitTest extends TestCase ['http://www.ecologiaperumanu.com/mapaproyecto.php'], ['http://www.esbaluard.org/es/'], ['https://www.google.es/maps/@40.0320175,-5.7727571,500m/data=!3m1!1e3'], - ['www.google.com/maps/place/Tecoanapa,+Gro./@16.9873264,-99.2593372,18.25z/data=!4m5!3m4!1s0x85ca2be1bd85bfcd:0xd3cb17e67573bf44!8m2!3d16.9865731!4d-99.2604936'] + ['www.google.com/maps/place/Tecoanapa,+Gro./@16.9873264,-99.2593372,18.25z/data=!4m5!3m4!1s0x85ca2be1bd85bfcd:0xd3cb17e67573bf44!8m2!3d16.9865731!4d-99.2604936'], ]; } @@ -50,7 +50,7 @@ class ProjectsPumpTraitTest extends TestCase $this->assertEquals($finalAddress, $cleanAddress); } - + public function provideConjoinedAddresses(): array { return [ @@ -58,7 +58,7 @@ class ProjectsPumpTraitTest extends TestCase ['buenos aires, argentina y barcelona españa', 'BUENOS AIRES, ARGENTINA'], ['Barcelona y Bilbao', 'BARCELONA'], ['Madrid, España / San Francisco, EEUU', 'MADRID, ESPAÑA'], - ['Calafou, Camí de Ca la Fou, s/n | CP: 08785 | Vallbona d´Anoia (Barcelona)', 'CALAFOU, CAMÍ DE CA LA FOU, S/N'] + ['Calafou, Camí de Ca la Fou, s/n | CP: 08785 | Vallbona d´Anoia (Barcelona)', 'CALAFOU, CAMÍ DE CA LA FOU, S/N'], ]; } @@ -68,7 +68,7 @@ class ProjectsPumpTraitTest extends TestCase public function testStripsColonSpecifiers($colonSpecified, $removedSpecifier) { $cleanAddress = $this->pump->cleanProjectLocation($colonSpecified); - + $this->assertStringNotContainsString($removedSpecifier, $cleanAddress); } @@ -96,7 +96,27 @@ class ProjectsPumpTraitTest extends TestCase return [ [', Cali, Colombia', 'CALI, COLOMBIA'], ['Lobres (Granada', 'LOBRES, GRANADA'], - ['California City, California, EE. UU.', 'CALIFORNIA CITY, CALIFORNIA, EE. UU'] + ['California City, California, EE. UU.', 'CALIFORNIA CITY, CALIFORNIA, EE. UU'], + ]; + } + + /** + * @dataProvider provideCountryVariations + */ + public function testStandarisesCountry($variation, $standard) + { + $cleanAddress = $this->pump->cleanProjectLocation($variation); + + $this->assertEquals($standard, $cleanAddress); + } + + public function provideCountryVariations(): array + { + return [ + ['SPAIN', 'ESPAÑA'], + ['MADRID, ESPAÑA', 'MADRID, ESPAÑA'], + ['MADRID, ESPANYA', 'MADRID, ESPAÑA'], + ['MADRID, ESPAGNE', 'MADRID, ESPAÑA'], ]; } }