PluginProbe
Packeta / 1.6.3
Packeta v1.6.3
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 1.6.3, at src/Packetery/Module/Order/Repository.php

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