PluginProbe
Packeta / trunk
Packeta vtrunk
2.3.2 2.3.1 trunk 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.3.0 1.3.1 1.3.2 1.4 1.4.1 1.4.2 1.4.3 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 All 56 releases
packeta / src / Packetery / Module / Order / GridExtender.php

GridExtender.php in Packeta trunk, at src/Packetery/Module/Order/GridExtender.php

534 lines 17.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Class GridExtender.
4 *
5 * @package Packetery\Order
6 */
7
8 declare( strict_types=1 );
9
10 namespace Packetery\Module\Order;
11
12 use Packetery\Core;
13 use Packetery\Core\CoreHelper;
14 use Packetery\Latte\Engine;
15 use Packetery\Module\Carrier\CarrierOptionsFactory;
16 use Packetery\Module\ContextResolver;
17 use Packetery\Module\EntityFactory\SizeFactory;
18 use Packetery\Module\Exception\InvalidCarrierException;
19 use Packetery\Module\Framework\WpAdapter;
20 use Packetery\Module\Log\Purger;
21 use Packetery\Module\ModuleHelper;
22 use Packetery\Module\Plugin;
23 use Packetery\Module\WcLogger;
24 use Packetery\Nette\Http\Request;
25 use WC_Order;
26
27 use function esc_html;
28
29 /**
30 * Class GridExtender.
31 *
32 * @package Packetery\Order
33 */
34 class GridExtender {
35
36 private const TEMPLATE_GRID_COLUMN_WEIGHT = PACKETERY_PLUGIN_DIR . '/template/order/grid-column-weight.latte';
37
38 /**
39 * Generic CoreHelper.
40 *
41 * @var CoreHelper
42 */
43 private $coreHelper;
44
45 /**
46 * Latte Engine.
47 *
48 * @var Engine
49 */
50 private $latteEngine;
51
52 /**
53 * Http Request.
54 *
55 * @var Request
56 */
57 private $httpRequest;
58
59 /**
60 * Order repository.
61 *
62 * @var Repository
63 */
64 private $orderRepository;
65
66 /**
67 * Order Validator.
68 *
69 * @var Core\Validator\Order
70 */
71 private $orderValidator;
72
73 /**
74 * Context resolver.
75 *
76 * @var ContextResolver
77 */
78 private $contextResolver;
79
80 /**
81 * Carrier options factory.
82 *
83 * @var CarrierOptionsFactory
84 */
85 private $carrierOptionsFactory;
86
87 /**
88 * WordPress Adapter.
89 *
90 * @var WpAdapter
91 */
92 private $wpAdapter;
93
94 /**
95 * Module helper
96 *
97 * @var ModuleHelper
98 */
99 private $moduleHelper;
100
101 /**
102 * @var SizeFactory
103 */
104 private $sizeFactory;
105
106 /**
107 * @var PacketStatusResolver
108 */
109 private $packetStatusResolver;
110
111 /**
112 * @var Form
113 */
114 private $orderForm;
115
116 /**
117 * GridExtender constructor.
118 *
119 * @param CoreHelper $coreHelper CoreHelper.
120 * @param Engine $latteEngine Latte Engine.
121 * @param Request $httpRequest Http Request.
122 * @param Repository $orderRepository Order repository.
123 * @param OrderValidatorFactory $orderValidatorFactory Order validator.
124 * @param ContextResolver $contextResolver Context resolver.
125 * @param CarrierOptionsFactory $carrierOptionsFactory Carrier options factory.
126 * @param WpAdapter $wpAdapter WordPress adapter.
127 * @param ModuleHelper $moduleHelper Module helper.
128 * @param SizeFactory $sizeFactory Size factory.
129 * @param PacketStatusResolver $packetStatusResolver Packet status resolver.
130 */
131 public function __construct(
132 CoreHelper $coreHelper,
133 Engine $latteEngine,
134 Request $httpRequest,
135 Repository $orderRepository,
136 OrderValidatorFactory $orderValidatorFactory,
137 ContextResolver $contextResolver,
138 CarrierOptionsFactory $carrierOptionsFactory,
139 WpAdapter $wpAdapter,
140 ModuleHelper $moduleHelper,
141 SizeFactory $sizeFactory,
142 PacketStatusResolver $packetStatusResolver,
143 Form $orderForm
144 ) {
145 $this->coreHelper = $coreHelper;
146 $this->latteEngine = $latteEngine;
147 $this->httpRequest = $httpRequest;
148 $this->orderRepository = $orderRepository;
149 $this->orderValidator = $orderValidatorFactory->create();
150 $this->contextResolver = $contextResolver;
151 $this->carrierOptionsFactory = $carrierOptionsFactory;
152 $this->wpAdapter = $wpAdapter;
153 $this->moduleHelper = $moduleHelper;
154 $this->sizeFactory = $sizeFactory;
155 $this->packetStatusResolver = $packetStatusResolver;
156 $this->orderForm = $orderForm;
157 }
158
159 /**
160 * Adds custom filtering links to order grid.
161 *
162 * @param string[]|mixed $htmlLinks Array of html links.
163 *
164 * @return string[]|mixed
165 */
166 public function addFilterLinks( $htmlLinks ) {
167 if ( ! is_array( $htmlLinks ) ) {
168 WcLogger::logArgumentTypeError( __METHOD__, 'htmlLinks', 'array', $htmlLinks );
169
170 return $htmlLinks;
171 }
172 $linkConfig = new GridLinksConfig(
173 $this->wpAdapter->__( 'Packeta orders to submit', 'packeta' ),
174 $this->wpAdapter->__( 'Packeta orders to print', 'packeta' ),
175 $this->wpAdapter->__( 'Run Packeta wizard', 'packeta' )
176 );
177 $originalLinkConfig = clone $linkConfig;
178 $linkConfig = $this->wpAdapter->applyFilters( 'packeta_order_grid_links_settings', $linkConfig );
179 if ( ! $linkConfig instanceof GridLinksConfig ) {
180 $linkConfig = $originalLinkConfig;
181 }
182
183 if ( $linkConfig->isFilterOrdersToSubmitEnabled() === true ) {
184 $latteParams = [
185 'link' => ModuleHelper::getOrderGridUrl(
186 [
187 'filter_action' => 'packetery_filter_link',
188 'packetery_to_submit' => '1',
189 'packetery_to_print' => false,
190 ]
191 ),
192 'title' => $linkConfig->getFilterOrdersToSubmitTitle(),
193 'orderCount' => $this->orderRepository->countOrdersToSubmit(),
194 'active' => ( $this->httpRequest->getQuery( 'packetery_to_submit' ) === '1' ),
195 ];
196 $htmlLinks['js-wizard-packetery-filter-orders-to-submit'] = $this->latteEngine->renderToString(
197 PACKETERY_PLUGIN_DIR . '/template/order/filter-link.latte',
198 $latteParams
199 );
200 }
201
202 if ( $linkConfig->isFilterOrdersToPrintEnabled() === true ) {
203 $latteParams = [
204 'link' => ModuleHelper::getOrderGridUrl(
205 [
206 'filter_action' => 'packetery_filter_link',
207 'packetery_to_submit' => false,
208 'packetery_to_print' => '1',
209 ]
210 ),
211 'title' => $linkConfig->getFilterOrdersToPrintTitle(),
212 'orderCount' => $this->orderRepository->countOrdersToPrint(),
213 'active' => ( $this->httpRequest->getQuery( 'packetery_to_print' ) === '1' ),
214 ];
215 $htmlLinks['js-wizard-packetery-filter-orders-to-print'] = $this->latteEngine->renderToString(
216 PACKETERY_PLUGIN_DIR . '/template/order/filter-link.latte',
217 $latteParams
218 );
219 }
220
221 if ( $linkConfig->isOrderGridRunWizardEnabled() === true ) {
222 $latteParams = [
223 'link' => $this->wpAdapter->adminUrl( 'admin.php?page=wc-orders&wizard-enabled=true&wizard-order-grid-enabled=true' ),
224 'title' => $this->wpAdapter->__( 'Use this link to start interactive tutorial', 'packeta' ),
225 'escapedText' => '&#9654; ' . htmlspecialchars( $linkConfig->getOrderGridRunWizardTitle() ),
226 ];
227 $htmlLinks['js-wizard-packetery-order-grid-run'] = $this->latteEngine->renderToString(
228 PACKETERY_PLUGIN_DIR . '/template/order/unescaped-link.latte',
229 $latteParams
230 );
231 }
232
233 return $htmlLinks;
234 }
235
236 /**
237 * Adds select to order grid.
238 */
239 public function renderOrderTypeSelect(): void {
240 if ( $this->contextResolver->isOrderGridPage() === false ) {
241 return;
242 }
243
244 $linkFilters = [];
245
246 if ( $this->httpRequest->getQuery( 'packetery_to_submit' ) !== null ) {
247 $linkFilters['packetery_to_submit'] = '1';
248 }
249
250 if ( $this->httpRequest->getQuery( 'packetery_to_print' ) !== null ) {
251 $linkFilters['packetery_to_print'] = '1';
252 }
253
254 $this->latteEngine->render(
255 PACKETERY_PLUGIN_DIR . '/template/order/type-select.latte',
256 [
257 'packeteryOrderType' => $this->httpRequest->getQuery( 'packetery_order_type' ),
258 'linkFilters' => $linkFilters,
259 'translations' => [
260 'packetaMethodType' => __( 'Packeta shipping method', 'packeta' ),
261 'carrierPackets' => __( 'Carrier packets', 'packeta' ),
262 'packetaPickupPointPackets' => __( 'Packeta pickup points packets', 'packeta' ),
263 ],
264 ]
265 );
266 }
267
268 /**
269 * Gets weight cell content.
270 *
271 * @param Core\Entity\Order $order Order.
272 *
273 * @return string
274 */
275 public function getWeightCellContent( Core\Entity\Order $order ): string {
276 return $this->latteEngine->renderToString(
277 self::TEMPLATE_GRID_COLUMN_WEIGHT,
278 $this->getWeightCellContentParams( $order )
279 );
280 }
281
282 /**
283 * Gets weight cell content.
284 *
285 * @param Core\Entity\Order $order Order.
286 *
287 * @return array{orderNumber: null|string, weight: null|float}
288 */
289 private function getWeightCellContentParams( Core\Entity\Order $order ): array {
290 return [
291 'orderNumber' => $order->getNumber(),
292 'weight' => $order->getFinalWeight(),
293 ];
294 }
295
296 /**
297 * Get Order Entity from cache
298 *
299 * @param int $orderId Order ID.
300 *
301 * @return Core\Entity\Order|null
302 * @throws InvalidCarrierException InvalidCarrierException.
303 */
304 private function getOrderByIdCached( int $orderId ): ?Core\Entity\Order {
305 static $ordersCache;
306
307 if ( ! isset( $ordersCache[ $orderId ] ) ) {
308 $ordersCache[ $orderId ] = $this->orderRepository->getById( $orderId );
309 }
310
311 return $ordersCache[ $orderId ] ?? null;
312 }
313
314 /**
315 * Fills custom order list columns.
316 *
317 * @param string|mixed $column Current order column name.
318 * @param WC_Order|int|mixed $wcOrder WC Order.
319 */
320 public function fillCustomOrderListColumns( $column, $wcOrder ): void {
321 if ( is_string( $column ) === false ) {
322 return;
323 }
324
325 if ( $wcOrder instanceof WC_Order ) {
326 $orderId = $wcOrder->get_id();
327 } elseif ( is_numeric( $wcOrder ) ) {
328 $orderId = (int) $wcOrder;
329 } else {
330 return;
331 }
332
333 try {
334 $order = $this->getOrderByIdCached( $orderId );
335 } catch ( InvalidCarrierException $exception ) {
336 if ( $column === 'packetery' ) {
337 echo esc_html( $exception->getMessage() );
338 }
339
340 return;
341 }
342 if ( $order === null ) {
343 return;
344 }
345
346 switch ( $column ) {
347 case 'packetery_weight':
348 $this->latteEngine->render(
349 self::TEMPLATE_GRID_COLUMN_WEIGHT,
350 $this->getWeightCellContentParams( $order )
351 );
352
353 break;
354 case 'packetery_destination':
355 $pickupPoint = $order->getPickupPoint();
356 if ( $pickupPoint !== null ) {
357 $pointPlaceOrName = $pickupPoint->getPlace() ?? $pickupPoint->getName();
358 $pointId = $pickupPoint->getId();
359 if ( ! $order->isExternalCarrier() ) {
360 echo esc_html( "$pointPlaceOrName ($pointId)" );
361 } else {
362 echo esc_html( $pointPlaceOrName );
363 }
364
365 break;
366 }
367
368 $homeDeliveryCarrierOptions = $this->carrierOptionsFactory->createByCarrierId( $order->getCarrier()->getId() );
369 echo esc_html( $homeDeliveryCarrierOptions->getName() );
370
371 break;
372 case 'packetery_packet_id':
373 $packetId = $order->getPacketId();
374 $packetClaimId = $order->getPacketClaimId();
375 $latteParams = [
376 'order' => $order,
377 'packetIdTrackingUrl' => null,
378 'packetClaimIdTrackingUrl' => null,
379 'translations' => [
380 'packetClaimTracking' => __( 'Packet claim tracking', 'packeta' ),
381 ],
382 ];
383
384 if ( $packetId !== null ) {
385 $latteParams['packetIdTrackingUrl'] = $this->coreHelper->getTrackingUrl( $packetId );
386 }
387
388 if ( $packetClaimId !== null ) {
389 $latteParams['packetClaimIdTrackingUrl'] = $this->coreHelper->getTrackingUrl( $packetClaimId );
390 }
391
392 $this->latteEngine->render(
393 PACKETERY_PLUGIN_DIR . '/template/order/grid-column-tracking.latte',
394 $latteParams
395 );
396
397 break;
398 case 'packetery':
399 $orderGridParams = $this->httpRequest->getUrl()->getQueryParameters();
400 unset( $orderGridParams['wizard-enabled'], $orderGridParams['wizard-order-grid-enabled'] );
401 $encodedOrderGridParams = rawurlencode( http_build_query( $orderGridParams ) );
402 $packetSubmitUrl = add_query_arg(
403 [
404 PacketActionsCommonLogic::PARAM_ORDER_ID => $order->getNumber(),
405 Plugin::PARAM_PACKETERY_ACTION => PacketActionsCommonLogic::ACTION_SUBMIT_PACKET,
406 PacketActionsCommonLogic::PARAM_REDIRECT_TO => PacketActionsCommonLogic::REDIRECT_TO_ORDER_GRID,
407 Plugin::PARAM_NONCE => wp_create_nonce( PacketActionsCommonLogic::createNonceAction( PacketActionsCommonLogic::ACTION_SUBMIT_PACKET, $order->getNumber() ) ),
408 PacketActionsCommonLogic::PARAM_ORDER_GRID_PARAMS => $encodedOrderGridParams,
409 ],
410 admin_url( 'admin.php' )
411 );
412 $printLink = add_query_arg(
413 [
414 'page' => LabelPrint::MENU_SLUG,
415 LabelPrint::LABEL_TYPE_PARAM => ( $order->isExternalCarrier() ? LabelPrint::ACTION_CARRIER_LABELS : LabelPrint::ACTION_PACKETA_LABELS ),
416 'id' => $order->getNumber(),
417 'packet_id' => $order->getPacketId(),
418 'offset' => 0,
419 PacketActionsCommonLogic::PARAM_ORDER_GRID_PARAMS => $encodedOrderGridParams,
420 ],
421 admin_url( 'admin.php' )
422 );
423 $packetCancelLink = add_query_arg(
424 [
425 PacketActionsCommonLogic::PARAM_ORDER_ID => $order->getNumber(),
426 PacketActionsCommonLogic::PARAM_PACKET_ID => $order->getPacketId(),
427 Plugin::PARAM_PACKETERY_ACTION => PacketActionsCommonLogic::ACTION_CANCEL_PACKET,
428 PacketActionsCommonLogic::PARAM_REDIRECT_TO => PacketActionsCommonLogic::REDIRECT_TO_ORDER_GRID,
429 Plugin::PARAM_NONCE => wp_create_nonce( PacketActionsCommonLogic::createNonceAction( PacketActionsCommonLogic::ACTION_CANCEL_PACKET, $order->getNumber() ) ),
430 PacketActionsCommonLogic::PARAM_ORDER_GRID_PARAMS => $encodedOrderGridParams,
431 ],
432 admin_url( 'admin.php' )
433 );
434
435 $invalidFields = $this->orderForm->getInvalidFieldsFromValidationResult( $this->orderValidator->validate( $order ) );
436 $invalidFieldsMessage = $this->orderForm->getInvalidFieldsMessageFromValidationResult( $invalidFields, $order );
437
438 $this->latteEngine->render(
439 PACKETERY_PLUGIN_DIR . '/template/order/grid-column-packetery.latte',
440 [
441 'order' => $order,
442 'dimensions' => $this->sizeFactory->createSizeInSetDimensionUnit( $order ),
443 'orderIsSubmittable' => $this->orderValidator->isValid( $order ),
444 'isPossibleExtendPacketPickUpDate' => $order->isPossibleExtendPacketPickUpDate(),
445 'storedUntil' => $this->coreHelper->getStringFromDateTime( $order->getStoredUntil(), CoreHelper::DATEPICKER_FORMAT ),
446 'orderWarningFields' => $invalidFields,
447 'invalidFieldsMessage' => $invalidFieldsMessage,
448 'packetSubmitUrl' => $packetSubmitUrl,
449 'packetCancelLink' => $packetCancelLink,
450 'printLink' => $printLink,
451 'helper' => $this->coreHelper,
452 'datePickerFormat' => CoreHelper::DATEPICKER_FORMAT,
453 'logPurgerDatetimeModifier' => $this->wpAdapter->getOption( Purger::PURGER_OPTION_NAME, Purger::PURGER_MODIFIER_DEFAULT ),
454 'packetDeliverOn' => $this->coreHelper->getStringFromDateTime( $order->getDeliverOn(), CoreHelper::DATEPICKER_FORMAT ),
455 'translations' => [
456 'printLabel' => __( 'Print label', 'packeta' ),
457 'setAdditionalPacketInfo' => __( 'Set additional packet information', 'packeta' ),
458 'setStoredUntil' => __( 'Set the pickup date extension', 'packeta' ),
459 'submitToPacketa' => __( 'Submit to Packeta', 'packeta' ),
460 // translators: %s: Order number.
461 'reallyCancelPacketHeading' => sprintf( __( 'Order #%s', 'packeta' ), $order->getCustomNumber() ),
462 // translators: %s: Packet number.
463 'reallyCancelPacket' => sprintf( __( 'Do you really wish to cancel parcel number %s?', 'packeta' ), (string) $order->getPacketId() ),
464
465 'cancelPacket' => __( 'Cancel packet', 'packeta' ),
466 'lastErrorFromApi' => __( 'Last error from Packeta API', 'packeta' ),
467 ],
468 ]
469 );
470
471 break;
472 case 'packetery_packet_status':
473 echo esc_html( $this->packetStatusResolver->getTranslatedName( $order->getPacketStatus() ) );
474
475 break;
476 case 'packetery_packet_stored_until':
477 $this->latteEngine->render(
478 PACKETERY_PLUGIN_DIR . '/template/order/grid-column-stored-until.latte',
479 [
480 'orderNumber' => $order->getNumber(),
481 'storedUntil' => $this->moduleHelper->getTranslatedStringFromDateTime( $order->getStoredUntil() ) ?? '',
482 ]
483 );
484
485 break;
486 }
487 }
488
489 /**
490 * Add order list columns.
491 *
492 * @param string[]|mixed $columns Order list columns.
493 *
494 * @return string[]|mixed All columns.
495 */
496 public function addOrderListColumns( $columns ) {
497 if ( ! is_array( $columns ) ) {
498 WcLogger::logArgumentTypeError( __METHOD__, 'columns', 'array', $columns );
499
500 return $columns;
501 }
502
503 $newColumns = array();
504
505 foreach ( $columns as $columnName => $columnInfo ) {
506 $newColumns[ $columnName ] = $columnInfo;
507
508 if ( $columnName === 'order_total' ) {
509 $newColumns['packetery_weight'] = __( 'Weight', 'packeta' );
510 $newColumns['packetery'] = __( 'Packeta', 'packeta' );
511 $newColumns['packetery_packet_id'] = __( 'Tracking No.', 'packeta' );
512 $newColumns['packetery_packet_status'] = __( 'Packeta packet status', 'packeta' );
513 $newColumns['packetery_packet_stored_until'] = __( 'Stored until', 'packeta' );
514 $newColumns['packetery_destination'] = __( 'Pickup point or carrier', 'packeta' );
515 }
516 }
517
518 return $newColumns;
519 }
520
521 /**
522 * Add order list sortable columns.
523 *
524 * @param string[] $columns Order list columns.
525 *
526 * @return string[] All columns.
527 */
528 public function makeOrderListSpecificColumnsSortable( array $columns ): array {
529 $metaKey = 'packetery_packet_stored_until';
530
531 return wp_parse_args( [ 'packetery_packet_stored_until' => $metaKey ], $columns );
532 }
533 }
534