Skip to content

Commit 83101e9

Browse files
authored
Merge pull request #396 from zigzagdev/chore/integrate-image_url-into-image-table
feat: migrate image storage from image_url field to world_heritage_site_images table
2 parents 92b53c1 + 03a13ca commit 83101e9

15 files changed

+230
-339
lines changed

src/app/Console/Commands/AlgoliaImportWorldHeritages.php

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,12 @@ public function handle(): int
5151

5252
WorldHeritage::query()
5353
->with([
54-
'countries',
54+
'images' => function ($query) {
55+
$query->where('is_primary', true)->select(['world_heritage_site_id', 'url']);
56+
},
57+
'countries' => function ($query) {
58+
$query->select(['countries.state_party_code', 'countries.name_en', 'countries.name_jp']);
59+
},
5560
])
5661
->select([
5762
'world_heritage_sites.id',
@@ -63,7 +68,6 @@ public function handle(): int
6368
'world_heritage_sites.category',
6469
'world_heritage_sites.year_inscribed',
6570
'world_heritage_sites.is_endangered',
66-
'world_heritage_sites.image_url',
6771
])
6872
->chunkById($chunk, function ($rows) use ($client, $indexName, $dryRun, &$processed) {
6973
$objects = [];
@@ -130,7 +134,7 @@ public function handle(): int
130134
'category' => (string) $row->category,
131135
'year_inscribed' => $row->year_inscribed !== null ? (int) $row->year_inscribed : null,
132136
'is_endangered' => (bool) $row->is_endangered,
133-
'thumbnail_url' => $row->image_url !== null ? (string) $row->image_url : null,
137+
'thumbnail_url' => $row->images->first()?->url,
134138
'state_party_codes' => $statePartyCodes,
135139
'country_names_jp' => $countryCount > 1 ? $countryNamesJp : [],
136140
];

src/app/Console/Commands/ImportWorldHeritageSiteFromSplitFile.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,6 @@ public function handle(): int
9696
'latitude' => $this->toNullableFloat($row['latitude'] ?? null),
9797
'longitude' => $this->toNullableFloat($row['longitude'] ?? null),
9898
'short_description' => $this->toNullableString($row['short_description'] ?? null),
99-
'image_url' => $this->toNullableString($row['image_url'] ?? null),
10099
'unesco_site_url' => $this->toNullableString($row['unesco_site_url'] ?? null),
101100
'created_at' => $now,
102101
'updated_at' => $now,

src/app/Console/Commands/SplitWorldHeritageJson.php

Lines changed: 76 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,13 @@ public function handle(): int
9595
$normalizer = app(CountryCodeNormalizer::class);
9696

9797
$logged = 0;
98-
$logSkip = function (string $reason, int $index, mixed $idNo = null, array $extra = []) use ($logLimit, &$logged): void {
98+
$logSkip = function (
99+
string $reason,
100+
int $index,
101+
mixed $idNo = null,
102+
array $extra =
103+
[]
104+
) use ($logLimit, &$logged): void {
99105
if ($logLimit <= 0) {
100106
return;
101107
}
@@ -324,9 +330,9 @@ public function handle(): int
324330
];
325331
} else {
326332
if (($countries[$code3]['name_en'] ?? null) === $code3) {
327-
$better = $names[$idx] ?? $names[0] ?? null;
328-
if (is_string($better) && trim($better) !== '') {
329-
$countries[$code3]['name_en'] = trim($better);
333+
$betterName = $names[$idx] ?? $names[0] ?? null;
334+
if (is_string($betterName) && trim($betterName) !== '') {
335+
$countries[$code3]['name_en'] = trim($betterName);
330336
}
331337
}
332338
if (($countries[$code3]['region'] ?? null) === null && $region !== null) {
@@ -609,14 +615,14 @@ private function extractIsoCodes(mixed $v): array
609615
$out = [];
610616
$seen = [];
611617

612-
foreach ($parts as $p) {
613-
$p = strtoupper($p);
614-
if ($p === '') {
618+
foreach ($parts as $part) {
619+
$part = strtoupper($part);
620+
if ($part === '') {
615621
continue;
616622
}
617-
if (!isset($seen[$p])) {
618-
$seen[$p] = true;
619-
$out[] = $p;
623+
if (!isset($seen[$part])) {
624+
$seen[$part] = true;
625+
$out[] = $part;
620626
}
621627
}
622628

@@ -632,8 +638,8 @@ private function normalizeStatesNames(mixed $statesNames): array
632638
$seen = [];
633639
$out = [];
634640

635-
foreach ($statesNames as $v) {
636-
$name = trim((string) $v);
641+
foreach ($statesNames as $stateName) {
642+
$name = trim((string) $stateName);
637643
if ($name === '') {
638644
continue;
639645
}
@@ -650,49 +656,49 @@ private function extractImageUrls(array $row): array
650656
{
651657
$urls = [];
652658

653-
$main = $row['main_image_url']['url'] ?? null;
654-
if (is_string($main)) {
655-
$main = trim($main);
656-
if ($main !== '') {
657-
$urls[] = $main;
659+
$mainImageUrl = $row['main_image_url']['url'] ?? null;
660+
if (is_string($mainImageUrl)) {
661+
$mainImageUrl = trim($mainImageUrl);
662+
if ($mainImageUrl !== '') {
663+
$urls[] = $mainImageUrl;
658664
}
659665
}
660666

661-
$images = $row['images_urls'] ?? null;
667+
$imageUrls = $row['images_urls'] ?? null;
662668

663-
if (is_string($images)) {
664-
$parts = preg_split('/\s*,\s*/', trim($images)) ?: [];
665-
foreach ($parts as $p) {
666-
$p = trim($p);
667-
if ($p !== '') {
668-
$urls[] = $p;
669+
if (is_string($imageUrls)) {
670+
$parts = preg_split('/\s*,\s*/', trim($imageUrls)) ?: [];
671+
foreach ($parts as $part) {
672+
$part = trim($part);
673+
if ($part !== '') {
674+
$urls[] = $part;
669675
}
670676
}
671677
}
672678

673-
if (is_array($images)) {
674-
foreach ($images as $p) {
675-
if (!is_string($p)) {
679+
if (is_array($imageUrls)) {
680+
foreach ($imageUrls as $imageUrl) {
681+
if (!is_string($imageUrl)) {
676682
continue;
677683
}
678-
$p = trim($p);
679-
if ($p !== '') {
680-
$urls[] = $p;
684+
$imageUrl = trim($imageUrl);
685+
if ($imageUrl !== '') {
686+
$urls[] = $imageUrl;
681687
}
682688
}
683689
}
684690

685691
$seen = [];
686-
$out = [];
687-
foreach ($urls as $u) {
688-
if (isset($seen[$u])) {
692+
$deduplicated = [];
693+
foreach ($urls as $url) {
694+
if (isset($seen[$url])) {
689695
continue;
690696
}
691-
$seen[$u] = true;
692-
$out[] = $u;
697+
$seen[$url] = true;
698+
$deduplicated[] = $url;
693699
}
694700

695-
return $out;
701+
return $deduplicated;
696702
}
697703

698704
private function normalizeSiteRowImportReady(array $row, int $siteId): array
@@ -735,8 +741,6 @@ private function normalizeSiteRowImportReady(array $row, int $siteId): array
735741
'latitude' => isset($lat) ? (is_numeric($lat) ? (float) $lat : null) : null,
736742
'longitude' => isset($lon) ? (is_numeric($lon) ? (float) $lon : null) : null,
737743
'short_description' => $this->stringOrNull($row['short_description_en'] ?? null),
738-
'image_url' => $this->stringOrNull($row['image_url'] ?? null),
739-
'primary_image_url' => $this->stringOrNull($row['image_url'] ?? null),
740744
'unesco_site_url' => $this->stringOrNull($row['unesco_site_url'] ?? ($row['url'] ?? null)),
741745
];
742746
}
@@ -782,11 +786,11 @@ private function mergeSiteRowPreferExisting(array $existing, array $incoming): a
782786
if (($existing['state_party'] ?? null) === null) {
783787
$iso2List = $this->extractIsoCodes($incoming['iso_codes'] ?? null);
784788
if (count($iso2List) === 1) {
785-
$sp = $this->toIso3OrNull($iso2List[0]);
786-
if ($sp !== null) {
787-
$existing['state_party'] = $sp;
789+
$stateParty = $this->toIso3OrNull($iso2List[0]);
790+
if ($stateParty !== null) {
791+
$existing['state_party'] = $stateParty;
788792
if (($existing['country'] ?? null) === null) {
789-
$existing['country'] = $sp;
793+
$existing['country'] = $stateParty;
790794
}
791795
}
792796
}
@@ -804,25 +808,9 @@ private function mergeSiteRowPreferExisting(array $existing, array $incoming): a
804808

805809
$fill('short_description', $incoming['short_description_en'] ?? null);
806810

807-
if (($existing['image_url'] ?? null) === null || $existing['image_url'] === '') {
808-
$main = $incoming['main_image_url']['url'] ?? null;
809-
if (is_string($main)) {
810-
$main = trim($main);
811-
if ($main !== '') {
812-
$existing['image_url'] = mb_substr($main, 0, 255);
813-
}
814-
}
815-
}
816-
817-
if (($existing['primary_image_url'] ?? null) !== null) {
818-
$existing['primary_image_url'] = null;
819-
}
820-
821-
if (($existing['unesco_site_url'] ?? null) === null) {
822-
$u = $incoming['unesco_site_url'] ?? ($incoming['url'] ?? null);
823-
if ($u) {
824-
$existing['unesco_site_url'] = $u;
825-
}
811+
$unescoUrl = $incoming['unesco_site_url'] ?? ($incoming['url'] ?? null);
812+
if (($existing['unesco_site_url'] ?? null) === null && $unescoUrl) {
813+
$existing['unesco_site_url'] = $unescoUrl;
826814
}
827815

828816
return $existing;
@@ -945,11 +933,11 @@ private function cleanOutputDir(string $outDir): void
945933
$files = glob($pattern) ?: [];
946934
$deleted = 0;
947935

948-
foreach ($files as $f) {
949-
if (!is_file($f)) {
936+
foreach ($files as $file) {
937+
if (!is_file($file)) {
950938
continue;
951939
}
952-
if (@unlink($f)) {
940+
if (@unlink($file)) {
953941
$deleted++;
954942
}
955943
}
@@ -963,30 +951,17 @@ private function extractCriteriaList(mixed $criteriaTxt): array
963951
return [];
964952
}
965953

966-
$s = trim($criteriaTxt);
967-
if ($s === '') {
954+
$stringText = trim($criteriaTxt);
955+
if ($stringText === '') {
968956
return [];
969957
}
970958

971-
preg_match_all('/\(([ivx]+)\)/i', $s, $m);
972-
if (!isset($m[1]) || !is_array($m[1])) {
959+
preg_match_all('/\(([ivx]+)\)/i', $stringText, $matches);
960+
if (!isset($matches[1]) || !is_array($matches[1])) {
973961
return [];
974962
}
975963

976-
$out = [];
977-
$seen = [];
978-
foreach ($m[1] as $v) {
979-
$v = strtolower(trim((string) $v));
980-
if ($v === '') {
981-
continue;
982-
}
983-
if (!isset($seen[$v])) {
984-
$seen[$v] = true;
985-
$out[] = $v;
986-
}
987-
}
988-
989-
return $out;
964+
return $this->deduplicateCriteria($matches[1]);
990965
}
991966

992967
private function resolveCriteriaList(array $row): array
@@ -1001,12 +976,7 @@ private function resolveCriteriaList(array $row): array
1001976
return $criteria;
1002977
}
1003978

1004-
$criteria = $this->extractCriteriaFromJustification($row['justification_en'] ?? null);
1005-
if ($criteria !== []) {
1006-
return $criteria;
1007-
}
1008-
1009-
return [];
979+
return $this->extractCriteriaFromJustification($row['justification_en'] ?? null);
1010980
}
1011981

1012982
private function extractCriteriaFromJustification(mixed $justificationEn): array
@@ -1015,37 +985,41 @@ private function extractCriteriaFromJustification(mixed $justificationEn): array
1015985
return [];
1016986
}
1017987

1018-
$s = trim($justificationEn);
1019-
if ($s === '') {
988+
$stringText = trim($justificationEn);
989+
if ($stringText === '') {
1020990
return [];
1021991
}
1022992

1023-
$pos = stripos($s, 'criterion');
993+
$pos = stripos($stringText, 'criterion');
1024994
if ($pos === false) {
1025-
$pos = stripos($s, 'criteria');
995+
$pos = stripos($stringText, 'criteria');
1026996
}
1027997
if ($pos === false) {
1028998
return [];
1029999
}
10301000

1031-
$slice = substr($s, $pos, 600);
1001+
$slice = substr($stringText, $pos, 600);
10321002

1033-
preg_match_all('/\(([ivx]+)\)/i', $slice, $m);
1034-
if (!isset($m[1]) || !is_array($m[1]) || $m[1] === []) {
1003+
preg_match_all('/\(([ivx]+)\)/i', $slice, $matches);
1004+
if (!isset($matches[1]) || !is_array($matches[1]) || $matches[1] === []) {
10351005
return [];
10361006
}
10371007

1008+
return $this->deduplicateCriteria($matches[1]);
1009+
}
1010+
1011+
private function deduplicateCriteria(array $criteriaMatches): array
1012+
{
10381013
$out = [];
10391014
$seen = [];
1040-
foreach ($m[1] as $v) {
1041-
$v = strtolower(trim((string) $v));
1042-
if ($v === '') {
1015+
1016+
foreach ($criteriaMatches as $criterion) {
1017+
$criterion = strtolower(trim((string) $criterion));
1018+
if ($criterion === '' || isset($seen[$criterion])) {
10431019
continue;
10441020
}
1045-
if (!isset($seen[$v])) {
1046-
$seen[$v] = true;
1047-
$out[] = $v;
1048-
}
1021+
$seen[$criterion] = true;
1022+
$out[] = $criterion;
10491023
}
10501024

10511025
return $out;

src/app/Models/Country.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
namespace App\Models;
44

5-
use App\Models\WorldHeritage;
65
use Illuminate\Database\Eloquent\Model;
76
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
87

src/app/Models/Image.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
namespace App\Models;
44

55
use Illuminate\Database\Eloquent\Model;
6-
use Illuminate\Database\Eloquent\SoftDeletes;
76

87
class Image extends Model
98
{
@@ -23,6 +22,13 @@ class Image extends Model
2322
'updated_at',
2423
];
2524

25+
public function casts(): array
26+
{
27+
return [
28+
'is_primary' => 'boolean',
29+
];
30+
}
31+
2632
public function worldHeritage()
2733
{
2834
return $this->belongsTo(WorldHeritage::class, 'world_heritage_site_id', 'id');

src/app/Models/WorldHeritage.php

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ class WorldHeritage extends Model
3535
'longitude',
3636
'short_description',
3737
'unesco_site_url',
38-
'thumbnail_image_id',
3938
];
4039

4140
protected $hidden = [
@@ -61,10 +60,6 @@ public function images(): HasMany
6160
->orderBy('sort_order', 'asc');
6261
}
6362

64-
public function thumbnail(): BelongsTo
65-
{
66-
return $this->belongsTo(Image::class, 'thumbnail_image_id');
67-
}
6863
protected function casts(): array
6964
{
7065
return [

0 commit comments

Comments
 (0)