191 lines
5.5 KiB
PHP
191 lines
5.5 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
/**
|
|
* Fix GS1 brandName for all products.
|
|
*
|
|
* Fetches all products from MojeGS1 API, finds those with wrong brandName,
|
|
* and updates them to the correct brand.
|
|
*
|
|
* Usage:
|
|
* php bin/fix_gs1_brand.php [correct_brand]
|
|
*
|
|
* Default correct brand: pomysloweprezenty.pl
|
|
*/
|
|
|
|
$correctBrand = $argv[1] ?? 'pomysloweprezenty.pl';
|
|
|
|
// --- Load credentials from .env + DB ---
|
|
$login = '';
|
|
$password = '';
|
|
|
|
$envFile = dirname(__DIR__) . '/.env';
|
|
$env = [];
|
|
if (is_file($envFile)) {
|
|
foreach (file($envFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) as $line) {
|
|
$line = trim($line);
|
|
if ($line === '' || $line[0] === '#') {
|
|
continue;
|
|
}
|
|
$pos = strpos($line, '=');
|
|
if ($pos === false) {
|
|
continue;
|
|
}
|
|
$env[trim(substr($line, 0, $pos))] = trim(trim(substr($line, $pos + 1)), "\"'");
|
|
}
|
|
}
|
|
|
|
try {
|
|
$pdo = new PDO(
|
|
sprintf(
|
|
'mysql:host=%s;port=%s;dbname=%s;charset=utf8mb4',
|
|
$env['DB_HOST'] ?? '127.0.0.1',
|
|
$env['DB_PORT'] ?? '3306',
|
|
$env['DB_DATABASE'] ?? 'orderpro'
|
|
),
|
|
$env['DB_USERNAME'] ?? 'root',
|
|
$env['DB_PASSWORD'] ?? '',
|
|
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
|
|
);
|
|
|
|
$stmt = $pdo->prepare('SELECT setting_key, setting_value FROM app_settings WHERE setting_key IN (?, ?)');
|
|
$stmt->execute(['gs1_api_login', 'gs1_api_password']);
|
|
foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
|
|
if ($row['setting_key'] === 'gs1_api_login') {
|
|
$login = (string) $row['setting_value'];
|
|
}
|
|
if ($row['setting_key'] === 'gs1_api_password') {
|
|
$password = (string) $row['setting_value'];
|
|
}
|
|
}
|
|
} catch (Throwable $e) {
|
|
fwrite(STDERR, "Blad DB: " . $e->getMessage() . "\n");
|
|
}
|
|
|
|
if ($login === '' || $password === '') {
|
|
fwrite(STDERR, "Brak credentials GS1. Sprawdz ustawienia w bazie.\n");
|
|
exit(1);
|
|
}
|
|
|
|
echo "Correct brand: {$correctBrand}\n";
|
|
echo "Pobieram produkty z GS1...\n\n";
|
|
|
|
// --- Fetch all products ---
|
|
$allProducts = [];
|
|
$page = 1;
|
|
$limit = 100;
|
|
|
|
do {
|
|
$url = "https://mojegs1.pl/api/v2/products?page[offset]={$page}&page[limit]={$limit}&sort=name";
|
|
$response = gs1Request('GET', $url, $login, $password);
|
|
|
|
if ($response['status'] < 200 || $response['status'] >= 300) {
|
|
fwrite(STDERR, "Blad pobierania listy (HTTP {$response['status']}): {$response['body']}\n");
|
|
exit(1);
|
|
}
|
|
|
|
$decoded = json_decode($response['body'], true);
|
|
$items = is_array($decoded['data'] ?? null) ? $decoded['data'] : [];
|
|
$total = (int) ($decoded['meta']['record-count'] ?? 0);
|
|
|
|
foreach ($items as $item) {
|
|
$allProducts[] = $item;
|
|
}
|
|
|
|
echo " Strona {$page}: pobrano " . count($items) . " produktow (lacznie: " . count($allProducts) . " / {$total})\n";
|
|
$page++;
|
|
} while (count($items) >= $limit);
|
|
|
|
echo "\nLacznie pobrano: " . count($allProducts) . " produktow\n\n";
|
|
|
|
// --- Find and fix products with wrong brand ---
|
|
$updated = 0;
|
|
$skipped = 0;
|
|
$errors = 0;
|
|
|
|
foreach ($allProducts as $item) {
|
|
$gtin = (string) ($item['id'] ?? '');
|
|
$attrs = is_array($item['attributes'] ?? null) ? $item['attributes'] : [];
|
|
$currentBrand = (string) ($attrs['brandName'] ?? '');
|
|
|
|
if ($gtin === '') {
|
|
continue;
|
|
}
|
|
|
|
if ($currentBrand === $correctBrand) {
|
|
$skipped++;
|
|
continue;
|
|
}
|
|
|
|
echo " [{$gtin}] brandName: \"{$currentBrand}\" -> \"{$correctBrand}\"";
|
|
|
|
$putUrl = "https://mojegs1.pl/api/v2/products/" . urlencode($gtin);
|
|
$payload = json_encode([
|
|
'data' => [
|
|
'type' => 'products',
|
|
'id' => $gtin,
|
|
'attributes' => [
|
|
'brandName' => $correctBrand,
|
|
],
|
|
],
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
|
|
|
$putResponse = gs1Request('PUT', $putUrl, $login, $password, $payload);
|
|
|
|
if ($putResponse['status'] >= 200 && $putResponse['status'] < 300) {
|
|
echo " OK\n";
|
|
$updated++;
|
|
} else {
|
|
echo " BLAD (HTTP {$putResponse['status']}): " . mb_substr($putResponse['body'], 0, 200) . "\n";
|
|
$errors++;
|
|
}
|
|
}
|
|
|
|
echo "\n--- Podsumowanie ---\n";
|
|
echo "Zaktualizowano: {$updated}\n";
|
|
echo "Pominieto (juz OK): {$skipped}\n";
|
|
echo "Bledy: {$errors}\n";
|
|
|
|
// --- HTTP helper ---
|
|
function gs1Request(string $method, string $url, string $login, string $password, ?string $body = null): array
|
|
{
|
|
$curl = curl_init($url);
|
|
if ($curl === false) {
|
|
return ['status' => 0, 'body' => 'cURL init failed', 'error' => 'init'];
|
|
}
|
|
|
|
$headers = ['Accept: application/json'];
|
|
if ($body !== null) {
|
|
$headers[] = 'Content-Type: application/json';
|
|
}
|
|
|
|
curl_setopt_array($curl, [
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_HTTPHEADER => $headers,
|
|
CURLOPT_USERPWD => $login . ':' . $password,
|
|
CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
|
|
CURLOPT_TIMEOUT => 30,
|
|
CURLOPT_CONNECTTIMEOUT => 10,
|
|
CURLOPT_SSL_VERIFYPEER => true,
|
|
CURLOPT_SSL_VERIFYHOST => 2,
|
|
CURLOPT_FOLLOWLOCATION => true,
|
|
CURLOPT_MAXREDIRS => 5,
|
|
CURLOPT_CUSTOMREQUEST => $method,
|
|
]);
|
|
|
|
if ($body !== null) {
|
|
curl_setopt($curl, CURLOPT_POSTFIELDS, $body);
|
|
}
|
|
|
|
$responseBody = curl_exec($curl);
|
|
$httpCode = (int) curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
|
|
$error = curl_error($curl);
|
|
curl_close($curl);
|
|
|
|
return [
|
|
'status' => $httpCode,
|
|
'body' => is_string($responseBody) ? $responseBody : '',
|
|
'error' => $error,
|
|
];
|
|
}
|