PluginProbe
Packeta / 1.6.0
Packeta v1.6.0
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.0, 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 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 $carrierId = $this->pickupPointsConfig->getFixedCarrierId( $result->carrier_id, $country );
296 $carrier = $this->carrierRepository->getAnyById( $carrierId );
297 if ( null === $carrier ) {
298 throw new InvalidCarrierException(
299 sprintf(
300 // translators: %s is carrier id.
301 __( 'Order carrier is invalid (%s). Please contact Packeta support.', 'packeta' ),
302 $carrierId
303 )
304 );
305 }
306 $partialOrder = new Order( $result->id, $carrier );
307 $orderWeight = $this->parseFloat( $result->weight );
308 if ( null !== $orderWeight ) {
309 $partialOrder->setWeight( $orderWeight );
310 }
311 $partialOrder->setPacketId( $result->packet_id );
312 $partialOrder->setPacketClaimId( $result->packet_claim_id );
313 $partialOrder->setPacketClaimPassword( $result->packet_claim_password );
314 $partialOrder->setSize( new Size( $this->parseFloat( $result->length ), $this->parseFloat( $result->width ), $this->parseFloat( $result->height ) ) );
315 $partialOrder->setIsExported( (bool) $result->is_exported );
316 $partialOrder->setIsLabelPrinted( (bool) $result->is_label_printed );
317 $partialOrder->setCarrierNumber( $result->carrier_number );
318 $partialOrder->setPacketStatus( $result->packet_status );
319 $partialOrder->setAddressValidated( (bool) $result->address_validated );
320 $partialOrder->setAdultContent( $this->parseBool( $result->adult_content ) );
321 $partialOrder->setValue( $this->parseFloat( $result->value ) );
322 $partialOrder->setCod( $this->parseFloat( $result->cod ) );
323 $partialOrder->setDeliverOn( $this->helper->getDateTimeFromString( $result->deliver_on ) );
324 $partialOrder->setLastApiErrorMessage( $result->api_error_message );
325 $partialOrder->setLastApiErrorDateTime(
326 ( null === $result->api_error_date )
327 ? null
328 : \DateTimeImmutable::createFromFormat(
329 Core\Helper::MYSQL_DATETIME_FORMAT,
330 $result->api_error_date,
331 new \DateTimeZone( 'UTC' )
332 )->setTimezone( wp_timezone() )
333 );
334
335 if ( $result->delivery_address ) {
336 $deliveryAddressDecoded = json_decode( $result->delivery_address, false );
337 $deliveryAddress = new Address(
338 $deliveryAddressDecoded->street,
339 $deliveryAddressDecoded->city,
340 $deliveryAddressDecoded->zip
341 );
342
343 $deliveryAddress->setHouseNumber( $deliveryAddressDecoded->houseNumber );
344 $deliveryAddress->setLongitude( $deliveryAddressDecoded->longitude );
345 $deliveryAddress->setLatitude( $deliveryAddressDecoded->latitude );
346 $deliveryAddress->setCounty( $deliveryAddressDecoded->county );
347
348 $partialOrder->setDeliveryAddress( $deliveryAddress );
349 }
350
351 if ( null !== $result->point_id ) {
352 $pickUpPoint = new PickupPoint(
353 $result->point_id,
354 $result->point_name,
355 $result->point_city,
356 $result->point_zip,
357 $result->point_street,
358 $result->point_url
359 );
360
361 $partialOrder->setPickupPoint( $pickUpPoint );
362 }
363
364 return $partialOrder;
365 }
366
367 /**
368 * Parses string value as float.
369 *
370 * @param string|float|null $value Value.
371 *
372 * @return float|null
373 */
374 private function parseFloat( $value ): ?float {
375 if ( null === $value || '' === $value ) {
376 return null;
377 }
378
379 return (float) $value;
380 }
381
382 /**
383 * Parses string value as float.
384 *
385 * @param string|int|null $value Value.
386 *
387 * @return bool|null
388 */
389 private function parseBool( $value ): ?bool {
390 if ( null === $value || '' === $value ) {
391 return null;
392 }
393
394 return (bool) $value;
395 }
396
397 /**
398 * Transforms order to DB array.
399 *
400 * @param Order $order Order.
401 *
402 * @return array
403 */
404 private function orderToDbArray( Order $order ): array {
405 $point = $order->getPickupPoint();
406 if ( null === $point ) {
407 $point = new PickupPoint();
408 }
409
410 $deliveryAddress = null;
411 if ( $order->isAddressValidated() && $order->getDeliveryAddress() ) {
412 $deliveryAddress = wp_json_encode( $order->getDeliveryAddress()->export() );
413 }
414
415 $apiErrorDateTime = $order->getLastApiErrorDateTime();
416 if ( null !== $apiErrorDateTime ) {
417 $apiErrorDateTime = $apiErrorDateTime->format( Core\Helper::MYSQL_DATETIME_FORMAT );
418 }
419
420 $data = [
421 'id' => (int) $order->getNumber(),
422 'carrier_id' => $order->getCarrier()->getId(),
423 'is_exported' => (int) $order->isExported(),
424 'packet_id' => $order->getPacketId(),
425 'packet_claim_id' => $order->getPacketClaimId(),
426 'packet_claim_password' => $order->getPacketClaimPassword(),
427 'packet_status' => $order->getPacketStatus(),
428 'is_label_printed' => (int) $order->isLabelPrinted(),
429 'carrier_number' => $order->getCarrierNumber(),
430 'weight' => $order->getWeight(),
431 'point_id' => $point->getId(),
432 'point_name' => $point->getName(),
433 'point_url' => $point->getUrl(),
434 'point_street' => $point->getStreet(),
435 'point_zip' => $point->getZip(),
436 'point_city' => $point->getCity(),
437 'address_validated' => (int) $order->isAddressValidated(),
438 'delivery_address' => $deliveryAddress,
439 'length' => $order->getLength(),
440 'width' => $order->getWidth(),
441 'height' => $order->getHeight(),
442 'adult_content' => $order->containsAdultContent(),
443 'cod' => $order->getCod(),
444 'value' => $order->getValue(),
445 'api_error_message' => $order->getLastApiErrorMessage(),
446 'api_error_date' => $apiErrorDateTime,
447 'deliver_on' => $this->helper->getStringFromDateTime( $order->getDeliverOn(), $this->helper::DATEPICKER_FORMAT ),
448 ];
449
450 return $data;
451 }
452
453 /**
454 * Saves order.
455 *
456 * @param Order $order Order.
457 *
458 * @return void
459 */
460 public function save( Order $order ): void {
461 $this->wpdbAdapter->insertReplaceHelper( $this->wpdbAdapter->packetery_order, $this->orderToDbArray( $order ), null, 'REPLACE' );
462 }
463
464 /**
465 * Loads order entities by list of ids.
466 *
467 * @param array $orderIds Order ids.
468 *
469 * @return Order[]
470 */
471 public function getByIds( array $orderIds ): array {
472 if ( empty( $orderIds ) ) {
473 return [];
474 }
475
476 $wpdbAdapter = $this->wpdbAdapter;
477 $ordersIdsPlaceholder = implode( ', ', array_fill( 0, count( $orderIds ), '%d' ) );
478 $packeteryOrdersResult = $wpdbAdapter->get_results(
479 $wpdbAdapter->prepare(
480 'SELECT * FROM `' . $wpdbAdapter->packetery_order . '`
481 WHERE `id` IN (' . $ordersIdsPlaceholder . ')',
482 $orderIds
483 ),
484 OBJECT_K
485 );
486
487 $orderEntities = [];
488 foreach ( $orderIds as $orderId ) {
489 if ( ! isset( $packeteryOrdersResult[ $orderId ] ) ) {
490 continue;
491 }
492
493 $wcOrder = $this->getWcOrderById( (int) $orderId );
494 assert( null !== $wcOrder, 'WC order has to be present' );
495
496 try {
497 $partialOrder = $this->createPartialOrder(
498 $packeteryOrdersResult[ $orderId ],
499 Module\Helper::getWcOrderCountry( $wcOrder )
500 );
501 $orderEntities[ $orderId ] = $this->builder->finalize( $wcOrder, $partialOrder );
502 } catch ( InvalidCarrierException $exception ) {
503 continue;
504 }
505 }
506
507 return $orderEntities;
508 }
509
510 /**
511 * Finds orders.
512 *
513 * @param array $allowedPacketStatuses Allowed packet statuses.
514 * @param array $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 iterable|Order[]
519 */
520 public function findStatusSyncingOrders( array $allowedPacketStatuses, array $allowedOrderStatuses, int $maxDays, int $limit ): iterable {
521 $dateLimit = Core\Helper::now()->modify( '- ' . $maxDays . ' days' )->format( 'Y-m-d H:i:s' );
522
523 $andWhere = [ '`o`.`packet_id` IS NOT NULL' ];
524 $hposEnabled = Module\Helper::isHposEnabled();
525
526 if ( $hposEnabled ) {
527 $andWhere[] = $this->wpdbAdapter->prepare( '`wc_o`.`date_created_gmt` >= %s', $dateLimit );
528 } else {
529 $andWhere[] = $this->wpdbAdapter->prepare( '`wp_p`.`post_date_gmt` >= %s', $dateLimit );
530 }
531
532 $orPacketStatus = [];
533 $orPacketStatus[] = '`o`.`packet_status` IS NULL';
534
535 if ( $allowedPacketStatuses ) {
536 $orPacketStatus[] = '`o`.`packet_status` IN (' . $this->wpdbAdapter->prepareInClause( $allowedPacketStatuses ) . ')';
537 }
538
539 if ( $orPacketStatus ) {
540 $andWhere[] = '(' . implode( ' OR ', $orPacketStatus ) . ')';
541 }
542
543 if ( $allowedOrderStatuses && $hposEnabled ) {
544 $andWhere[] = '`wc_o`.`status` IN (' . $this->wpdbAdapter->prepareInClause( $allowedOrderStatuses ) . ')';
545 } elseif ( $allowedOrderStatuses && false === $hposEnabled ) {
546 $andWhere[] = '`wp_p`.`post_status` IN (' . $this->wpdbAdapter->prepareInClause( $allowedOrderStatuses ) . ')';
547 } else {
548 $andWhere[] = '1 = 0';
549 }
550
551 $where = '';
552 if ( $andWhere ) {
553 $where = ' WHERE ' . implode( ' AND ', $andWhere );
554 }
555
556 if ( $hposEnabled ) {
557 $orderBy = ' ORDER BY `wc_o`.`date_created_gmt` ';
558 } else {
559 $orderBy = ' ORDER BY `wp_p`.`post_date_gmt` ';
560 }
561
562 $sql = $this->wpdbAdapter->prepare(
563 '
564 SELECT `o`.* FROM `' . $this->wpdbAdapter->packetery_order . '` `o`
565 ' . $this->getWcOrderJoinClause() . '
566 ' . $where . '
567 ' . $orderBy . '
568 LIMIT %d',
569 $limit
570 );
571
572 $rows = $this->wpdbAdapter->get_results( $sql );
573
574 foreach ( $rows as $row ) {
575 $wcOrder = $this->getWcOrderById( (int) $row->id );
576 if ( null === $wcOrder || ! $wcOrder->has_shipping_method( ShippingMethod::PACKETERY_METHOD_ID ) ) {
577 continue;
578 }
579
580 try {
581 $partial = $this->createPartialOrder( $row, Module\Helper::getWcOrderCountry( $wcOrder ) );
582 yield $this->builder->finalize( $wcOrder, $partial );
583 } catch ( InvalidCarrierException $exception ) {
584 continue;
585 }
586 }
587 }
588
589 /**
590 * Counts order to be submitted.
591 *
592 * @return int
593 */
594 public function countOrdersToSubmit(): int {
595 return $this->countOrders( [ 'packetery_to_submit' => '1' ] );
596 }
597
598 /**
599 * Counts order to be printed.
600 *
601 * @return int
602 */
603 public function countOrdersToPrint(): int {
604 return $this->countOrders( [ 'packetery_to_print' => '1' ] );
605 }
606
607 /**
608 * Counts orders by given params.
609 *
610 * @param array $params Params.
611 *
612 * @return int
613 */
614 private function countOrders( array $params ): int {
615 $clauses = [ 'join' => '' ];
616
617 if ( Module\Helper::isHposEnabled() ) {
618 $clauses['select'] = ' SELECT COUNT(DISTINCT `' . $this->wpdbAdapter->wc_orders . '`.`id`) ';
619 $clauses['from'] = ' FROM `' . $this->wpdbAdapter->wc_orders . '` ';
620 } else {
621 $clauses['select'] = ' SELECT COUNT(DISTINCT `' . $this->wpdbAdapter->posts . '`.`ID`) ';
622 $clauses['from'] = ' FROM `' . $this->wpdbAdapter->posts . '` ';
623 }
624
625 $clauses['where'] = ' WHERE `' . $this->wpdbAdapter->packetery_order . '`.`id` IS NOT NULL ';
626 $clauses = $this->processClauses( $clauses, null, $params );
627
628 return (int) $this->wpdbAdapter->get_var(
629 $clauses['select'] .
630 $clauses['from'] .
631 $clauses['join'] .
632 $clauses['where']
633 );
634 }
635
636 /**
637 * Gets WC Order join clause.
638 *
639 * @return string
640 */
641 public function getWcOrderJoinClause(): string {
642 $packeteryTableAlias = 'o';
643
644 if ( Module\Helper::isHposEnabled() ) {
645 $sourceTableAlias = 'wc_o';
646 return sprintf(
647 'JOIN `%s` `%s` ON `%s`.`id` = `%s`.`id`',
648 $this->wpdbAdapter->wc_orders,
649 $sourceTableAlias,
650 $sourceTableAlias,
651 $packeteryTableAlias
652 );
653 }
654
655 $sourceTableAlias = 'wp_p';
656 return sprintf(
657 'JOIN `%s` `%s` ON `%s`.`ID` = `%s`.`id`',
658 $this->wpdbAdapter->posts,
659 $sourceTableAlias,
660 $sourceTableAlias,
661 $packeteryTableAlias
662 );
663 }
664
665 /**
666 * Deletes all custom table records linked to permanently deleted orders.
667 *
668 * @return void
669 */
670 public function deleteOrphans(): void {
671 if ( Module\Helper::isHposEnabled() ) {
672 $this->wpdbAdapter->query(
673 'DELETE `' . $this->wpdbAdapter->packetery_order . '` FROM `' . $this->wpdbAdapter->packetery_order . '`
674 LEFT JOIN `' . $this->wpdbAdapter->wc_orders . '` ON `' . $this->wpdbAdapter->wc_orders . '`.`id` = `' . $this->wpdbAdapter->packetery_order . '`.`id`
675 WHERE `' . $this->wpdbAdapter->wc_orders . '`.`id` IS NULL'
676 );
677 return;
678 }
679
680 $this->wpdbAdapter->query(
681 'DELETE `' . $this->wpdbAdapter->packetery_order . '` FROM `' . $this->wpdbAdapter->packetery_order . '`
682 LEFT JOIN `' . $this->wpdbAdapter->posts . '` ON `' . $this->wpdbAdapter->posts . '`.`ID` = `' . $this->wpdbAdapter->packetery_order . '`.`id`
683 WHERE `' . $this->wpdbAdapter->posts . '`.`ID` IS NULL'
684 );
685 }
686
687 /**
688 * Deletes data from custom table.
689 *
690 * @param int $orderId Order id.
691 *
692 * @return void
693 */
694 private function delete( int $orderId ): void {
695 $this->wpdbAdapter->delete( $this->wpdbAdapter->packetery_order, [ '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 if ( 'shop_order' === $post->post_type ) {
708 $this->delete( $postId );
709 }
710 }
711
712 /**
713 * Gets WC_Order object.
714 *
715 * @param int $id Order id.
716 *
717 * @return WC_Order|null
718 */
719 public function getWcOrderById( int $id ): ?WC_Order {
720 $result = wc_get_order( $id );
721 if ( $result instanceof WC_Order ) {
722 return $result;
723 }
724
725 return null;
726 }
727
728 }
729