Skip to content

Commit d4f3f35

Browse files
committed
Add country builder; Add all timezones and countries; Add languages cz, de, en, es, fr, hr, it, pl, se
1 parent 4f063d1 commit d4f3f35

23 files changed

+4295
-317
lines changed

bin/build-countries

Lines changed: 392 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,392 @@
1+
<?php
2+
3+
// #!/usr/bin/env php
4+
5+
require_once 'vendor/autoload.php';
6+
7+
use Ixnode\PhpNamingConventions\Exception\FunctionReplaceException;
8+
use Ixnode\PhpNamingConventions\NamingConventions;
9+
10+
class BuildCountries
11+
{
12+
private const CLASS_TEMPLATE = <<<EOT
13+
<?php
14+
15+
/*
16+
* This file is part of the ixnode/php-timezone project.
17+
*
18+
* (c) Björn Hempel <https://www.hempel.li/>
19+
*
20+
* For the full copyright and license information, please view the LICENSE.md
21+
* file that was distributed with this source code.
22+
*/
23+
24+
declare(strict_types=1);
25+
26+
namespace Ixnode\PhpTimezone\Constants;
27+
28+
/**
29+
* Class Country%s (auto-generated with bin/build-countries from "%s")
30+
*
31+
* @author Björn Hempel <bjoern@hempel.li>
32+
* @version 0.1.0 (%s)
33+
* @since 0.1.0 (%s) Generated version.
34+
*/
35+
class Country%s
36+
{
37+
%s}
38+
39+
EOT;
40+
41+
private const CLASS_TEMPLATE_ALL = <<<EOT
42+
<?php
43+
44+
/*
45+
* This file is part of the ixnode/php-timezone project.
46+
*
47+
* (c) Björn Hempel <https://www.hempel.li/>
48+
*
49+
* For the full copyright and license information, please view the LICENSE.md
50+
* file that was distributed with this source code.
51+
*/
52+
53+
declare(strict_types=1);
54+
55+
namespace Ixnode\PhpTimezone\Constants;
56+
57+
/**
58+
* Class CountryAll (auto-generated with bin/build-countries from "%s")
59+
*
60+
* @author Björn Hempel <bjoern@hempel.li>
61+
* @version 0.1.0 (%s)
62+
* @since 0.1.0 (%s) Generated version.
63+
*/
64+
class CountryAll
65+
{
66+
public const COUNTRY_NAMES = [
67+
68+
%s
69+
/* Unknown/Invalid */
70+
CountryUnknown::COUNTRY_CODE_UK => CountryUnknown::COUNTRY_NAME_UK,
71+
CountryUnknown::COUNTRY_CODE_IV => CountryUnknown::COUNTRY_NAME_IV,
72+
];
73+
}
74+
75+
EOT;
76+
77+
private array $countries;
78+
79+
/** @var array $collectedCodes */
80+
private array $collectedCodes = [];
81+
82+
/**
83+
* @param string $csvFileCountries
84+
* @param array $csvFilesContinents
85+
*/
86+
public function __construct(protected string $csvFileCountries, protected array $csvFilesContinents)
87+
{
88+
$this->countries = $this->getCountries();
89+
}
90+
91+
/**
92+
* Returns the countries from given CSV file.
93+
*
94+
* @return array
95+
*/
96+
private function getCountries(): array
97+
{
98+
/* Check if the file exists. */
99+
if (!file_exists($this->csvFileCountries)) {
100+
print sprintf('The given file does not exist ("%s").%s', $this->csvFileCountries, PHP_EOL);
101+
exit(1);
102+
}
103+
104+
/* Load the content of the file. */
105+
$csvContent = file_get_contents($this->csvFileCountries);
106+
107+
/* Convert the content of the CSV into an array. */
108+
$data = array();
109+
$lines = explode(PHP_EOL, $csvContent);
110+
111+
/* The first line contains the languages, we use these as keys for the array. */
112+
$languages = str_getcsv(array_shift($lines), ';');
113+
114+
/* Remove the first column, because it does contain the locale header. */
115+
array_shift($languages);
116+
117+
foreach ($lines as $line) {
118+
119+
/* Ignore empty lines. */
120+
if (empty($line)) {
121+
continue;
122+
}
123+
124+
$values = str_getcsv($line, ';');
125+
126+
/* Use the first column as key. */
127+
$key = array_shift($values);
128+
129+
$data[$key] = array_combine($languages, $values);
130+
}
131+
132+
return $data;
133+
}
134+
135+
/**
136+
* Combines the given country CSV file with the continent file.
137+
*
138+
* @param string $csvContinent
139+
* @return array
140+
*/
141+
private function getContinentValue(string $csvContinent): array
142+
{
143+
/* Check if the file exists. */
144+
if (!file_exists($csvContinent)) {
145+
print sprintf('The given file does not exist ("%s").%s', $csvContinent, PHP_EOL);
146+
exit(1);
147+
}
148+
149+
/* Load the content of the file. */
150+
$csvContent = file_get_contents($csvContinent);
151+
152+
/* Convert the content of the CSV into an array. */
153+
$data = array();
154+
$lines = explode(PHP_EOL, $csvContent);
155+
156+
/* The first line contains the languages, we use these as keys for the array. */
157+
array_shift($lines);
158+
159+
foreach ($lines as $line) {
160+
161+
/* Ignore empty lines. */
162+
if (empty($line)) {
163+
continue;
164+
}
165+
166+
$values = str_getcsv($line, ';');
167+
168+
$iso2 = $values[0];
169+
$iso3 = $values[1];
170+
$tld = str_replace('.', '', $values[2]);
171+
172+
$values = [
173+
'iso2' => $iso2,
174+
'iso3' => $iso3,
175+
'name' => $this->countries[$iso2],
176+
'tld' => $tld,
177+
];
178+
179+
$data[$iso2] = $values;
180+
}
181+
182+
return $data;
183+
}
184+
185+
/**
186+
* @return array
187+
* @throws FunctionReplaceException
188+
*/
189+
public function getContinentValues(): array
190+
{
191+
$data = [];
192+
193+
foreach ($this->csvFilesContinents as $continent => $csvFileContinent) {
194+
$className = (new NamingConventions($continent))->getPascalCase();
195+
$name = (new NamingConventions($continent))->getTitle();
196+
197+
$data[$continent] = [
198+
'file' => $csvFileContinent,
199+
'name' => $name,
200+
'class-name' => $className,
201+
'class-file' => sprintf('src/Constants/Country%s.php', $className),
202+
'data' => $this->getContinentValue($csvFileContinent)
203+
];
204+
}
205+
206+
return $data;
207+
}
208+
209+
/**
210+
* Returns the constants as string representation (encapsulated within an array).
211+
*
212+
* @return array
213+
*/
214+
public function getConstantsAsString(): array
215+
{
216+
$constantsData = [];
217+
218+
foreach ($this->getContinentValues() as $continent => $countries) {
219+
$file = $countries['file'];
220+
$name = $countries['name'];
221+
$className = $countries['class-name'];
222+
$classFile = $countries['class-file'];
223+
$data = $countries['data'];
224+
225+
$codeConstants = [];
226+
227+
if (!array_key_exists($continent, $this->collectedCodes)) {
228+
$this->collectedCodes[$continent] = [
229+
'name' => $name,
230+
'data' => [],
231+
];
232+
}
233+
234+
foreach ($data as $iso2 => $country) {
235+
$this->collectedCodes[$continent]['data'][] = sprintf(
236+
'Country%s::COUNTRY_CODE_%s => Country%s::COUNTRY_NAME_%s,',
237+
$className,
238+
strtoupper($iso2),
239+
$className,
240+
strtoupper($iso2)
241+
);
242+
}
243+
244+
foreach ($data as $iso2 => $country) {
245+
$codeConstants[] = sprintf(
246+
' public const COUNTRY_CODE_%s = \'%s\';',
247+
strtoupper($iso2),
248+
strtoupper($iso2)
249+
);
250+
}
251+
252+
$nameConstants = [];
253+
254+
foreach ($data as $iso2 => $country) {
255+
$languages = [];
256+
257+
$names = $country['name'];
258+
259+
foreach ($names as $language => $name) {
260+
$languages[] = sprintf(
261+
' Locale::%s => \'%s\',',
262+
strtoupper($language),
263+
str_replace('\'', '\\\'', $name)
264+
);
265+
}
266+
267+
$nameConstants[] = sprintf(
268+
' public const COUNTRY_NAME_%s = [%s%s%s];',
269+
strtoupper($iso2),
270+
PHP_EOL,
271+
implode(PHP_EOL, $languages),
272+
PHP_EOL.' '
273+
);
274+
}
275+
276+
$constantsData[$continent] = [
277+
'data' => sprintf(
278+
'%s%s%s%s%s',
279+
' /* Country codes */'.PHP_EOL,
280+
implode(PHP_EOL, $codeConstants).PHP_EOL,
281+
PHP_EOL,
282+
' /* Country language names */'.PHP_EOL,
283+
implode(PHP_EOL, $nameConstants).PHP_EOL
284+
),
285+
'file' => $file,
286+
'class-name' => $className,
287+
'class-file' => $classFile,
288+
];
289+
}
290+
291+
return $constantsData;
292+
}
293+
294+
/**
295+
* Returns the full class string.
296+
*
297+
* @return array
298+
*/
299+
public function getClasses(): array
300+
{
301+
$classes = [];
302+
303+
foreach ($this->getConstantsAsString() as $continent => $constantsData) {
304+
$data = $constantsData['data'];
305+
$file = $constantsData['file'];
306+
$className = $constantsData['class-name'];
307+
$classFile = $constantsData['class-file'];
308+
309+
$classes[$continent] = [
310+
'data' => sprintf(
311+
self::CLASS_TEMPLATE,
312+
$className,
313+
$file,
314+
date('Y-m-d H:i:s'),
315+
date('Y-m-d H:i:s'),
316+
$className,
317+
$data
318+
),
319+
'file' => $file,
320+
'class-name' => $className,
321+
'class-file' => $classFile,
322+
];
323+
}
324+
325+
return $classes;
326+
}
327+
328+
/**
329+
* Writes classes to given php file.
330+
*
331+
* @return bool
332+
*/
333+
public function writeClasses(): bool
334+
{
335+
foreach ($this->getClasses() as $continent => $classesData) {
336+
$data = $classesData['data'];
337+
$file = $classesData['file'];
338+
$className = $classesData['class-name'];
339+
$classFile = $classesData['class-file'];
340+
341+
file_put_contents($classFile, $data);
342+
print sprintf('Class %s written.'.PHP_EOL, $classFile);
343+
}
344+
345+
$allContent = [];
346+
foreach ($this->collectedCodes as $continent) {
347+
$name = $continent['name'];
348+
$data = $continent['data'];
349+
350+
$allContent[] = sprintf(' /* %s */', $name);
351+
352+
foreach ($data as $collected) {
353+
$allContent[] = sprintf(' %s', $collected);
354+
}
355+
356+
$allContent[] = '';
357+
}
358+
359+
/* Register all variables to all class. */
360+
$classFile = 'src/Constants/CountryAll.php';
361+
$data = sprintf(
362+
self::CLASS_TEMPLATE_ALL,
363+
implode(', ', $this->csvFilesContinents),
364+
date('Y-m-d H:i:s'),
365+
date('Y-m-d H:i:s'),
366+
implode(PHP_EOL, $allContent),
367+
);
368+
file_put_contents($classFile, $data);
369+
print sprintf('Class %s written.'.PHP_EOL, $classFile);
370+
371+
return true;
372+
}
373+
}
374+
375+
376+
$csvFileCountries = 'data/countries.csv';
377+
$csvFiles = [
378+
'africa' => 'data/africa.csv',
379+
'antarctica' => 'data/antarctica.csv',
380+
'asia' => 'data/asia.csv',
381+
'australia' => 'data/australia.csv',
382+
'europe' => 'data/europe.csv',
383+
'north-america' => 'data/north-america.csv',
384+
'south-america' => 'data/south-america.csv',
385+
];
386+
387+
$buildCountries = new BuildCountries($csvFileCountries, $csvFiles);
388+
389+
match ($buildCountries->writeClasses()) {
390+
true => print 'Classes written.',
391+
false => print 'Unable to write classes.',
392+
};

0 commit comments

Comments
 (0)