Repo rebuild

This commit is contained in:
Mark Gregory
2026-09-15 12:33:28 +01:00
commit be28c4feec
5629 changed files with 317074 additions and 0 deletions
View File
@@ -0,0 +1,52 @@
<?php
namespace Modules\Countries\Support;
use Illuminate\Support\Collection;
use Modules\Countries\Models\Country;
use Modules\Countries\Models\CountrySubdivision;
class CountryRepository
{
/**
* Active countries for form selects.
*
* @return Collection<int, Country>
*/
public function activeForSelect(): Collection
{
return Country::query()->active()->ordered()
->get(['id', 'alpha2', 'alpha3', 'numeric', 'name', 'display_name', 'common_name', 'flag_emoji', 'region', 'subregion']);
}
public function findByAlpha2(string $alpha2): ?Country
{
return Country::query()->where('alpha2', Iso3166::normaliseAlpha2($alpha2))->first();
}
public function findByIsoCode(string $code): ?Country
{
return Country::query()->forIsoCode($code)->first();
}
public function findSubdivision(string $code): ?CountrySubdivision
{
return CountrySubdivision::query()->where('code', strtoupper(trim($code)))->first();
}
/**
* Active subdivisions for a country select.
*
* @return Collection<int, CountrySubdivision>
*/
public function activeSubdivisionsForCountry(string $alpha2): Collection
{
$alpha2 = Iso3166::normaliseAlpha2($alpha2);
return CountrySubdivision::query()
->where('country_alpha2', $alpha2)
->active()
->ordered()
->get(['id', 'country_alpha2', 'code', 'subdivision_code', 'name', 'local_name', 'type']);
}
}
@@ -0,0 +1,80 @@
<?php
namespace Modules\Countries\Support;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
use Modules\Countries\Models\Country;
class CountryUsageReport
{
/**
* Tables commonly using country_id in WMS and SaaS workflows.
*
* @var array<string, string>
*/
private array $countryIdTables = [
'companies' => 'Companies',
'warehouses' => 'Warehouses',
'users' => 'Users',
'suppliers' => 'Suppliers',
'customers' => 'Customers',
'carriers' => 'Carriers',
'addresses' => 'Addresses',
'billing_addresses' => 'Billing addresses',
'shipping_addresses' => 'Shipping addresses',
];
/**
* Tables commonly storing ISO alpha-2 country codes.
*
* @var array<string, string>
*/
private array $alpha2Tables = [
'companies' => 'Companies by ISO code',
'warehouses' => 'Warehouses by ISO code',
'addresses' => 'Addresses by ISO code',
'billing_addresses' => 'Billing addresses by ISO code',
'shipping_addresses' => 'Shipping addresses by ISO code',
];
/**
* Return usage counts without failing when optional business tables do not exist.
*
* @return array<int, array{label: string, table: string, column: string, count: int}>
*/
public function forCountry(Country $country): array
{
$rows = [];
foreach ($this->countryIdTables as $table => $label) {
if (! Schema::hasTable($table) || ! Schema::hasColumn($table, 'country_id')) {
continue;
}
$rows[] = [
'label' => $label,
'table' => $table,
'column' => 'country_id',
'count' => (int) DB::table($table)->where('country_id', $country->id)->count(),
];
}
foreach ($this->alpha2Tables as $table => $label) {
foreach (['country_code', 'country_alpha2', 'iso_country_code'] as $column) {
if (! Schema::hasTable($table) || ! Schema::hasColumn($table, $column)) {
continue;
}
$rows[] = [
'label' => $label,
'table' => $table,
'column' => $column,
'count' => (int) DB::table($table)->where($column, $country->alpha2)->count(),
];
}
}
return $rows;
}
}
+90
View File
@@ -0,0 +1,90 @@
<?php
namespace Modules\Countries\Support;
use InvalidArgumentException;
final class Iso3166
{
public const STATUS_OFFICIAL = 'official';
public const STATUS_RESERVED = 'reserved';
public const STATUS_TRANSITIONAL = 'transitional';
public const STATUS_DELETED = 'deleted';
public const STATUS_USER_ASSIGNED = 'user_assigned';
public const STATUS_EXCEPTIONALLY_RESERVED = 'exceptionally_reserved';
/** @return list<string> */
public static function statuses(): array
{
return [
self::STATUS_OFFICIAL,
self::STATUS_RESERVED,
self::STATUS_TRANSITIONAL,
self::STATUS_DELETED,
self::STATUS_USER_ASSIGNED,
self::STATUS_EXCEPTIONALLY_RESERVED,
];
}
public static function normaliseAlpha2(string $code): string
{
$normalised = strtoupper(trim($code));
if (! preg_match('/^[A-Z]{2}$/', $normalised)) {
throw new InvalidArgumentException('ISO 3166-1 alpha-2 codes must contain exactly two letters.');
}
return $normalised;
}
public static function normaliseAlpha3(string $code): string
{
$normalised = strtoupper(trim($code));
if (! preg_match('/^[A-Z]{3}$/', $normalised)) {
throw new InvalidArgumentException('ISO 3166-1 alpha-3 codes must contain exactly three letters.');
}
return $normalised;
}
public static function normaliseNumeric(string|int $code): string
{
$normalised = str_pad((string) $code, 3, '0', STR_PAD_LEFT);
if (! preg_match('/^[0-9]{3}$/', $normalised)) {
throw new InvalidArgumentException('ISO 3166-1 numeric codes must contain exactly three digits.');
}
return $normalised;
}
public static function normaliseSubdivisionCode(string $countryAlpha2, string $subdivisionCode): string
{
$country = self::normaliseAlpha2($countryAlpha2);
$code = strtoupper(trim($subdivisionCode));
if (str_starts_with($code, $country . '-')) {
return $code;
}
if (! preg_match('/^[A-Z0-9]{1,6}$/', $code)) {
throw new InvalidArgumentException('ISO 3166-2 subdivision codes must contain 1 to 6 letters or numbers after the country prefix.');
}
return $country . '-' . $code;
}
public static function flagEmoji(string $alpha2): string
{
$alpha2 = self::normaliseAlpha2($alpha2);
$base = 127397;
return mb_chr($base + ord($alpha2[0]), 'UTF-8') . mb_chr($base + ord($alpha2[1]), 'UTF-8');
}
}
+24
View File
@@ -0,0 +1,24 @@
<?php
namespace Modules\Countries\Support;
class ModuleInfo
{
protected static string $moduleName = 'Countries';
/**
* defines the Module Name
*/
public static function name(): string
{
return static::$moduleName;
}
/**
* define the lowercase version
*/
public static function nameLower(): string
{
return strtolower(static::$moduleName);
}
}