feat: update appraisal return address and test packaging assets
This commit is contained in:
296
server-api/tools/import_known_brands.php
Normal file
296
server-api/tools/import_known_brands.php
Normal file
@@ -0,0 +1,296 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
require dirname(__DIR__) . '/vendor/autoload.php';
|
||||
|
||||
const LEGACY_CODE_ALIASES = [
|
||||
'tiffany_co' => ['1'],
|
||||
];
|
||||
|
||||
$dryRun = in_array('--dry-run', $argv, true);
|
||||
$brandFile = dirname(__DIR__) . '/resources/catalog/known_brands.php';
|
||||
|
||||
if (!is_file($brandFile)) {
|
||||
fwrite(STDERR, "Known brand file not found: {$brandFile}\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$brands = require $brandFile;
|
||||
if (!is_array($brands)) {
|
||||
fwrite(STDERR, "Known brand file must return an array.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$dotenv = Dotenv\Dotenv::createImmutable(dirname(__DIR__));
|
||||
$dotenv->safeLoad();
|
||||
|
||||
$dsn = sprintf(
|
||||
'mysql:host=%s;port=%s;dbname=%s;charset=%s',
|
||||
$_ENV['DB_HOST'] ?? '127.0.0.1',
|
||||
$_ENV['DB_PORT'] ?? '3306',
|
||||
$_ENV['DB_DATABASE'] ?? '',
|
||||
$_ENV['DB_CHARSET'] ?? 'utf8mb4'
|
||||
);
|
||||
|
||||
$pdo = new PDO(
|
||||
$dsn,
|
||||
$_ENV['DB_USERNAME'] ?? '',
|
||||
$_ENV['DB_PASSWORD'] ?? '',
|
||||
[
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||
]
|
||||
);
|
||||
|
||||
function normalize_list(mixed $value): array
|
||||
{
|
||||
if (!is_array($value)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$items = [];
|
||||
foreach ($value as $item) {
|
||||
$text = trim((string)$item);
|
||||
if ($text !== '') {
|
||||
$items[] = $text;
|
||||
}
|
||||
}
|
||||
|
||||
return array_values(array_unique($items));
|
||||
}
|
||||
|
||||
function decode_json_list(mixed $value): array
|
||||
{
|
||||
if (is_array($value)) {
|
||||
return normalize_list($value);
|
||||
}
|
||||
if (!is_string($value) || trim($value) === '') {
|
||||
return [];
|
||||
}
|
||||
|
||||
$decoded = json_decode($value, true);
|
||||
return normalize_list(is_array($decoded) ? $decoded : []);
|
||||
}
|
||||
|
||||
function stable_json_list(array $value): string
|
||||
{
|
||||
$items = normalize_list($value);
|
||||
sort($items, SORT_STRING);
|
||||
return json_encode($items, JSON_UNESCAPED_UNICODE);
|
||||
}
|
||||
|
||||
function load_enabled_categories(PDO $pdo): array
|
||||
{
|
||||
$rows = $pdo->query(
|
||||
"SELECT id, name, code, supported_service_types
|
||||
FROM catalog_categories
|
||||
WHERE is_enabled = 1
|
||||
ORDER BY sort_order ASC, id ASC"
|
||||
)->fetchAll();
|
||||
|
||||
$byCode = [];
|
||||
$byName = [];
|
||||
$byId = [];
|
||||
foreach ($rows as $row) {
|
||||
$category = [
|
||||
'id' => (int)$row['id'],
|
||||
'name' => (string)$row['name'],
|
||||
'code' => (string)$row['code'],
|
||||
'supported_service_types' => decode_json_list($row['supported_service_types'] ?? null),
|
||||
];
|
||||
$byId[$category['id']] = $category;
|
||||
$byCode[strtolower($category['code'])] = $category;
|
||||
$byName[$category['name']] = $category;
|
||||
}
|
||||
|
||||
return [$byCode, $byName, $byId];
|
||||
}
|
||||
|
||||
function match_categories(array $brand, array $categoriesByCode, array $categoriesByName): array
|
||||
{
|
||||
$matched = [];
|
||||
|
||||
foreach (normalize_list($brand['category_codes'] ?? []) as $code) {
|
||||
$key = strtolower($code);
|
||||
if (isset($categoriesByCode[$key])) {
|
||||
$matched[$categoriesByCode[$key]['id']] = $categoriesByCode[$key];
|
||||
}
|
||||
}
|
||||
|
||||
foreach (normalize_list($brand['category_names'] ?? []) as $name) {
|
||||
if (isset($categoriesByName[$name])) {
|
||||
$matched[$categoriesByName[$name]['id']] = $categoriesByName[$name];
|
||||
}
|
||||
}
|
||||
|
||||
return $matched;
|
||||
}
|
||||
|
||||
function infer_supported_service_types(array $categories): array
|
||||
{
|
||||
$serviceTypes = [];
|
||||
foreach ($categories as $category) {
|
||||
foreach ($category['supported_service_types'] as $serviceType) {
|
||||
$serviceTypes[$serviceType] = $serviceType;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$serviceTypes) {
|
||||
$serviceTypes['anxinyan'] = 'anxinyan';
|
||||
}
|
||||
|
||||
return array_values($serviceTypes);
|
||||
}
|
||||
|
||||
function find_existing_brand(PDO $pdo, string $code): ?array
|
||||
{
|
||||
$stmt = $pdo->prepare('SELECT * FROM catalog_brands WHERE code = ? LIMIT 1');
|
||||
$stmt->execute([$code]);
|
||||
$row = $stmt->fetch();
|
||||
if ($row) {
|
||||
return $row;
|
||||
}
|
||||
|
||||
foreach (LEGACY_CODE_ALIASES[$code] ?? [] as $legacyCode) {
|
||||
$stmt->execute([$legacyCode]);
|
||||
$legacy = $stmt->fetch();
|
||||
if ($legacy) {
|
||||
return $legacy;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function existing_relation_ids(PDO $pdo, int $brandId): array
|
||||
{
|
||||
$stmt = $pdo->prepare('SELECT category_id FROM catalog_brand_categories WHERE brand_id = ?');
|
||||
$stmt->execute([$brandId]);
|
||||
|
||||
$ids = [];
|
||||
foreach ($stmt->fetchAll() as $row) {
|
||||
$ids[(int)$row['category_id']] = true;
|
||||
}
|
||||
|
||||
return $ids;
|
||||
}
|
||||
|
||||
[$categoriesByCode, $categoriesByName, $categoriesById] = load_enabled_categories($pdo);
|
||||
|
||||
$stats = [
|
||||
'brands_total' => count($brands),
|
||||
'inserted' => 0,
|
||||
'updated' => 0,
|
||||
'enabled_existing' => 0,
|
||||
'legacy_code_repaired' => 0,
|
||||
'relations_inserted' => 0,
|
||||
'skipped_no_enabled_category' => 0,
|
||||
'skipped_invalid' => 0,
|
||||
];
|
||||
|
||||
$now = date('Y-m-d H:i:s');
|
||||
|
||||
$insertBrand = $pdo->prepare(
|
||||
'INSERT INTO catalog_brands (name, en_name, code, logo, sort_order, is_enabled, supported_service_types, created_at, updated_at)
|
||||
VALUES (?, ?, ?, ?, ?, 1, ?, ?, ?)'
|
||||
);
|
||||
$updateBrand = $pdo->prepare(
|
||||
'UPDATE catalog_brands
|
||||
SET name = ?, en_name = ?, code = ?, sort_order = ?, is_enabled = 1, supported_service_types = ?, updated_at = ?
|
||||
WHERE id = ?'
|
||||
);
|
||||
$insertRelation = $pdo->prepare(
|
||||
'INSERT INTO catalog_brand_categories (brand_id, category_id, created_at)
|
||||
VALUES (?, ?, ?)'
|
||||
);
|
||||
|
||||
if (!$dryRun) {
|
||||
$pdo->beginTransaction();
|
||||
}
|
||||
|
||||
try {
|
||||
foreach ($brands as $brand) {
|
||||
$code = trim((string)($brand['code'] ?? ''));
|
||||
$name = trim((string)($brand['name'] ?? ''));
|
||||
$enName = trim((string)($brand['en_name'] ?? ''));
|
||||
if ($code === '' || $name === '' || $enName === '') {
|
||||
$stats['skipped_invalid']++;
|
||||
continue;
|
||||
}
|
||||
|
||||
$matchedCategories = match_categories($brand, $categoriesByCode, $categoriesByName);
|
||||
if (!$matchedCategories) {
|
||||
$stats['skipped_no_enabled_category']++;
|
||||
continue;
|
||||
}
|
||||
|
||||
$serviceTypes = infer_supported_service_types($matchedCategories);
|
||||
$serviceTypesJson = stable_json_list($serviceTypes);
|
||||
$sortOrder = (int)($brand['sort_order'] ?? 0);
|
||||
$existing = find_existing_brand($pdo, $code);
|
||||
|
||||
if ($existing) {
|
||||
$brandId = (int)$existing['id'];
|
||||
$wasDisabled = (int)$existing['is_enabled'] !== 1;
|
||||
$wasLegacyCode = (string)$existing['code'] !== $code;
|
||||
|
||||
$existingJson = stable_json_list(decode_json_list($existing['supported_service_types'] ?? null));
|
||||
$needsUpdate = $wasDisabled
|
||||
|| $wasLegacyCode
|
||||
|| (string)$existing['name'] !== $name
|
||||
|| (string)$existing['en_name'] !== $enName
|
||||
|| (int)$existing['sort_order'] !== $sortOrder
|
||||
|| $existingJson !== $serviceTypesJson;
|
||||
|
||||
if ($needsUpdate) {
|
||||
$stats['updated']++;
|
||||
if ($wasDisabled) {
|
||||
$stats['enabled_existing']++;
|
||||
}
|
||||
if ($wasLegacyCode) {
|
||||
$stats['legacy_code_repaired']++;
|
||||
}
|
||||
if (!$dryRun) {
|
||||
$updateBrand->execute([$name, $enName, $code, $sortOrder, $serviceTypesJson, $now, $brandId]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$stats['inserted']++;
|
||||
if ($dryRun) {
|
||||
$brandId = 0;
|
||||
} else {
|
||||
$insertBrand->execute([$name, $enName, $code, '', $sortOrder, $serviceTypesJson, $now, $now]);
|
||||
$brandId = (int)$pdo->lastInsertId();
|
||||
}
|
||||
}
|
||||
|
||||
$existingCategoryIds = $brandId > 0 ? existing_relation_ids($pdo, $brandId) : [];
|
||||
foreach (array_keys($matchedCategories) as $categoryId) {
|
||||
if (isset($existingCategoryIds[(int)$categoryId])) {
|
||||
continue;
|
||||
}
|
||||
$stats['relations_inserted']++;
|
||||
if (!$dryRun && $brandId > 0) {
|
||||
$insertRelation->execute([$brandId, (int)$categoryId, $now]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$dryRun) {
|
||||
$pdo->commit();
|
||||
}
|
||||
} catch (Throwable $e) {
|
||||
if (!$dryRun && $pdo->inTransaction()) {
|
||||
$pdo->rollBack();
|
||||
}
|
||||
fwrite(STDERR, "IMPORT_KNOWN_BRANDS_FAILED\n");
|
||||
fwrite(STDERR, $e->getMessage() . PHP_EOL);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
echo $dryRun ? "DRY_RUN\n" : "IMPORT_KNOWN_BRANDS_OK\n";
|
||||
echo "ENABLED_CATEGORIES=" . count($categoriesById) . PHP_EOL;
|
||||
foreach ($stats as $key => $value) {
|
||||
echo strtoupper($key) . '=' . $value . PHP_EOL;
|
||||
}
|
||||
Reference in New Issue
Block a user