Skip to content

Commit c1a6ce1

Browse files
authored
Merge pull request #417 from Zasilkovna/PES-3084-bugfix-carrier-load-external-points
PES-3084: bugfix - carrier load external points
2 parents 7c72dc1 + c75bfd9 commit c1a6ce1

File tree

6 files changed

+135
-17
lines changed

6 files changed

+135
-17
lines changed

packetery/CHANGE_LOG.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11

2-
v3.4
2+
v3.4.0
3+
- Updated: If Packeta pick-up point list is not loaded correctly in administration Order detail, log error and do not display button for choose pick-up point/change address.
34
- Added: Information about the selected pickup point to emails for e-shop owner.
45
- Updated: Loading the widget javascript library only on the checkout page.
56
- Updated: Multiple issues form PrestaShop validator resolved.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
/**
3+
* @author Packeta s.r.o. <e-commerce.support@packeta.com>
4+
* @copyright 2015-2026 Packeta s.r.o.
5+
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
6+
*/
7+
8+
namespace Packetery\Exceptions;
9+
10+
if (!defined('_PS_VERSION_')) {
11+
exit;
12+
}
13+
14+
class EmptyArrayToJsonConvertException extends \Exception
15+
{
16+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
/**
3+
* @author Packeta s.r.o. <e-commerce.support@packeta.com>
4+
* @copyright 2015-2026 Packeta s.r.o.
5+
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
6+
*/
7+
8+
namespace Packetery\Exceptions;
9+
10+
if (!defined('_PS_VERSION_')) {
11+
exit;
12+
}
13+
14+
class FailedToConvertJsonException extends \Exception
15+
{
16+
}

packetery/libs/LogWrapper/PrestashopLogWrapper.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
class PrestashopLogWrapper
1515
{
1616
public const LEVEL_INFO = 1;
17+
public const LEVEL_WARNING = 2;
1718
public const LEVEL_ERROR = 3;
1819

1920
/**

packetery/libs/Module/Helper.php

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77

88
namespace Packetery\Module;
99

10+
use Packetery\Exceptions\EmptyArrayToJsonConvertException;
11+
use Packetery\Exceptions\FailedToConvertJsonException;
12+
1013
if (!defined('_PS_VERSION_')) {
1114
exit;
1215
}
@@ -48,4 +51,48 @@ public static function unserialize(
4851
]
4952
);
5053
}
54+
55+
/**
56+
* Transforms non-empty array to JSON string
57+
*
58+
* @param array<int|string, mixed> $data
59+
*
60+
* @return string
61+
*
62+
* @throws EmptyArrayToJsonConvertException
63+
* @throws FailedToConvertJsonException
64+
*/
65+
public static function transformArrayToJson(array $data): string
66+
{
67+
if ($data === []) {
68+
throw new EmptyArrayToJsonConvertException('Function transformArrayToJson got empty array.');
69+
}
70+
71+
$json = json_encode($data, JSON_UNESCAPED_UNICODE);
72+
if ($json === false) {
73+
throw new FailedToConvertJsonException(json_last_error_msg());
74+
}
75+
76+
return $json;
77+
}
78+
79+
/**
80+
* Recursively escapes all string values in common array
81+
* Non-string values (int, float, bool, null) are preserved.
82+
*
83+
* @param array<int|string, mixed> $array
84+
*
85+
* @return array<int|string, mixed>
86+
*/
87+
public static function escapeArray(array $array): array
88+
{
89+
$resultArray = $array;
90+
array_walk_recursive($resultArray, function (&$value) {
91+
if (is_string($value)) {
92+
$value = htmlspecialchars($value, ENT_QUOTES | ENT_HTML5);
93+
}
94+
});
95+
96+
return $resultArray;
97+
}
5198
}

packetery/packetery.php

Lines changed: 53 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ class Packetery extends CarrierModule
2626
public const LOCAL = 'local';
2727
public const REMOTE = 'remote';
2828

29+
private const PACKETA_SUPPORT_EMAIL = 'e-commerce.support@packeta.com';
30+
2931
protected $config_form = false;
3032

3133
/** @var Packetery\DI\Container */
@@ -986,6 +988,7 @@ public function packeteryHookDisplayAdminOrder($params)
986988
$apiKey = $configHelper->getApiKey();
987989

988990
$pickupPointChangeAllowed = false;
991+
$widgetOptions = null;
989992
if ($apiKey !== false && (bool) $packeteryCarrier === true) {
990993
if ($isAddressDelivery === true) {
991994
$isAddressValidated = false;
@@ -1019,15 +1022,21 @@ public function packeteryHookDisplayAdminOrder($params)
10191022
$isAddressValidated = true;
10201023
}
10211024
$this->context->smarty->assign('validatedAddress', $validatedAddress);
1022-
$this->prepareAddressChange($apiKey, $packeteryOrder);
1025+
$widgetOptions = $this->prepareAddressChange($apiKey, $packeteryOrder, $orderId);
10231026
}
1027+
10241028
$this->context->smarty->assign('isAddressValidated', $isAddressValidated);
10251029
} elseif ((int) $packeteryOrder['id_carrier'] !== 0) {
1026-
$this->preparePickupPointChange($apiKey, $packeteryOrder, $orderId, $packeteryCarrier);
10271030
$pickupPointChangeAllowed = true;
1031+
$widgetOptions = $this->preparePickupPointChange($apiKey, $packeteryOrder, $orderId, $packeteryCarrier);
1032+
if ($widgetOptions === null) {
1033+
$pickupPointChangeAllowed = false;
1034+
}
10281035
}
10291036
}
10301037

1038+
$this->context->smarty->assign('widgetOptions', $widgetOptions);
1039+
10311040
/** @var Packetery\Weight\Calculator $weightCalculator */
10321041
$weightCalculator = $this->diContainer->get(Packetery\Weight\Calculator::class);
10331042
$orderWeight = $weightCalculator->getFinalWeight($packeteryOrder);
@@ -1105,16 +1114,15 @@ public function packeteryHookDisplayAdminOrder($params)
11051114
}
11061115

11071116
/**
1108-
* @param string $apiKey
1109-
* @param array $packeteryOrder
1117+
* @param array<string,string> $packeteryOrder
11101118
*
11111119
* @throws PrestaShopDatabaseException
11121120
* @throws PrestaShopException
11131121
*/
1114-
private function prepareAddressChange($apiKey, array $packeteryOrder)
1122+
private function prepareAddressChange(string $apiKey, array $packeteryOrder, int $orderId): ?string
11151123
{
11161124
if (!in_array($packeteryOrder['ps_country'], Packetery\Carrier\CarrierRepository::ADDRESS_VALIDATION_COUNTRIES, true)) {
1117-
return;
1125+
return null;
11181126
}
11191127

11201128
/** @var Packetery\Tools\ConfigHelper $configHelper */
@@ -1132,25 +1140,22 @@ private function prepareAddressChange($apiKey, array $packeteryOrder)
11321140
$widgetOptions['city'] = $packeteryOrder['city'];
11331141
$widgetOptions['zip'] = str_replace(' ', '', $packeteryOrder['zip']);
11341142
} else {
1135-
$order = new Order($packeteryOrder['id_order']);
1143+
$order = new Order($orderId);
11361144
$deliveryAddress = new Address($order->id_address_delivery);
11371145
$widgetOptions['houseNumber'] = '';
11381146
$widgetOptions['zip'] = str_replace(' ', '', $deliveryAddress->postcode);
11391147
$widgetOptions['city'] = $deliveryAddress->city;
11401148
$widgetOptions['street'] = $deliveryAddress->address1;
11411149
}
1142-
$this->context->smarty->assign('widgetOptions', json_encode($widgetOptions));
1150+
1151+
return $this->getValidWidgetOptions($widgetOptions, $orderId);
11431152
}
11441153

11451154
/**
1146-
* @param string $apiKey
1147-
* @param array $packeteryOrder
1148-
* @param int $orderId
1149-
* @param array $packeteryCarrier
1150-
*
1151-
* @throws PrestaShopException
1155+
* @param array<string,string> $packeteryOrder
1156+
* @param array<string,string> $packeteryCarrier
11521157
*/
1153-
private function preparePickupPointChange($apiKey, $packeteryOrder, $orderId, $packeteryCarrier)
1158+
private function preparePickupPointChange(string $apiKey, array $packeteryOrder, int $orderId, array $packeteryCarrier): ?string
11541159
{
11551160
/** @var Packetery\Tools\ConfigHelper $configHelper */
11561161
$configHelper = $this->diContainer->get(Packetery\Tools\ConfigHelper::class);
@@ -1163,6 +1168,7 @@ private function preparePickupPointChange($apiKey, $packeteryOrder, $orderId, $p
11631168
'lang' => $configHelper->getBackendLanguage($this),
11641169
'vendors' => $this->getAllowedVendorsForOrder($orderId, $country),
11651170
];
1171+
11661172
if (
11671173
$packeteryCarrier['pickup_point_type'] === 'external'
11681174
&& $packeteryOrder['id_branch'] !== null
@@ -1172,7 +1178,8 @@ private function preparePickupPointChange($apiKey, $packeteryOrder, $orderId, $p
11721178
} elseif ($packeteryCarrier['pickup_point_type'] === 'internal') {
11731179
$widgetOptions['carriers'] = Packetery\Carrier\CarrierVendors::INTERNAL_PICKUP_POINT_CARRIER;
11741180
}
1175-
$this->context->smarty->assign('widgetOptions', json_encode($widgetOptions));
1181+
1182+
return $this->getValidWidgetOptions($widgetOptions, $orderId);
11761183
}
11771184

11781185
/**
@@ -1717,4 +1724,34 @@ public function hookActionProductDelete(array $params): void
17171724
$productAttributeRepository = $this->diContainer->get(Packetery\Product\ProductAttributeRepository::class);
17181725
$productAttributeRepository->delete($params['product']->id);
17191726
}
1727+
1728+
/**
1729+
* Validates and encodes widget options to escaped JSON string
1730+
*
1731+
* @param array<string, string|int> $widgetOptions
1732+
*
1733+
* @return string|null Escaped JSON string or null on failure
1734+
*/
1735+
private function getValidWidgetOptions(array $widgetOptions, int $orderId): ?string
1736+
{
1737+
$logMessage = sprintf(
1738+
$this->l('Can not change delivery place in administration detail for order id %d, please copy this log to %s.'),
1739+
$orderId,
1740+
self::PACKETA_SUPPORT_EMAIL
1741+
);
1742+
$logMessage .= ' ';
1743+
1744+
try {
1745+
return htmlspecialchars(Packetery\Module\Helper::transformArrayToJson($widgetOptions), ENT_QUOTES);
1746+
} catch (Packetery\Exceptions\EmptyArrayToJsonConvertException $e) {
1747+
$logMessage .= $this->l($e->getMessage());
1748+
Packetery\LogWrapper\PrestashopLogWrapper::addLog($logMessage, Packetery\LogWrapper\PrestashopLogWrapper::LEVEL_WARNING);
1749+
} catch (Packetery\Exceptions\FailedToConvertJsonException $e) {
1750+
$logMessage .= $this->l('Function transformArrayToJson failed:') . ' ' . $e->getMessage() . ', ';
1751+
$logMessage .= $this->l('data:') . ' ' . print_r(Packetery\Module\Helper::escapeArray($widgetOptions), true);
1752+
Packetery\LogWrapper\PrestashopLogWrapper::addLog($logMessage, Packetery\LogWrapper\PrestashopLogWrapper::LEVEL_WARNING);
1753+
}
1754+
1755+
return null;
1756+
}
17201757
}

0 commit comments

Comments
 (0)