PluginProbe
Packeta / 2.0.9
Packeta v2.0.9
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 / Repository.php

Repository.php in Packeta 2.0.9, at src/Packetery/Module/Order/Repository.php

729 lines 21.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Class Repository.
4 *
5 * @package Packetery\Module\Order
6 */
7
8 declare( strict_types=1 );
9
10 namespace Packetery\Module\Order;
11
12 use DateTimeImmutable;
13 use Exception;
14 use Packetery\Core\CoreHelper;
15 use Packetery\Core\Entity;
16 use Packetery\Core\Entity\Order;
17 use Packetery\Core\Entity\PickupPoint;
18 use Packetery\Module\Carrier;
19 use Packetery\Module\Carrier\PacketaPickupPointsConfig;
20 use Packetery\Module\CustomsDeclaration;
21 use Packetery\Module\Exception\InvalidCarrierException;
22 use Packetery\Module\ModuleHelper;
23 use Packetery\Module\Shipping\ShippingProvider;
24 use Packetery\Module\WpdbAdapter;
25 use WC_Order;
26 use WP_Post;
27
28 /**
29 * Class Repository.
30 *
31 * @package Packetery\Module\Order
32 */
33 class Repository {
34
35 /**
36 * WpdbAdapter.
37 *
38 * @var WpdbAdapter
39 */
40 private $wpdbAdapter;
41
42 /**
43 * Order factory.
44 *
45 * @var Builder
46 */
47 private $builder;
48
49 /**
50 * CoreHelper.
51 *
52 * @var CoreHelper
53 */
54 private $coreHelper;
55
56 /**
57 * Internal pickup points config.
58 *
59 * @var PacketaPickupPointsConfig
60 */
61 private $pickupPointsConfig;
62
63 /**
64 * Carrier repository.
65 *
66 * @var Carrier\EntityRepository
67 */
68 private $carrierRepository;
69
70 /**
71 * Customs declaration repository.
72 *
73 * @var CustomsDeclaration\Repository
74 */
75 private $customsDeclarationRepository;
76
77 /**
78 * Repository constructor.
79 *
80 * @param WpdbAdapter $wpdbAdapter WpdbAdapter.
81 * @param Builder $orderFactory Order factory.
82 * @param CoreHelper $coreHelper CoreHelper.
83 * @param PacketaPickupPointsConfig $pickupPointsConfig Internal pickup points config.
84 * @param Carrier\EntityRepository $carrierRepository Carrier repository.
85 * @param CustomsDeclaration\Repository $customsDeclarationRepository Customs declaration repository.
86 */
87 public function __construct(
88 WpdbAdapter $wpdbAdapter,
89 Builder $orderFactory,
90 CoreHelper $coreHelper,
91 PacketaPickupPointsConfig $pickupPointsConfig,
92 Carrier\EntityRepository $carrierRepository,
93 CustomsDeclaration\Repository $customsDeclarationRepository
94 ) {
95 $this->wpdbAdapter = $wpdbAdapter;
96 $this->builder = $orderFactory;
97 $this->coreHelper = $coreHelper;
98 $this->pickupPointsConfig = $pickupPointsConfig;
99 $this->carrierRepository = $carrierRepository;
100 $this->customsDeclarationRepository = $customsDeclarationRepository;
101 }
102
103 /**
104 * Applies custom order status filter.
105 *
106 * @param array<string, string|null> $clauses Query clauses.
107 * @param \WP_Query|null $queryObject WP Query.
108 * @param array<string, string|null> $paramValues Param values.
109 *
110 * @return void
111 */
112 private function applyCustomFilters( array &$clauses, ?\WP_Query $queryObject, array $paramValues ): void {
113 /**
114 * Filters order statuses to exclude in Packeta order list filtering.
115 *
116 * @since 1.4
117 *
118 * @param array $orderStatusesToExclude Order statuses to exclude.
119 * @param \WP_Query|null $queryObject WP Query.
120 * @param array $paramValues Param values.
121 */
122 $orderStatusesToExclude = (array) apply_filters( 'packetery_exclude_orders_with_status', [], $queryObject, $paramValues );
123 if ( count( $orderStatusesToExclude ) === 0 ) {
124 return;
125 }
126
127 if ( ModuleHelper::isHposEnabled() ) {
128 $clauses['where'] .= sprintf( ' AND `%s`.`status` NOT IN (%s)', $this->wpdbAdapter->wcOrders, $this->wpdbAdapter->prepareInClause( $orderStatusesToExclude ) );
129 } else {
130 $clauses['where'] .= sprintf( ' AND `%s`.`post_status` NOT IN (%s)', $this->wpdbAdapter->posts, $this->wpdbAdapter->prepareInClause( $orderStatusesToExclude ) );
131 }
132 }
133
134 /**
135 * Extends SQL query clauses.
136 *
137 * @param array<string, string> $clauses Clauses.
138 * @param \WP_Query|null $queryObject Query object.
139 * @param array<string, string|null> $paramValues Param values.
140 *
141 * @return array<string, string>
142 */
143 public function processClauses( array $clauses, ?\WP_Query $queryObject, array $paramValues ): array {
144 if ( ModuleHelper::isHposEnabled() ) {
145 $clauses['join'] .= ' LEFT JOIN `' . $this->wpdbAdapter->packeteryOrder . '` ON `' . $this->wpdbAdapter->packeteryOrder . '`.`id` = `' . $this->wpdbAdapter->wcOrders . '`.`id`';
146 } else {
147 $clauses['join'] .= ' LEFT JOIN `' . $this->wpdbAdapter->packeteryOrder . '` ON `' . $this->wpdbAdapter->packeteryOrder . '`.`id` = `' . $this->wpdbAdapter->posts . '`.`id`';
148 }
149
150 if ( isset( $paramValues['packetery_carrier_id'] ) && $paramValues['packetery_carrier_id'] !== '' ) {
151 $clauses['where'] .= ' AND `' . $this->wpdbAdapter->packeteryOrder . '`.`carrier_id` = "' . esc_sql( $paramValues['packetery_carrier_id'] ) . '"';
152 $this->applyCustomFilters( $clauses, $queryObject, $paramValues );
153 }
154 if ( isset( $paramValues['packetery_to_submit'] ) && $paramValues['packetery_to_submit'] !== '' ) {
155 $clauses['where'] .= ' AND `' . $this->wpdbAdapter->packeteryOrder . '`.`carrier_id` IS NOT NULL ';
156 $clauses['where'] .= ' AND `' . $this->wpdbAdapter->packeteryOrder . '`.`is_exported` = false ';
157 $this->applyCustomFilters( $clauses, $queryObject, $paramValues );
158 }
159 if ( isset( $paramValues['packetery_to_print'] ) && $paramValues['packetery_to_print'] !== '' ) {
160 $clauses['where'] .= ' AND `' . $this->wpdbAdapter->packeteryOrder . '`.`packet_id` IS NOT NULL ';
161 $clauses['where'] .= ' AND `' . $this->wpdbAdapter->packeteryOrder . '`.`is_label_printed` = false ';
162 $this->applyCustomFilters( $clauses, $queryObject, $paramValues );
163 }
164 if ( isset( $paramValues['packetery_order_type'] ) && $paramValues['packetery_order_type'] !== '' ) {
165 if ( $paramValues['packetery_order_type'] === Entity\Carrier::INTERNAL_PICKUP_POINTS_ID ) {
166 $comparison = 'IN';
167 } else {
168 $comparison = 'NOT IN';
169 }
170 $internalCarriers = array_keys( $this->carrierRepository->getNonFeedCarriers() );
171 $internalCarriers[] = Entity\Carrier::INTERNAL_PICKUP_POINTS_ID;
172 $clauses['where'] .= ' AND `' . $this->wpdbAdapter->packeteryOrder . '`.`carrier_id` ' . $comparison . ' (' . $this->wpdbAdapter->prepareInClause( $internalCarriers ) . ')';
173 $this->applyCustomFilters( $clauses, $queryObject, $paramValues );
174 }
175 if ( isset( $paramValues['orderby'] ) && $paramValues['orderby'] === 'packetery_packet_stored_until' ) {
176 if ( $paramValues['order'] === 'asc' ) {
177 $clauses['orderby'] = '`' . $this->wpdbAdapter->packeteryOrder . '`.`stored_until` ASC';
178 }
179 if ( $paramValues['order'] === 'desc' ) {
180 $clauses['orderby'] = '`' . $this->wpdbAdapter->packeteryOrder . '`.`stored_until` DESC';
181 }
182 }
183
184 return $clauses;
185 }
186
187 /**
188 * Create table to store orders.
189 *
190 * @return bool
191 */
192 public function createOrAlterTable(): bool {
193 $createTableQuery = 'CREATE TABLE ' . $this->wpdbAdapter->packeteryOrder . ' (
194 `id` bigint(20) unsigned NOT NULL,
195 `carrier_id` varchar(15) NOT NULL,
196 `is_exported` tinyint(1) NOT NULL,
197 `packet_id` varchar(15) NULL,
198 `packet_claim_id` varchar(15) NULL,
199 `packet_claim_password` varchar(10) NULL,
200 `is_label_printed` tinyint(1) NOT NULL,
201 `point_id` varchar(50) NULL,
202 `point_name` varchar(150) NULL,
203 `point_url` varchar(255) NULL,
204 `point_street` varchar(120) NULL,
205 `point_zip` varchar(10) NULL,
206 `point_city` varchar(70) NULL,
207 `address_validated` tinyint(1) NOT NULL,
208 `delivery_address` text NULL,
209 `weight` float NULL,
210 `length` float NULL,
211 `width` float NULL,
212 `height` float NULL,
213 `adult_content` tinyint(1) NULL,
214 `value` double NULL,
215 `cod` double NULL,
216 `api_error_message` text NULL,
217 `api_error_date` datetime NULL,
218 `carrier_number` varchar(50) NULL,
219 `packet_status` varchar(30) NULL,
220 `stored_until` date NULL,
221 `deliver_on` date NULL,
222 `car_delivery_id` varchar(15) NULL,
223 PRIMARY KEY (`id`)
224 ) ' . $this->wpdbAdapter->get_charset_collate();
225
226 return $this->wpdbAdapter->dbDelta( $createTableQuery, $this->wpdbAdapter->packeteryOrder );
227 }
228
229 /**
230 * Drop table used to store orders.
231 */
232 public function drop(): void {
233 $this->wpdbAdapter->query( 'DROP TABLE IF EXISTS `' . $this->wpdbAdapter->packeteryOrder . '`' );
234 }
235
236 /**
237 * @throws InvalidCarrierException InvalidCarrierException.
238 */
239 public function getById( int $id ): ?Order {
240 $wcOrder = $this->getWcOrderById( $id );
241 if ( $wcOrder === null ) {
242 return null;
243 }
244
245 return $this->getByWcOrder( $wcOrder );
246 }
247
248 /**
249 * Ignores InvalidCarrierException.
250 */
251 public function getByIdWithValidCarrier( int $id ): ?Order {
252 $wcOrder = $this->getWcOrderById( $id );
253 if ( $wcOrder === null ) {
254 return null;
255 }
256
257 return $this->getByWcOrderWithValidCarrier( $wcOrder );
258 }
259
260 /**
261 * Returns Packeta order, or null.
262 *
263 * @param int $id Order ID.
264 *
265 * @return Order|null
266 */
267 public function findById( int $id ): ?Order {
268 $wcOrder = $this->getWcOrderById( $id );
269 if ( $wcOrder === null ) {
270 return null;
271 }
272
273 $result = $this->getDataById( $wcOrder->get_id() );
274 if ( $result === null ) {
275 return null;
276 }
277
278 try {
279 return $this->builder->build( $wcOrder, $result );
280 } catch ( InvalidCarrierException $invalidCarrierException ) {
281 return null;
282 }
283 }
284
285 /**
286 * Gets Packeta order data by id.
287 *
288 * @param int $id Order id.
289 *
290 * @return object|null
291 */
292 public function getDataById( int $id ): ?object {
293 return $this->wpdbAdapter->get_row(
294 $this->wpdbAdapter->prepare(
295 '
296 SELECT `o`.* FROM `' . $this->wpdbAdapter->packeteryOrder . '` `o`
297 ' . $this->getWcOrderJoinClause() . '
298 WHERE `o`.`id` = %d',
299 $id
300 )
301 );
302 }
303
304 private function getDataByWcOrder( WC_Order $wcOrder ): ?object {
305 if ( ! ShippingProvider::wcOrderHasOurMethod( $wcOrder ) ) {
306 return null;
307 }
308
309 $packeteryOrderData = $this->getDataById( $wcOrder->get_id() );
310 if ( ! is_object( $packeteryOrderData ) ) {
311 return null;
312 }
313
314 return $packeteryOrderData;
315 }
316
317 /**
318 * @throws InvalidCarrierException
319 */
320 public function getByWcOrder( WC_Order $wcOrder ): ?Order {
321 $packeteryOrderData = $this->getDataByWcOrder( $wcOrder );
322 if ( $packeteryOrderData === null ) {
323 return null;
324 }
325
326 return $this->builder->build( $wcOrder, $packeteryOrderData );
327 }
328
329 /**
330 * Ignores InvalidCarrierException.
331 */
332 public function getByWcOrderWithValidCarrier( WC_Order $wcOrder ): ?Order {
333 $packeteryOrderData = $this->getDataByWcOrder( $wcOrder );
334 if ( $packeteryOrderData === null ) {
335 return null;
336 }
337
338 try {
339 return $this->builder->build( $wcOrder, $packeteryOrderData );
340 } catch ( InvalidCarrierException $invalidCarrierException ) {
341 return null;
342 }
343 }
344
345 /**
346 * Transforms order to DB array.
347 *
348 * @param Order $order Order.
349 *
350 * @return array<string, bool|float|int|string|null>
351 */
352 private function orderToDbArray( Order $order ): array {
353 $point = $order->getPickupPoint();
354 if ( $point === null ) {
355 $point = new PickupPoint();
356 }
357
358 $deliveryAddress = null;
359 if ( $order->isAddressValidated() && $order->getDeliveryAddress() !== null ) {
360 $deliveryAddress = wp_json_encode( $order->getDeliveryAddress()->export() );
361 }
362
363 $apiErrorDateTime = $order->getLastApiErrorDateTime();
364 if ( $apiErrorDateTime !== null ) {
365 $apiErrorDateTime = $apiErrorDateTime->format( CoreHelper::MYSQL_DATETIME_FORMAT );
366 }
367
368 $data = [
369 'id' => (int) $order->getNumber(),
370 'carrier_id' => $order->getCarrier()->getId(),
371 'is_exported' => (int) $order->isExported(),
372 'packet_id' => $order->getPacketId(),
373 'packet_claim_id' => $order->getPacketClaimId(),
374 'packet_claim_password' => $order->getPacketClaimPassword(),
375 'packet_status' => $order->getPacketStatus(),
376 'stored_until' => $this->coreHelper->getStringFromDateTime( $order->getStoredUntil(), CoreHelper::DATEPICKER_FORMAT ),
377 'is_label_printed' => (int) $order->isLabelPrinted(),
378 'carrier_number' => $order->getCarrierNumber(),
379 'weight' => $order->getWeight(),
380 'car_delivery_id' => $order->getCarDeliveryId(),
381 'point_id' => $point->getId(),
382 'point_name' => $point->getName(),
383 'point_url' => $point->getUrl(),
384 'point_street' => $point->getStreet(),
385 'point_zip' => $point->getZip(),
386 'point_city' => $point->getCity(),
387 'address_validated' => (int) $order->isAddressValidated(),
388 'delivery_address' => $deliveryAddress,
389 'length' => $order->getLength(),
390 'width' => $order->getWidth(),
391 'height' => $order->getHeight(),
392 'adult_content' => $order->containsAdultContent(),
393 'cod' => $order->getManualCod(),
394 'value' => $order->getManualValue(),
395 'api_error_message' => $order->getLastApiErrorMessage(),
396 'api_error_date' => $apiErrorDateTime,
397 'deliver_on' => $this->coreHelper->getStringFromDateTime( $order->getDeliverOn(), CoreHelper::DATEPICKER_FORMAT ),
398 ];
399
400 return $data;
401 }
402
403 /**
404 * Saves order.
405 *
406 * @param Order $order Order.
407 *
408 * @return void
409 */
410 public function save( Order $order ): void {
411 $this->saveData( $this->orderToDbArray( $order ) );
412 }
413
414 /**
415 * Saves order data.
416 *
417 * @param array<string, int|string|null|DateTimeImmutable> $orderData Order data.
418 *
419 * @return void
420 */
421 public function saveData( array $orderData ): void {
422 $this->onBeforeDataInsertion( $orderData );
423 $this->wpdbAdapter->insertReplaceHelper( $this->wpdbAdapter->packeteryOrder, $orderData, null, 'REPLACE' );
424 }
425
426 /**
427 * Calls logic before order data replace/insert.
428 *
429 * @param array<string, string|null|DateTimeImmutable> $orderData Order data.
430 * @return void
431 */
432 private function onBeforeDataInsertion( array $orderData ): void {
433 $pointId = $orderData['point_id'] ?? null;
434 $carrierId = $orderData['carrier_id'] ?? null;
435 /**
436 * Tells if Packeta debug logs are enabled.
437 *
438 * @since 1.7.2
439 */
440 $isLoggingActive = (bool) apply_filters( 'packeta_enable_debug_logs', false );
441
442 if ( ( $pointId !== null && $pointId !== '' ) || ! $isLoggingActive || ! $this->pickupPointsConfig->isInternalPickupPointCarrier( $carrierId ) ) {
443 return;
444 }
445
446 $wcLogger = wc_get_logger();
447 $dataToLog = [
448 'order' => $orderData,
449 'trace' => array_map(
450 static function ( array $item ): array {
451 return [
452 'file' => sprintf( '%s(%s)', $item['file'], $item['line'] ),
453 'method' => sprintf( '%s%s%s(...)', $item['class'] ?? '', $item['type'] ?? '', $item['function'] ),
454 ];
455 },
456 ( new Exception() )->getTrace()
457 ),
458 ];
459 $wcLogger->warning(
460 sprintf(
461 'Required value for the pickup point order is not set: %s',
462 wp_json_encode( $dataToLog, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE )
463 ),
464 [ 'source' => 'packeta' ]
465 );
466 }
467
468 /**
469 * Loads order entities by list of ids.
470 *
471 * @param string[] $orderIds Order ids.
472 *
473 * @return Order[]
474 */
475 public function getByIds( array $orderIds ): array {
476 if ( count( $orderIds ) === 0 ) {
477 return [];
478 }
479
480 $wpdbAdapter = $this->wpdbAdapter;
481 $ordersIdsPlaceholder = implode( ', ', array_fill( 0, count( $orderIds ), '%d' ) );
482 $packeteryOrdersResult = $wpdbAdapter->get_results(
483 $wpdbAdapter->prepare(
484 'SELECT * FROM `' . $wpdbAdapter->packeteryOrder . '`
485 WHERE `id` IN (' . $ordersIdsPlaceholder . ')',
486 $orderIds
487 ),
488 OBJECT_K
489 );
490
491 $orderEntities = [];
492 foreach ( $orderIds as $orderId ) {
493 if ( ! isset( $packeteryOrdersResult[ $orderId ] ) ) {
494 continue;
495 }
496
497 $wcOrder = $this->getWcOrderById( (int) $orderId );
498 assert( $wcOrder !== null, 'WC order has to be present' );
499
500 try {
501 $orderEntities[ $orderId ] = $this->builder->build( $wcOrder, $packeteryOrdersResult[ $orderId ] );
502 } catch ( InvalidCarrierException $exception ) {
503 continue;
504 }
505 }
506
507 return $orderEntities;
508 }
509
510 /**
511 * Finds orders.
512 *
513 * @param string[] $allowedPacketStatuses Allowed packet statuses.
514 * @param string[] $allowedOrderStatuses Allowed order statuses.
515 * @param int $maxDays Max number of days of single packet sync.
516 * @param int $limit Number of records.
517 *
518 * @return \Generator<int>
519 * @throws Exception Exception.
520 */
521 public function findStatusSyncingOrderIds( array $allowedPacketStatuses, array $allowedOrderStatuses, int $maxDays, int $limit ): \Generator {
522 $dateLimit = CoreHelper::now()->modify( '- ' . $maxDays . ' days' )->format( 'Y-m-d H:i:s' );
523
524 $andWhere = [ '`o`.`packet_id` IS NOT NULL' ];
525 $hposEnabled = ModuleHelper::isHposEnabled();
526
527 if ( $hposEnabled ) {
528 $andWhere[] = $this->wpdbAdapter->prepare( '`wc_o`.`date_created_gmt` >= %s', $dateLimit );
529 } else {
530 $andWhere[] = $this->wpdbAdapter->prepare( '`wp_p`.`post_date_gmt` >= %s', $dateLimit );
531 }
532
533 $orPacketStatus = [];
534 $orPacketStatus[] = '`o`.`packet_status` IS NULL';
535
536 if ( count( $allowedPacketStatuses ) > 0 ) {
537 $orPacketStatus[] = '`o`.`packet_status` IN (' . $this->wpdbAdapter->prepareInClause( $allowedPacketStatuses ) . ')';
538 }
539
540 if ( count( $orPacketStatus ) > 0 ) {
541 $andWhere[] = '(' . implode( ' OR ', $orPacketStatus ) . ')';
542 }
543
544 if ( count( $allowedOrderStatuses ) > 0 && $hposEnabled ) {
545 $andWhere[] = '`wc_o`.`status` IN (' . $this->wpdbAdapter->prepareInClause( $allowedOrderStatuses ) . ')';
546 } elseif ( count( $allowedOrderStatuses ) > 0 && $hposEnabled === false ) {
547 $andWhere[] = '`wp_p`.`post_status` IN (' . $this->wpdbAdapter->prepareInClause( $allowedOrderStatuses ) . ')';
548 } else {
549 $andWhere[] = '1 = 0';
550 }
551
552 $where = '';
553 if ( count( $andWhere ) > 0 ) {
554 $where = ' WHERE ' . implode( ' AND ', $andWhere );
555 }
556
557 if ( $hposEnabled ) {
558 $orderBy = ' ORDER BY `wc_o`.`date_created_gmt` ';
559 } else {
560 $orderBy = ' ORDER BY `wp_p`.`post_date_gmt` ';
561 }
562
563 $sql = $this->wpdbAdapter->prepare(
564 '
565 SELECT `o`.`id` FROM `' . $this->wpdbAdapter->packeteryOrder . '` `o`
566 ' . $this->getWcOrderJoinClause() . '
567 ' . $where . '
568 ' . $orderBy . '
569 LIMIT %d',
570 $limit
571 );
572
573 $rows = $this->wpdbAdapter->get_results( $sql );
574
575 foreach ( $rows as $row ) {
576 $wcOrder = $this->getWcOrderById( (int) $row->id );
577 if ( $wcOrder === null || ! ShippingProvider::wcOrderHasOurMethod( $wcOrder ) ) {
578 continue;
579 }
580
581 yield (int) $row->id;
582 }
583 }
584
585 /**
586 * Counts order to be submitted.
587 *
588 * @return int
589 */
590 public function countOrdersToSubmit(): int {
591 return $this->countOrders( [ 'packetery_to_submit' => '1' ] );
592 }
593
594 /**
595 * Counts order to be printed.
596 *
597 * @return int
598 */
599 public function countOrdersToPrint(): int {
600 return $this->countOrders( [ 'packetery_to_print' => '1' ] );
601 }
602
603 /**
604 * Counts orders by given params.
605 *
606 * @param array<string, string> $params Params.
607 *
608 * @return int
609 */
610 private function countOrders( array $params ): int {
611 $clauses = [ 'join' => '' ];
612
613 if ( ModuleHelper::isHposEnabled() ) {
614 $clauses['select'] = ' SELECT COUNT(DISTINCT `' . $this->wpdbAdapter->wcOrders . '`.`id`) ';
615 $clauses['from'] = ' FROM `' . $this->wpdbAdapter->wcOrders . '` ';
616 } else {
617 $clauses['select'] = ' SELECT COUNT(DISTINCT `' . $this->wpdbAdapter->posts . '`.`ID`) ';
618 $clauses['from'] = ' FROM `' . $this->wpdbAdapter->posts . '` ';
619 }
620
621 $clauses['where'] = ' WHERE `' . $this->wpdbAdapter->packeteryOrder . '`.`id` IS NOT NULL ';
622 $clauses = $this->processClauses( $clauses, null, $params );
623
624 return (int) $this->wpdbAdapter->get_var(
625 $clauses['select'] .
626 $clauses['from'] .
627 $clauses['join'] .
628 $clauses['where']
629 );
630 }
631
632 /**
633 * Gets WC Order join clause.
634 *
635 * @return string
636 */
637 public function getWcOrderJoinClause(): string {
638 $packeteryTableAlias = 'o';
639
640 if ( ModuleHelper::isHposEnabled() ) {
641 $sourceTableAlias = 'wc_o';
642
643 return sprintf(
644 'JOIN `%s` `%s` ON `%s`.`id` = `%s`.`id`',
645 $this->wpdbAdapter->wcOrders,
646 $sourceTableAlias,
647 $sourceTableAlias,
648 $packeteryTableAlias
649 );
650 }
651
652 $sourceTableAlias = 'wp_p';
653
654 return sprintf(
655 'JOIN `%s` `%s` ON `%s`.`ID` = `%s`.`id`',
656 $this->wpdbAdapter->posts,
657 $sourceTableAlias,
658 $sourceTableAlias,
659 $packeteryTableAlias
660 );
661 }
662
663 /**
664 * Deletes all custom table records linked to permanently deleted orders.
665 *
666 * @return void
667 */
668 public function deleteOrphans(): void {
669 if ( ModuleHelper::isHposEnabled() ) {
670 $this->wpdbAdapter->query(
671 'DELETE `' . $this->wpdbAdapter->packeteryOrder . '` FROM `' . $this->wpdbAdapter->packeteryOrder . '`
672 LEFT JOIN `' . $this->wpdbAdapter->wcOrders . '` ON `' . $this->wpdbAdapter->wcOrders . '`.`id` = `' . $this->wpdbAdapter->packeteryOrder . '`.`id`
673 WHERE `' . $this->wpdbAdapter->wcOrders . '`.`id` IS NULL'
674 );
675
676 return;
677 }
678
679 $this->wpdbAdapter->query(
680 'DELETE `' . $this->wpdbAdapter->packeteryOrder . '` FROM `' . $this->wpdbAdapter->packeteryOrder . '`
681 LEFT JOIN `' . $this->wpdbAdapter->posts . '` ON `' . $this->wpdbAdapter->posts . '`.`ID` = `' . $this->wpdbAdapter->packeteryOrder . '`.`id`
682 WHERE `' . $this->wpdbAdapter->posts . '`.`ID` IS NULL'
683 );
684 }
685
686 /**
687 * Deletes order data including customs declaration and its items from custom tables.
688 *
689 * @param int $orderId Order id.
690 *
691 * @return void
692 */
693 public function delete( int $orderId ): void {
694 $this->customsDeclarationRepository->delete( (string) $orderId );
695 $this->wpdbAdapter->delete( $this->wpdbAdapter->packeteryOrder, [ 'id' => $orderId ], '%d' );
696 }
697
698 /**
699 * Fires after post deletion.
700 *
701 * @param int $postId Post id.
702 * @param WP_Post $post Post object.
703 *
704 * @return void
705 */
706 public function deletedPostHook( int $postId, WP_Post $post ): void {
707 // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
708 if ( $post->post_type === 'shop_order' ) {
709 $this->delete( $postId );
710 }
711 }
712
713 /**
714 * Gets WC_Order object.
715 *
716 * @param int $id Order id.
717 *
718 * @return WC_Order|null
719 */
720 public function getWcOrderById( int $id ): ?WC_Order {
721 $result = wc_get_order( $id );
722 if ( $result instanceof WC_Order ) {
723 return $result;
724 }
725
726 return null;
727 }
728 }
729