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.txt
na 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