Changeset View
Changeset View
Standalone View
Standalone View
src/app/Console/Commands/DataCountries.php
<?php | <?php | ||||
namespace App\Console\Commands; | namespace App\Console\Commands; | ||||
use Illuminate\Console\Command; | use Illuminate\Console\Command; | ||||
class DataCountries extends Command | class DataCountries extends Command | ||||
{ | { | ||||
private $currency_fixes = [ | |||||
// Country code => currency | |||||
'LT' => 'EUR', | |||||
]; | |||||
/** | /** | ||||
* The name and signature of the console command. | * The name and signature of the console command. | ||||
* | * | ||||
* @var string | * @var string | ||||
*/ | */ | ||||
protected $signature = 'data:countries'; | protected $signature = 'data:countries'; | ||||
/** | /** | ||||
* The console command description. | * The console command description. | ||||
* | * | ||||
* @var string | * @var string | ||||
*/ | */ | ||||
protected $description = 'Fetches countries map from wikipedia'; | protected $description = 'Fetches countries map from wikipedia'; | ||||
/** | /** | ||||
* Execute the console command. | * Execute the console command. | ||||
* | * | ||||
* @return mixed | * @return mixed | ||||
*/ | */ | ||||
public function handle() | public function handle() | ||||
{ | { | ||||
$countries = []; | $countries = []; | ||||
$currencies = []; | $currencies = []; | ||||
$currencies_url = 'http://en.wikipedia.org/wiki/ISO_4217'; | $currencies_url = 'http://country.io/currency.json'; | ||||
$countries_url = 'http://en.wikipedia.org/wiki/ISO_3166-1'; | $countries_url = 'http://country.io/names.json'; | ||||
$this->info("Fetching currencies from $currencies_url..."); | $this->info("Fetching currencies from $currencies_url..."); | ||||
// fetch currency table and create an index by country page url | // fetch currency table and create an index by country page url | ||||
$page = file_get_contents($currencies_url); | $currencies_json = file_get_contents($currencies_url); | ||||
if (!$page) { | if (!$currencies_json) { | ||||
$this->error("Failed to fetch currencies"); | $this->error("Failed to fetch currencies"); | ||||
return; | return; | ||||
} | } | ||||
$table_regexp = '!<table class="(wikitable|prettytable) sortable".+</table>!ims'; | |||||
if (preg_match_all($table_regexp, $page, $matches, PREG_PATTERN_ORDER)) { | |||||
foreach ($matches[0] as $currency_table) { | |||||
preg_match_all('!<tr>\s*<td>(.+)</td>\s*</tr>!Ums', $currency_table, $rows); | |||||
foreach ($rows[1] as $row) { | |||||
$cells = preg_split('!</td>\s*<td[^>]*>!', $row); | |||||
if (count($cells) == 5) { | |||||
// actual currency table | |||||
$currency = preg_match('/([A-Z]{3})/', $cells[0], $m) ? $m[1] : ''; | |||||
if (preg_match('/(\d+)/', $cells[1], $m)) { | |||||
$isocode = $m[1]; | |||||
$currencies[$m[1]] = $currency; | |||||
} | |||||
preg_match_all('!<a[^>]+href="(/wiki/[^"]+)"[^>]*>!', $cells[4], $links, PREG_PATTERN_ORDER); | |||||
foreach ($links[1] as $link) { | |||||
$currencies[strtolower($link)] = $currency; | |||||
} | |||||
} elseif (count($cells) == 7) { | |||||
// replacements table | |||||
$currency = preg_match('/([A-Z]{3})/', $cells[6], $m) ? $m[1] : ''; | |||||
if (preg_match('/(\d+)/', $cells[1], $m)) { | |||||
$currencies[$m[1]] = $currency; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} | |||||
$namecol = 0; | |||||
$codecol = 1; | |||||
$numcol = 3; | |||||
$lang = 'en'; | |||||
$this->info("Fetching countries from $countries_url..."); | $this->info("Fetching countries from $countries_url..."); | ||||
$page = file_get_contents($countries_url); | $countries_json = file_get_contents($countries_url); | ||||
if (!$page) { | if (!$countries_json) { | ||||
$this->error("Failed to fetch countries"); | $this->error("Failed to fetch countries"); | ||||
return; | return; | ||||
} | } | ||||
if (preg_match($table_regexp, $page, $matches)) { | $currencies = json_decode($currencies_json, true); | ||||
preg_match_all('!<tr>\s*<td>(.+)</td>\s*</tr>!Ums', $matches[0], $rows); | $countries = json_decode($countries_json, true); | ||||
foreach ($rows[1] as $row) { | |||||
$cells = preg_split('!</td>\s*<td[^>]*>!', $row); | |||||
if (count($cells) < 5) { | if (!is_array($countries) || empty($countries)) { | ||||
continue; | $this->error("Invalid countries data"); | ||||
} | return; | ||||
$regexp = '!<a[^>]+href="(/wiki/[^"]+)"[^>]*>([^>]+)</a>!i'; | |||||
$content = preg_match($regexp, $cells[$namecol], $m) ? $m : null; | |||||
if (preg_match('/>([A-Z]{2})</', $cells[$codecol], $m)) { | |||||
$code = $m[1]; | |||||
} elseif (preg_match('/^([A-Z]{2})/', $cells[$codecol], $m)) { | |||||
$code = $m[1]; | |||||
} else { | |||||
continue; | |||||
} | } | ||||
if ($content) { | if (!is_array($currencies) || empty($currencies)) { | ||||
$isocode = preg_match('/(\d+)/', $cells[$numcol], $m) ? $m[1] : ''; | $this->error("Invalid currencies data"); | ||||
list(, $link, $name) = $content; | return; | ||||
$countries[$code][$lang] = $name; | |||||
if (!empty($currencies[$isocode])) { | |||||
$countries[$code]['currency'] = $currencies[$isocode]; | |||||
} elseif (!empty($currencies[strtolower($link)])) { | |||||
$countries[$code]['currency'] = $currencies[strtolower($link)]; | |||||
} | |||||
} | |||||
} | |||||
} | } | ||||
$file = resource_path('countries.php'); | $file = resource_path('countries.php'); | ||||
$this->info("Generating resource file $file..."); | $this->info("Generating resource file $file..."); | ||||
asort($countries); | |||||
$out = "<?php return [\n"; | $out = "<?php return [\n"; | ||||
foreach ($countries as $code => $names) { | foreach ($countries as $code => $name) { | ||||
if (!empty($names['en']) && !empty($names['currency'])) { | $currency = $currencies[$code] ?? null; | ||||
$out .= sprintf(" '%s' => ['%s','%s'],\n", $code, $names['currency'], addslashes($names['en'])); | |||||
if (!empty($this->currency_fixes[$code])) { | |||||
$currency = $this->currency_fixes[$code]; | |||||
} | } | ||||
if (!$currency) { | |||||
$this->error("Unknown currency for {$name} ({$code}). Skipped."); | |||||
continue; | |||||
} | |||||
$out .= sprintf(" '%s' => ['%s','%s'],\n", $code, $currency, addslashes($name)); | |||||
} | } | ||||
$out .= "];\n"; | $out .= "];\n"; | ||||
file_put_contents($file, $out); | file_put_contents($file, $out); | ||||
} | } | ||||
} | } |