43 lines
1.6 KiB
PHP
43 lines
1.6 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use RuntimeException;
|
|
|
|
/** Public read projection authorized by Tempo; source rows and originals stay private. */
|
|
class ApprovedAdministrativeBoundaries
|
|
{
|
|
public const HASH = '06ab905fcf9b19115c3521bf81de03f37873880f7765f229b9e1f79d99df7adc';
|
|
|
|
/** @var array<string,array<string,string>>|null */
|
|
private ?array $items = null;
|
|
|
|
/** @return array<string,array<string,string>> */
|
|
public function snapshots(): array
|
|
{
|
|
if ($this->items !== null) {
|
|
return $this->items;
|
|
}
|
|
$contents = file_get_contents(base_path('docs/investmoz/unification/approved-administrative-boundaries-20261024.json'));
|
|
if ($contents === false || ! hash_equals(self::HASH, hash('sha256', str_replace("\r\n", "\n", $contents)))) {
|
|
throw new RuntimeException('Approved administrative boundary manifest changed.');
|
|
}
|
|
$manifest = json_decode($contents, true, 512, JSON_THROW_ON_ERROR);
|
|
if (count($manifest['items']) !== 408) {
|
|
throw new RuntimeException('Exact 408-boundary scope required.');
|
|
}
|
|
$this->items = array_column($manifest['items'], null, 'id');
|
|
|
|
return $this->items;
|
|
}
|
|
|
|
public function allows(string $id, string $territoryId, string $geometryHash, string $propertiesHash): bool
|
|
{
|
|
$item = $this->snapshots()[$id] ?? null;
|
|
|
|
return $item !== null && $item['territory_id'] === $territoryId
|
|
&& hash_equals($item['geometry_sha256'], $geometryHash)
|
|
&& hash_equals($item['properties_sha256'], $propertiesHash);
|
|
}
|
|
}
|