OpenXE/classes/Modules/Country/Service/CountryMigrationService.php
2021-05-21 08:49:41 +02:00

133 lines
5.0 KiB
PHP

<?php
namespace Xentral\Modules\Country\Service;
use Xentral\Components\Database\Database;
use Xentral\Modules\Country\Data\CountryData;
use Xentral\Modules\Country\Exception\CountryMigrationFailedException;
final class CountryMigrationService
{
/** @var Database $db */
private $db;
/**
* @param Database $database
*/
public function __construct(Database $database)
{
$this->db = $database;
}
/**
* Migration notwendig?
*
* * Prüft ob Länderliste in Datenbank vollständig
* * Prüft bei vorhandnen Ländern ob ISO3-Code in Datenbank gefüllt
*
* @param string $tableName
*
* @return bool
*/
public function needsMigration($tableName = 'laender')
{
$countries = $this->getCountryList();
$countryCodes = array_map(function ($country) {
/** @var CountryData $country */
return $country->getIsoAlpha2();
}, $countries);
// Check for empty ISO3 codes on existing entries
$emptyIso3Count = (int)$this->db->fetchValue(
"SELECT COUNT(*)
FROM {$tableName} AS l
WHERE l.iso IN (:country_codes)
AND (l.iso3 IS NULL OR l.iso3 = '')",
['country_codes' => $countryCodes]
);
if ($emptyIso3Count > 0) {
return true;
}
// Check for missing countries
$existingCount = (int)$this->db->fetchValue(
"SELECT COUNT(l.id) FROM {$tableName} AS l WHERE l.iso IN (:country_codes)",
['country_codes' => $countryCodes]
);
if ($existingCount !== count($countries)) {
return true;
}
return false;
}
/**
* @param string $tableName
*
* @return void
*/
public function doMigration($tableName = 'laender')
{
$countries = $this->getCountryList();
$iso2List = array_map(function ($country){
/** @var CountryData $country */
return '(SELECT "' . $this->db->escapeValue($country->getIsoAlpha2()) . '" AS iso2_orig,
"' . $this->db->escapeValue($country->getIsoAlpha3()) . '" AS iso3_orig,
"' . $this->db->escapeValue($country->getIsoNumeric()) . '" AS num_orig,
"' . $this->db->escapeValue($country->getNameGerman()) . '" AS name_de_orig,
"' . $this->db->escapeValue($country->getNameEnglish()) . '" AS name_en_orig,
"' . $this->db->escapeValue((int)$country->isEu()) . '" AS is_eu_orig)';
}, $countries);
$sqlIsoData = implode(' UNION ', $iso2List);
$missingValues = $this->db->fetchAll("SELECT * FROM {$tableName} AS l
RIGHT JOIN ({$sqlIsoData}) AS iso_data
ON l.iso=iso_data.iso2_orig
WHERE l.iso IS NULL OR l.iso = '' OR l.iso3 != iso_data.iso3_orig
");
//TODO check is ISO2 present multiple times
foreach ($missingValues as $missingValue){
if($missingValue['id'] == null){
// whole entry missing
$this->db->perform(
"INSERT INTO {$tableName}(iso, iso3, num_code, bezeichnung_de, bezeichnung_en, eu)
VALUES (:iso2_code, :iso3_code, :num_code, :name_de, :name_en, :is_eu)",
[
'iso2_code' => $missingValue['iso2_orig'],
'iso3_code' => $missingValue['iso3_orig'],
'num_code' => $missingValue['num_orig'],
'name_de' => $missingValue['name_de_orig'],
'name_en' => $missingValue['name_en_orig'],
'is_eu' => $missingValue['is_eu_orig'],
]
);
}else{
// entry corrupted/iso3 missing
$this->db->perform(
"UPDATE {$tableName} SET iso3 = :iso3_code, num_code = :num_code WHERE iso = :iso2_code LIMIT 1",
[
'iso2_code' => $missingValue['iso2_orig'],
'iso3_code' => $missingValue['iso3_orig'],
'num_code' => $missingValue['num_orig'],
]
);
}
}
}
/**
* @return CountryData[]
*/
public function getCountryList()
{
$countryArray = include __DIR__ . '/../migration/iso_code_data.php';
return array_map(function ($country) {
return new CountryData($country[0], $country[1], $country[2], $country[3], $country[4], (bool)$country[5]);
}, $countryArray);
}
}