232 lines
7.2 KiB
PHP
232 lines
7.2 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
/**
|
|
* GS1 API diagnostic
|
|
*
|
|
* Usage:
|
|
* php bin/test_gs1_api.php <login> <password> [gtin]
|
|
*
|
|
* If login/password are not provided, script tries to read them from DB app_settings.
|
|
*/
|
|
|
|
$login = $argv[1] ?? '';
|
|
$password = $argv[2] ?? '';
|
|
$targetGtin = $argv[3] ?? '5905323904514';
|
|
|
|
if ($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) {
|
|
// Ignore and use CLI args fallback.
|
|
}
|
|
}
|
|
|
|
if ($login === '' || $password === '') {
|
|
fwrite(STDERR, "Brak credentials. Uzyj: php bin/test_gs1_api.php <login> <password> [gtin]\n");
|
|
exit(1);
|
|
}
|
|
|
|
if (!preg_match('/^\d{13,14}$/', $targetGtin)) {
|
|
fwrite(STDERR, "Nieprawidlowy GTIN: {$targetGtin}. Oczekiwane 13 lub 14 cyfr.\n");
|
|
exit(1);
|
|
}
|
|
|
|
const GS1_BASE = 'https://mojegs1.pl/api/v2';
|
|
|
|
/**
|
|
* @return array{status:int, body:string, error:string}
|
|
*/
|
|
function gs1Request(
|
|
string $method,
|
|
string $url,
|
|
string $login,
|
|
string $password,
|
|
?string $rawBody = null,
|
|
string $contentType = 'application/json',
|
|
string $accept = 'application/json'
|
|
): array {
|
|
$curl = curl_init($url);
|
|
if ($curl === false) {
|
|
return ['status' => 0, 'body' => '', 'error' => 'Nie mozna zainicjalizowac cURL'];
|
|
}
|
|
|
|
$headers = ['Accept: ' . $accept];
|
|
if ($rawBody !== null) {
|
|
$headers[] = 'Content-Type: ' . $contentType;
|
|
}
|
|
|
|
curl_setopt_array($curl, [
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_HTTPHEADER => $headers,
|
|
CURLOPT_USERPWD => $login . ':' . $password,
|
|
CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
|
|
CURLOPT_TIMEOUT => 30,
|
|
CURLOPT_SSL_VERIFYPEER => true,
|
|
CURLOPT_SSL_VERIFYHOST => 2,
|
|
CURLOPT_CUSTOMREQUEST => $method,
|
|
]);
|
|
|
|
if ($rawBody !== null) {
|
|
curl_setopt($curl, CURLOPT_POSTFIELDS, $rawBody);
|
|
}
|
|
|
|
$body = curl_exec($curl);
|
|
$status = (int) curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
|
|
$error = curl_error($curl);
|
|
curl_close($curl);
|
|
|
|
return [
|
|
'status' => $status,
|
|
'body' => is_string($body) ? $body : '',
|
|
'error' => $error,
|
|
];
|
|
}
|
|
|
|
function toJson(mixed $value): string
|
|
{
|
|
$json = json_encode($value, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT);
|
|
return $json === false ? '[json_encode error]' : $json;
|
|
}
|
|
|
|
function printResponse(string $label, array $response): void
|
|
{
|
|
echo $label . PHP_EOL;
|
|
echo 'HTTP: ' . $response['status'] . PHP_EOL;
|
|
if ($response['error'] !== '') {
|
|
echo 'cURL error: ' . $response['error'] . PHP_EOL;
|
|
}
|
|
if ($response['body'] === '') {
|
|
echo "BODY: [empty]\n\n";
|
|
return;
|
|
}
|
|
|
|
$decoded = json_decode($response['body'], true);
|
|
if (is_array($decoded)) {
|
|
echo "BODY:\n" . toJson($decoded) . PHP_EOL;
|
|
if (!empty($decoded['errors'])) {
|
|
echo "ERRORS:\n" . toJson($decoded['errors']) . PHP_EOL;
|
|
}
|
|
} else {
|
|
echo "BODY:\n" . $response['body'] . PHP_EOL;
|
|
}
|
|
echo PHP_EOL;
|
|
}
|
|
|
|
function putProduct(string $gtin, array $attributes, string $login, string $password): array
|
|
{
|
|
$payload = [
|
|
'data' => [
|
|
'type' => 'products',
|
|
'id' => $gtin,
|
|
'attributes' => $attributes,
|
|
],
|
|
];
|
|
|
|
return gs1Request(
|
|
'PUT',
|
|
GS1_BASE . '/products/' . rawurlencode($gtin),
|
|
$login,
|
|
$password,
|
|
json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)
|
|
);
|
|
}
|
|
|
|
echo "=== GS1 Diagnostic v5 ===\n";
|
|
echo "Target GTIN: {$targetGtin}\n\n";
|
|
|
|
// 1) Check target GTIN
|
|
$targetGet = gs1Request('GET', GS1_BASE . '/products/' . rawurlencode($targetGtin), $login, $password);
|
|
printResponse('--- Step 1: GET target GTIN ---', $targetGet);
|
|
|
|
// 2) PUT with values aligned to external API swagger example (language as `pl`)
|
|
$attrsSwaggerLike = [
|
|
'brandName' => 'Test Marka',
|
|
'subBrandName' => 'Test Podmarka',
|
|
'commonName' => 'Test produkt',
|
|
'name' => 'Test produkt API',
|
|
'description' => 'Test opisu produktu',
|
|
'gpcCode' => 10000002,
|
|
'netContent' => 1.5,
|
|
'netContentUnit' => 'kg',
|
|
'status' => 'ACT',
|
|
'targetMarket' => ['PL'],
|
|
'descriptionLanguage' => 'pl',
|
|
];
|
|
$putTargetSwaggerLike = putProduct($targetGtin, $attrsSwaggerLike, $login, $password);
|
|
printResponse('--- Step 2: PUT target GTIN (swagger-like payload) ---', $putTargetSwaggerLike);
|
|
|
|
// 3) PUT with original app defaults (for direct comparison with old script behavior)
|
|
$attrsAppLike = [
|
|
'brandName' => 'marianek.pl',
|
|
'subBrandName' => 'marianek.pl',
|
|
'commonName' => 'Produkt testowy',
|
|
'name' => 'Produkt testowy API',
|
|
'gpcCode' => 10008365,
|
|
'netContent' => 1,
|
|
'netContentUnit' => 'szt',
|
|
'status' => 'ACT',
|
|
'targetMarket' => ['PL'],
|
|
'descriptionLanguage' => 'PL',
|
|
];
|
|
$putTargetAppLike = putProduct($targetGtin, $attrsAppLike, $login, $password);
|
|
printResponse('--- Step 3: PUT target GTIN (app-like payload) ---', $putTargetAppLike);
|
|
|
|
// 4) Permission check: read an existing product and try no-op PUT.
|
|
$list = gs1Request('GET', GS1_BASE . '/products?page[offset]=1&page[limit]=1&sort=name', $login, $password);
|
|
printResponse('--- Step 4a: GET list (first product) ---', $list);
|
|
|
|
$existingGtin = null;
|
|
$existingAttributes = null;
|
|
$listDecoded = json_decode($list['body'], true);
|
|
if (is_array($listDecoded) && isset($listDecoded['data'][0]['id'])) {
|
|
$existingGtin = (string) $listDecoded['data'][0]['id'];
|
|
$existingAttributes = $listDecoded['data'][0]['attributes'] ?? null;
|
|
}
|
|
|
|
if ($existingGtin !== null && is_array($existingAttributes)) {
|
|
$noOpPut = putProduct($existingGtin, $existingAttributes, $login, $password);
|
|
printResponse('--- Step 4b: PUT existing product with attributes from GET (no-op) ---', $noOpPut);
|
|
} else {
|
|
echo "--- Step 4b: skipped (no product data from list) ---\n\n";
|
|
}
|
|
|
|
echo "=== DONE ===\n";
|