Spis treści:
W tym artykule opiszę szczegółowo mechanizm działania trzech skryptów PHP, które współpracują ze sobą, aby umożliwić przesyłanie pliku z danymi zamówień i przesyłek, przetwarzanie tych danych oraz weryfikację i aktualizację numerów przesyłek za pomocą API Baselinker. Skrypty te to dane.php, przygotuj.php oraz numery_nadan_bl.php. Dzięki wykorzystaniu API Baselinker, proces weryfikacji i aktualizacji numerów przesyłek jest zautomatyzowany, co oszczędza czas i minimalizuje ryzyko błędów.
Przygotowanie pliku wejściowego dane.txt
- Plik nie może przekroczyć 50 KB, jeżeli chcesz móc wgrać plik o większym rozmiarze, trzeba zmienić fragment kodu w pliku 'przygotuj.php’ w miejscu
if ($_FILES['plikDanych']['size'] > 50000). Jeśli tak się stanie, to skrypt zostanie zatrzymany i wyświetli się komunikat informujący, że plik jest zbyt duży. Jest to jedna z prostszych form walidacji pliku, mająca na celu ochronę serwera przed przesyłaniem zbyt dużych plików. - Numery telefonów mogą być z prefiksem +48 lub bez.
- Dane szczegółów zamówień według formatu: ’Numer zamówienia;Imię i Nazwisko;E-mail;Telefon;Numer paczkomatu’.
- W tym celu stworzyłem eksport danych (Baselinker->Zamówienia->Wydruki i eksporty).
- Dane z wygenerowanych etykiet według formatu: ’Numer przesyłki;Numer telefonu;Data utworzenia’.
- Te dane otrzymuję od osoby, która generuje etykiety.
- W pliku dane.txt nie trzeba podawać nagłówków z 3 i 4 punktu. Nie ma różnicy czy będą czy nie. Skrypt poradzi sobie i tak z obróbką danych do formatu: 'Numer przesyłki;Numer zamówienia’.
- Nie trzeba ręcznie czyścić zawartości pliku po każdym uruchomieniu skryptu, gdyż jest to robione automatycznie.
- Jeżeli w danych znajdzie się zamówienie w Baselinker, które posiada już dodany numer przesyłki, to przy automatycznym dodawaniu numerów zostanie pominięte.
Wyjaśnienie działania skryptu dane.php
Skrypt HTML/PHP generuje formularz umożliwiający użytkownikowi przesłanie pliku dane.txtna serwer. Formularz zawiera zabezpieczenie przed atakami CSRF (Cross-Site Request Forgery) poprzez wygenerowanie i weryfikację tokena CSRF. Token jest generowany, jeśli nie istnieje już w sesji, i jest dodawany jako ukryte pole formularza. Dzięki temu można zweryfikować, czy formularz został przesłany przez uprawnionego użytkownika.
<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="UTF-8">
<title>Przygotuj plik z danymi</title>
</head>
<body>
<?php
session_start();
if (empty($_SESSION['csrf_token'])) {
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
?>
<form action="przygotuj.php" method="post" enctype="multipart/form-data">
<label>Wybierz plik z danymi:</label>
<input type="file" name="plikDanych" required>
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>">
<input type="submit" value="Prześlij">
</form>
</body>
</html>
Wyjaśnienie działania skryptu przygotuj.php
Skrypt PHP służy do przetwarzania przesłanego pliku tekstowego, który zawiera dane zamówień i przesyłek. Skrypt sprawdza poprawność tokena CSRF, waliduje rozmiar i typ pliku, a następnie przetwarza zawartość pliku, łącząc dane zamówień z przesyłkami na podstawie numerów telefonów. Wyniki są zapisywane do pliku dane.txt i wyświetlane na stronie. Dodatkowo skrypt generuje formularz do dalszego przetwarzania przesyłek.
Dane po przetworzeniu powinny być według formatu: ’Numer przesyłki;Numer zamówienia’.
<?php
session_start();
if (!isset($_POST['csrf_token']) || $_POST['csrf_token'] !== $_SESSION['csrf_token']) {
die("Nieprawidłowy token CSRF.");
}
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['plikDanych'])) {
if ($_FILES['plikDanych']['error'] === UPLOAD_ERR_OK) {
if ($_FILES['plikDanych']['size'] > 50000) {
die("Plik jest zbyt duży. Maksymalny dopuszczalny rozmiar to 50 KB.");
}
$finfo = new finfo(FILEINFO_MIME_TYPE);
$mime = $finfo->file($_FILES['plikDanych']['tmp_name']);
if ($mime != 'text/plain') {
die("Nieprawidłowy typ pliku. Oczekiwano pliku tekstowego.");
}
$content = file_get_contents($_FILES['plikDanych']['tmp_name']);
$lines = explode("\n", $content);
$orders = $shipments = $results = [];
$results[] = "Numer przesyłki;Numer zamówienia";
foreach ($lines as $line) {
if (strpos($line, ';') === false) continue;
list($firstElement) = explode(";", $line);
if (is_numeric($firstElement)) {
if (strpos($line, '@') !== false) {
list($orderNumber, , , $phone, , ) = explode(";", $line);
$phone = htmlspecialchars(str_replace('+48', '', $phone), ENT_QUOTES, 'UTF-8');
$orders[$phone] = htmlspecialchars($orderNumber, ENT_QUOTES, 'UTF-8');
} else {
list($shipmentNumber, $phone) = explode(";", $line);
$phone = htmlspecialchars(str_replace('+48', '', $phone), ENT_QUOTES, 'UTF-8');
$shipments[$phone] = htmlspecialchars($shipmentNumber, ENT_QUOTES, 'UTF-8');
}
}
}
foreach ($shipments as $phone => $shipmentNumber) {
if (isset($orders[$phone])) {
$results[] = "$shipmentNumber;{$orders[$phone]}";
}
}
file_put_contents('dane.txt', implode("\n", $results));
echo "<pre>" . htmlspecialchars(implode("\n", $results), ENT_QUOTES, 'UTF-8') . "</pre>";
} else {
echo "Wystąpił błąd podczas przesyłania pliku.";
}
// Formularz do wywołania numery_nadan_bl.php
echo '<form action="numery_nadan_bl.php" method="post">
<input type="hidden" name="csrf_token" value="'.$_SESSION['csrf_token'].'">
<input type="submit" value="Dodaj numery nadań">
</form>';
} else {
echo "Nieprawidłowe żądanie.";
}
?>
Wyjaśnienie działania skryptu numery_nadan_bl.php
Skrypt przetwarza plik dane.txt, sprawdzając każdą parę „Numer przesyłki;Numer zamówienia”. Dla każdego zamówienia weryfikuje, czy zamówienie już posiada numer przesyłki, korzystając z API Baselinker. Jeśli zamówienie nie ma przypisanego numeru przesyłki, skrypt dodaje numer przesyłki do zamówienia poprzez wywołanie odpowiedniego API. Po przetworzeniu wszystkich wierszy, skrypt usuwa zawartość pliku dane.txt, pozostawiając jedynie nagłówek, i wyświetla komunikat informujący o liczbie dodanych numerów przesyłek.
<?php
session_start();
// Sprawdzenie tokena CSRF
if (!isset($_POST['csrf_token']) || $_POST['csrf_token'] !== $_SESSION['csrf_token']) {
die("Nieprawidłowy token CSRF.");
}
// Otworzenie pliku dane.txt w trybie do odczytu (r)
$file = fopen("dane.txt", "r");
// Przygotowanie zmiennej na zawartość pliku bez pierwszego wiersza
$newFileContent = "Numer przesyłki;Numer zamówienia\n";
// Pomijanie pierwszego wiersza z nagłówkami
fgets($file);
// Inicjalizacja cURL
$curl = curl_init("https://api.baselinker.com/connector.php");
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_HTTPHEADER, ["X-BLToken: xxx"]); // Tutaj dodaj swój token
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$addedNumbersCount = 0;
// Przetwarzanie kolejnych wierszy
while (($row = fgetcsv($file, 0, ";")) !== false) {
// Zapisanie danych przesyłki i zamówienia do odpowiednich zmiennych
$package_number = htmlspecialchars($row[0], ENT_QUOTES, 'UTF-8');
$order_id = htmlspecialchars($row[1], ENT_QUOTES, 'UTF-8');
// Sprawdzenie, czy zamówienie posiada już numer przesyłki
$checkParams = json_encode(["order_id" => intval($order_id)]);
$apiCheckParams = [
"method" => "getOrderPackages",
"parameters" => $checkParams
];
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($apiCheckParams));
$checkResponse = curl_exec($curl);
$checkData = json_decode($checkResponse, true);
// Przygotowanie parametrów dla API
if (empty($checkData['packages'])) {
$methodParams = json_encode([
"order_id" => intval($order_id),
"courier_code" => "InPost Paczkomaty",
"package_number" => $package_number
]);
$apiParams = [
"method" => "createPackageManual",
"parameters" => $methodParams
];
// Wykonanie zapytania do API
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($apiParams));
$response = curl_exec($curl);
$addedNumbersCount++;
}
}
// Zamknięcie połączenia cURL
curl_close($curl);
// Ponowne otwarcie pliku dane.txt, ale tym razem w trybie do zapisu (w), co usunie wszystkie dane i zostawi tylko nagłówek
fclose($file); // Najpierw zamykamy plik, który był otwarty do odczytu
$file = fopen("dane.txt", "w"); // Otwieramy ten sam plik, ale do zapisu
fwrite($file, $newFileContent); // Zapisujemy tylko nagłówek do pliku, usuwając pozostałe dane
fclose($file); // Zamknięcie pliku
echo "Dodano numery nadań dla $addedNumbersCount zamówień.";
?>
Gotowe skrypty do pobrania
Zawartość folderu z plikami:
- dane.php
- dane.txt
- numery_nadan_bl.php
- przygotuj.php
Pobierz skrypty z numery_nadan_bl.7zip
![[Baselinker] Automatyzacja dodawania numerów przesyłek za pomocą API w PHP Programista piszący skrypty](https://pawelmacur.com/wp-content/uploads/2024/05/programista-768x773.jpg)