PluginProbe
Packeta / 1.5.3
Packeta v1.5.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 / Plugin.php

Plugin.php in Packeta 1.5.3, at src/Packetery/Module/Plugin.php

989 lines 29.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Main Packeta plugin class.
4 *
5 * @package Packetery
6 */
7
8 declare( strict_types=1 );
9
10 namespace Packetery\Module;
11
12 use Packetery\Core\Log\ILogger;
13 use Packetery\Module\Carrier\OptionsPage;
14 use Packetery\Module\Log;
15 use Packetery\Module\Options;
16 use Packetery\Module\Order;
17 use Packetery\Module\Product;
18 use PacketeryLatte\Engine;
19 use PacketeryNette\Http\Request;
20 use PacketeryNette\Utils\Html;
21 use WC_Email;
22 use WC_Order;
23
24 /**
25 * Class Plugin
26 *
27 * @package Packetery
28 */
29 class Plugin {
30
31 public const VERSION = '1.5.3';
32 public const DOMAIN = 'packeta';
33 public const MIN_LISTENER_PRIORITY = - 9998;
34 public const PARAM_PACKETERY_ACTION = 'packetery_action';
35 public const PARAM_NONCE = '_wpnonce';
36
37 /**
38 * Options page.
39 *
40 * @var Options\Page Options page,
41 */
42 private $options_page;
43
44 /**
45 * PacketeryLatte engine.
46 *
47 * @var Engine
48 */
49 private $latte_engine;
50
51 /**
52 * Dashboard widget.
53 *
54 * @var DashboardWidget
55 */
56 private $dashboardWidget;
57
58 /**
59 * Country options page.
60 *
61 * @var OptionsPage
62 */
63 private $carrierOptionsPage;
64
65 /**
66 * Path to main plugin file.
67 *
68 * @var string Path to main plugin file.
69 */
70 private $main_file_path;
71
72 /**
73 * Admin edit order page Packeta metabox.
74 *
75 * @var Order\Metabox
76 */
77 private $order_metabox;
78
79 /**
80 * Message manager.
81 *
82 * @var MessageManager
83 */
84 private $message_manager;
85
86 /**
87 * Checkout object.
88 *
89 * @var Checkout
90 */
91 private $checkout;
92
93 /**
94 * Order BulkActions.
95 *
96 * @var Order\BulkActions
97 */
98 private $orderBulkActions;
99
100 /**
101 * Label printing.
102 *
103 * @var Order\LabelPrint
104 */
105 private $labelPrint;
106
107 /**
108 * Order collection printing.
109 *
110 * @var Order\CollectionPrint
111 */
112 private $orderCollectionPrint;
113
114 /**
115 * Order grid extender.
116 *
117 * @var Order\GridExtender
118 */
119 private $gridExtender;
120
121 /**
122 * Product tab.
123 *
124 * @var Product\DataTab
125 */
126 private $productTab;
127
128 /**
129 * Log page.
130 *
131 * @var Log\Page
132 */
133 private $logPage;
134
135 /**
136 * Log manager.
137 *
138 * @var ILogger
139 */
140 private $logger;
141
142 /**
143 * Cron service.
144 *
145 * @var CronService
146 */
147 private $cronService;
148
149 /**
150 * Order controller.
151 *
152 * @var Order\Controller
153 */
154 private $orderController;
155
156 /**
157 * Order modal.
158 *
159 * @var Order\Modal
160 */
161 private $orderModal;
162
163 /**
164 * Options exporter.
165 *
166 * @var Options\Exporter
167 */
168 private $exporter;
169
170 /**
171 * Request.
172 *
173 * @var Request
174 */
175 private $request;
176
177 /**
178 * Order repository.
179 *
180 * @var Order\Repository
181 */
182 private $orderRepository;
183
184 /**
185 * Plugin upgrade.
186 *
187 * @var Upgrade
188 */
189 private $upgrade;
190
191 /**
192 * QueryProcessor.
193 *
194 * @var QueryProcessor
195 */
196 private $queryProcessor;
197
198 /**
199 * Options provider.
200 *
201 * @var Options\Provider
202 */
203 private $optionsProvider;
204
205 /**
206 * Packet canceller.
207 *
208 * @var Order\PacketCanceller
209 */
210 private $packetCanceller;
211
212 /**
213 * Context resolver.
214 *
215 * @var ContextResolver
216 */
217 private $contextResolver;
218
219 /**
220 * Packet submitter
221 *
222 * @var Order\PacketSubmitter
223 */
224 private $packetSubmitter;
225
226 /**
227 * Category form fields.
228 *
229 * @var ProductCategory\FormFields
230 */
231 private $productCategoryFormFields;
232
233 /**
234 * Packet auto submitter.
235 *
236 * @var Order\PacketAutoSubmitter
237 */
238 private $packetAutoSubmitter;
239
240 /**
241 * Feature Flag Manager.
242 *
243 * @var Options\FeatureFlagManager
244 */
245 private $featureFlagManager;
246
247 /**
248 * Plugin constructor.
249 *
250 * @param Order\Metabox $order_metabox Order metabox.
251 * @param MessageManager $message_manager Message manager.
252 * @param Options\Page $options_page Options page.
253 * @param Checkout $checkout Checkout class.
254 * @param Engine $latte_engine PacketeryLatte engine.
255 * @param OptionsPage $carrierOptionsPage Carrier options page.
256 * @param Order\BulkActions $orderBulkActions Order BulkActions.
257 * @param Order\LabelPrint $labelPrint Label printing.
258 * @param Order\GridExtender $gridExtender Order grid extender.
259 * @param Product\DataTab $productTab Product tab.
260 * @param Log\Page $logPage Log page.
261 * @param ILogger $logger Log manager.
262 * @param Order\Controller $orderController Order controller.
263 * @param Order\Modal $orderModal Order modal.
264 * @param Options\Exporter $exporter Options exporter.
265 * @param Order\CollectionPrint $orderCollectionPrint Order collection print.
266 * @param Request $request HTTP request.
267 * @param Order\Repository $orderRepository Order repository.
268 * @param Upgrade $upgrade Plugin upgrade.
269 * @param QueryProcessor $queryProcessor QueryProcessor.
270 * @param Options\Provider $optionsProvider Options provider.
271 * @param CronService $cronService Cron service.
272 * @param Order\PacketCanceller $packetCanceller Packet canceller.
273 * @param ContextResolver $contextResolver Context resolver.
274 * @param DashboardWidget $dashboardWidget Dashboard widget.
275 * @param Order\PacketSubmitter $packetSubmitter Packet submitter.
276 * @param ProductCategory\FormFields $productCategoryFormFields Product category form fields.
277 * @param Order\PacketAutoSubmitter $packetAutoSubmitter Packet auto submitter.
278 * @param Options\FeatureFlagManager $featureFlagManager Feature Flag Manager.
279 */
280 public function __construct(
281 Order\Metabox $order_metabox,
282 MessageManager $message_manager,
283 Options\Page $options_page,
284 Checkout $checkout,
285 Engine $latte_engine,
286 OptionsPage $carrierOptionsPage,
287 Order\BulkActions $orderBulkActions,
288 Order\LabelPrint $labelPrint,
289 Order\GridExtender $gridExtender,
290 Product\DataTab $productTab,
291 Log\Page $logPage,
292 ILogger $logger,
293 Order\Controller $orderController,
294 Order\Modal $orderModal,
295 Options\Exporter $exporter,
296 Order\CollectionPrint $orderCollectionPrint,
297 Request $request,
298 Order\Repository $orderRepository,
299 Upgrade $upgrade,
300 QueryProcessor $queryProcessor,
301 Options\Provider $optionsProvider,
302 CronService $cronService,
303 Order\PacketCanceller $packetCanceller,
304 ContextResolver $contextResolver,
305 DashboardWidget $dashboardWidget,
306 Order\PacketSubmitter $packetSubmitter,
307 ProductCategory\FormFields $productCategoryFormFields,
308 Order\PacketAutoSubmitter $packetAutoSubmitter,
309 Options\FeatureFlagManager $featureFlagManager
310 ) {
311 $this->options_page = $options_page;
312 $this->latte_engine = $latte_engine;
313 $this->main_file_path = PACKETERY_PLUGIN_DIR . '/packeta.php';
314 $this->order_metabox = $order_metabox;
315 $this->message_manager = $message_manager;
316 $this->checkout = $checkout;
317 $this->carrierOptionsPage = $carrierOptionsPage;
318 $this->orderBulkActions = $orderBulkActions;
319 $this->labelPrint = $labelPrint;
320 $this->gridExtender = $gridExtender;
321 $this->productTab = $productTab;
322 $this->logPage = $logPage;
323 $this->logger = $logger;
324 $this->orderController = $orderController;
325 $this->orderModal = $orderModal;
326 $this->exporter = $exporter;
327 $this->orderCollectionPrint = $orderCollectionPrint;
328 $this->request = $request;
329 $this->orderRepository = $orderRepository;
330 $this->upgrade = $upgrade;
331 $this->queryProcessor = $queryProcessor;
332 $this->optionsProvider = $optionsProvider;
333 $this->cronService = $cronService;
334 $this->packetCanceller = $packetCanceller;
335 $this->contextResolver = $contextResolver;
336 $this->dashboardWidget = $dashboardWidget;
337 $this->packetSubmitter = $packetSubmitter;
338 $this->productCategoryFormFields = $productCategoryFormFields;
339 $this->packetAutoSubmitter = $packetAutoSubmitter;
340 $this->featureFlagManager = $featureFlagManager;
341 }
342
343 /**
344 * Method to register hooks
345 */
346 public function run(): void {
347 add_action( 'init', [ $this, 'loadTranslation' ] );
348
349 if ( ! self::isWooCommercePluginActive() ) {
350 add_action( 'admin_notices', [ $this, 'echoInactiveWooCommerceNotice' ] );
351
352 return;
353 }
354
355 add_action( 'init', [ $this->upgrade, 'check' ] );
356 add_action( 'init', [ $this->logger, 'register' ] );
357 add_action( 'init', [ $this->message_manager, 'init' ] );
358 add_action( 'rest_api_init', [ $this->orderController, 'registerRoutes' ] );
359
360 add_action( 'admin_enqueue_scripts', array( $this, 'enqueueAdminAssets' ) );
361 add_action( 'wp_enqueue_scripts', [ $this, 'enqueueFrontAssets' ] );
362
363 add_action(
364 'admin_notices',
365 function () {
366 $this->message_manager->render( MessageManager::RENDERER_WORDPRESS );
367 },
368 self::MIN_LISTENER_PRIORITY
369 );
370 add_action( 'init', array( $this, 'init' ) );
371
372 // TODO: deactivation_hook.
373 register_deactivation_hook(
374 $this->main_file_path,
375 static function () {
376 CronService::deactivate();
377 }
378 );
379
380 register_uninstall_hook( $this->main_file_path, array( __CLASS__, 'uninstall' ) );
381
382 add_action( 'woocommerce_email_footer', [ $this, 'renderEmailFooter' ] );
383 add_filter( 'woocommerce_shipping_methods', array( $this, 'add_shipping_method' ) );
384
385 add_filter( 'views_edit-shop_order', [ $this->gridExtender, 'addFilterLinks' ] );
386 add_action( 'restrict_manage_posts', [ $this->gridExtender, 'renderOrderTypeSelect' ] );
387 $this->queryProcessor->register();
388
389 add_filter( 'manage_edit-shop_order_columns', [ $this->gridExtender, 'addOrderListColumns' ] );
390 add_action( 'manage_shop_order_posts_custom_column', [ $this->gridExtender, 'fillCustomOrderListColumns' ] );
391
392 add_filter( 'woocommerce_order_data_store_cpt_get_orders_query', [ $this->upgrade, 'handleCustomQueryVar' ], 10, 2 );
393
394 add_action( 'admin_menu', array( $this, 'add_menu_pages' ) );
395 add_action( 'admin_head', array( $this->labelPrint, 'hideFromMenus' ) );
396 add_action( 'admin_head', array( $this->orderCollectionPrint, 'hideFromMenus' ) );
397 add_action( 'admin_head', [ $this, 'renderConfirmModalTemplate' ] );
398 $this->orderModal->register();
399 $this->order_metabox->register();
400
401 $this->checkout->register_hooks();
402 $this->productTab->register();
403 $this->cronService->register();
404 $this->productCategoryFormFields->register();
405 $this->packetAutoSubmitter->register();
406
407 add_action( 'woocommerce_admin_order_data_after_shipping_address', [ $this, 'renderDeliveryDetail' ] );
408 add_action( 'woocommerce_order_details_after_order_table', [ $this, 'renderOrderDetail' ] );
409
410 // Adding custom actions to dropdown in admin order list.
411 add_filter( 'bulk_actions-edit-shop_order', [ $this->orderBulkActions, 'addActions' ], 20, 1 );
412 // Execute the action for selected orders.
413 add_filter(
414 'handle_bulk_actions-edit-shop_order',
415 [
416 $this->orderBulkActions,
417 'handleActions',
418 ],
419 10,
420 3
421 );
422 // Print packets export result.
423 add_action( 'admin_notices', [ $this->orderBulkActions, 'renderPacketsExportResult' ], self::MIN_LISTENER_PRIORITY );
424
425 add_action( 'admin_init', [ $this->labelPrint, 'outputLabelsPdf' ] );
426 add_action( 'admin_init', [ $this->orderCollectionPrint, 'print' ] );
427
428 add_action( 'admin_init', [ $this->exporter, 'outputExportTxt' ] );
429 add_action( 'admin_init', [ $this, 'handleActions' ] );
430 add_filter( 'woocommerce_order_data_store_cpt_get_orders_query', [ $this, 'transformGetOrdersQuery' ] );
431
432 add_action( 'deleted_post', [ $this->orderRepository, 'deletedPostHook' ], 10, 2 );
433 $this->dashboardWidget->register();
434 }
435
436 /**
437 * Print inactive WooCommerce notice.
438 *
439 * @return void
440 */
441 public function echoInactiveWooCommerceNotice(): void {
442 if ( self::isWooCommercePluginActive() ) {
443 // When Packeta plugin is active and WooCommerce plugin is inactive.
444 // If user decides to activate WooCommerce plugin then invalid notice will not be rendered.
445 // Packeta plugin probably bootstraps twice in such case.
446 return;
447 }
448
449 $this->latte_engine->render(
450 PACKETERY_PLUGIN_DIR . '/template/admin-notice.latte',
451 [
452 'message' => [
453 'type' => 'error',
454 'message' => __( 'Packeta plugin requires WooCommerce. Please install and activate it first.', 'packeta' ),
455 ],
456 ]
457 );
458 }
459
460 /**
461 * Is WC plugin active.
462 *
463 * @return bool
464 */
465 private static function isWooCommercePluginActive(): bool {
466 return Helper::isPluginActive( 'woocommerce/woocommerce.php' );
467 }
468
469 /**
470 * Creates HTML link parts in array.
471 *
472 * @param string $href Href.
473 * @param string|null $target Target.
474 * @param string|null $class Class.
475 *
476 * @return string[]
477 */
478 public static function createLinkParts( string $href, ?string $target = null, ?string $class = null ): array {
479 $link = Html::el( 'a' )->href( $href );
480
481 if ( null !== $target ) {
482 $link->target( $target );
483 }
484
485 if ( null !== $class ) {
486 $link->class( $class );
487 }
488
489 return [ $link->startTag(), $link->endTag() ];
490 }
491
492 /**
493 * Filter queries.
494 *
495 * @param array $query Query.
496 *
497 * @return array
498 */
499 public function transformGetOrdersQuery( array $query ): array {
500 if ( ! empty( $query['packetery_meta_query'] ) ) {
501 // @codingStandardsIgnoreStart
502 $query['meta_query'] = $query['packetery_meta_query'];
503 // @codingStandardsIgnoreEnd
504 }
505
506 return $query;
507 }
508
509 /**
510 * Renders delivery detail for packetery orders.
511 *
512 * @param WC_Order $order WordPress order.
513 */
514 public function renderDeliveryDetail( WC_Order $order ): void {
515 $orderEntity = $this->orderRepository->getByWcOrder( $order );
516 if ( null === $orderEntity ) {
517 return;
518 }
519
520 $carrierId = $orderEntity->getCarrierId();
521 $carrierOptions = Carrier\Options::createByCarrierId( $carrierId );
522
523 $this->latte_engine->render(
524 PACKETERY_PLUGIN_DIR . '/template/order/delivery-detail.latte',
525 [
526 'pickupPoint' => $orderEntity->getPickupPoint(),
527 'validatedDeliveryAddress' => $orderEntity->getValidatedDeliveryAddress(),
528 'carrierAddressValidation' => $carrierOptions->getAddressValidation(),
529 'isExternalCarrier' => $orderEntity->isExternalCarrier(),
530 'translations' => [
531 'packeta' => __( 'Packeta', 'packeta' ),
532 'pickupPointDetail' => __( 'Pickup Point Detail', 'packeta' ),
533 'name' => __( 'Name', 'packeta' ),
534 'address' => __( 'Address', 'packeta' ),
535 'pickupPointDetailCaps' => __( 'Pickup Point Detail', 'packeta' ),
536 'addressWasNotValidated' => __( 'Address was not validated', 'packeta' ),
537 'validatedAddress' => __( 'Validated address', 'packeta' ),
538 'street' => __( 'Street', 'packeta' ),
539 'houseNumber' => __( 'House number', 'packeta' ),
540 'city' => __( 'City', 'packeta' ),
541 'zip' => __( 'Zip', 'packeta' ),
542 'county' => __( 'County', 'packeta' ),
543 'gps' => __( 'GPS', 'packeta' ),
544 ],
545 ]
546 );
547 }
548
549 /**
550 * Renders delivery detail for packetery orders, on "thank you" page and in frontend detail.
551 *
552 * @param WC_Order $wcOrder WordPress order.
553 */
554 public function renderOrderDetail( WC_Order $wcOrder ): void {
555 $order = $this->orderRepository->getById( $wcOrder->get_id() );
556 if ( null === $order ) {
557 return;
558 }
559
560 $pickupPoint = $order->getPickupPoint();
561 $validatedDeliveryAddress = $order->getValidatedDeliveryAddress();
562 if ( null === $pickupPoint && null === $validatedDeliveryAddress ) {
563 return;
564 }
565
566 $this->latte_engine->render(
567 PACKETERY_PLUGIN_DIR . '/template/order/detail.latte',
568 [
569 'displayPickupPointInfo' => $this->shouldDisplayPickupPointInfo(),
570 'pickupPoint' => $pickupPoint,
571 'validatedDeliveryAddress' => $validatedDeliveryAddress,
572 'isExternalCarrier' => $order->isExternalCarrier(),
573 'translations' => [
574 'packeta' => __( 'Packeta', 'packeta' ),
575 'selectedPickupPoint' => __( 'Selected pickup point', 'packeta' ),
576 'pickupPointName' => __( 'Pickup Point Name', 'packeta' ),
577 'pickupPointDetail' => __( 'Pickup Point Detail', 'packeta' ),
578 'validatedAddress' => __( 'Validated address', 'packeta' ),
579 'address' => __( 'Address', 'packeta' ),
580 ],
581 ]
582 );
583 }
584
585 /**
586 * Renders email footer.
587 *
588 * @param mixed $email Email data.
589 */
590 public function renderEmailFooter( $email ): void {
591 if ( ! $email instanceof WC_Email || ! $email->object instanceof WC_Order ) {
592 return;
593 }
594
595 $packeteryOrder = $this->orderRepository->getByWcOrder( $email->object );
596 if ( null === $packeteryOrder ) {
597 return;
598 }
599
600 $pickupPoint = $packeteryOrder->getPickupPoint();
601 $validatedDeliveryAddress = $packeteryOrder->getValidatedDeliveryAddress();
602
603 $templateParams = [
604 'displayPickupPointInfo' => $this->shouldDisplayPickupPointInfo(),
605 'pickupPoint' => $pickupPoint,
606 'validatedDeliveryAddress' => $validatedDeliveryAddress,
607 'isExternalCarrier' => $packeteryOrder->isExternalCarrier(),
608 'translations' => [
609 'packeta' => __( 'Packeta', 'packeta' ),
610 'pickupPointDetail' => __( 'Pickup Point Detail', 'packeta' ),
611 'pickupPointName' => __( 'Pickup Point Name', 'packeta' ),
612 'link' => __( 'Link', 'packeta' ),
613 'pickupPointAddress' => __( 'Pickup Point Address', 'packeta' ),
614 'validatedDeliveryAddress' => __( 'validated delivery address', 'packeta' ),
615 'street' => __( 'Street', 'packeta' ),
616 'houseNumber' => __( 'House number', 'packeta' ),
617 'city' => __( 'City', 'packeta' ),
618 'zip' => __( 'Zip', 'packeta' ),
619 'county' => __( 'County', 'packeta' ),
620 ],
621 ];
622 $emailFooterHtml = $this->latte_engine->renderToString(
623 PACKETERY_PLUGIN_DIR . '/template/email/footer.latte',
624 $templateParams
625 );
626 /**
627 * This filter allows you to change the HTML of e-mail footer.
628 *
629 * @since 1.5.3
630 */
631 Helper::renderString( (string) apply_filters( 'packeta_email_footer', $emailFooterHtml, $templateParams ) );
632 }
633
634 /**
635 * Tells if pickup point info should be displayed.
636 *
637 * @return bool
638 */
639 public function shouldDisplayPickupPointInfo(): bool {
640 return ! $this->optionsProvider->replaceShippingAddressWithPickupPointAddress() || wc_ship_to_billing_address_only();
641 }
642
643 /**
644 * Renders confirm modal template.
645 */
646 public function renderConfirmModalTemplate(): void {
647 if ( $this->contextResolver->isPacketeryConfirmPage() ) {
648 $this->latte_engine->render(
649 PACKETERY_PLUGIN_DIR . '/template/confirm-modal-template.latte',
650 [
651 'translations' => [
652 'closeModalPanel' => __( 'Close modal panel', 'packeta' ),
653 'no' => __( 'No', 'packeta' ),
654 'yes' => __( 'Yes', 'packeta' ),
655 ],
656 ]
657 );
658 }
659 }
660
661 /**
662 * Enqueues admin JS file.
663 *
664 * @param string $name Name of script.
665 * @param string $file Relative file path.
666 * @param bool $inFooter Tells where to include script.
667 * @param array $deps Script dependencies.
668 */
669 private function enqueueScript( string $name, string $file, bool $inFooter, array $deps = [] ): void {
670 wp_enqueue_script(
671 $name,
672 plugin_dir_url( $this->main_file_path ) . $file,
673 $deps,
674 md5( (string) filemtime( PACKETERY_PLUGIN_DIR . '/' . $file ) ),
675 $inFooter
676 );
677 }
678
679 /**
680 * Enqueues CSS file.
681 *
682 * @param string $name Name of script.
683 * @param string $file Relative file path.
684 */
685 private function enqueueStyle( string $name, string $file ): void {
686 wp_enqueue_style(
687 $name,
688 plugin_dir_url( $this->main_file_path ) . $file,
689 [],
690 md5( (string) filemtime( PACKETERY_PLUGIN_DIR . '/' . $file ) )
691 );
692 }
693
694 /**
695 * Builds asset URL.
696 *
697 * @param string $asset Relative asset path without leading slash.
698 *
699 * @return string|null
700 */
701 public static function buildAssetUrl( string $asset ): ?string {
702 $url = plugin_dir_url( PACKETERY_PLUGIN_DIR . '/packeta.php' ) . $asset;
703 $filename = PACKETERY_PLUGIN_DIR . '/' . $asset;
704
705 if ( ! file_exists( $filename ) ) {
706 return null;
707 }
708
709 return add_query_arg( [ 'v' => md5( (string) filemtime( $filename ) ) ], $url );
710 }
711
712 /**
713 * Enqueues javascript files and stylesheets for checkout.
714 */
715 public function enqueueFrontAssets(): void {
716 if ( is_checkout() ) {
717 $this->enqueueStyle( 'packetery-front-styles', 'public/front.css' );
718 $this->enqueueStyle( 'packetery-custom-front-styles', 'public/custom-front.css' );
719 $this->enqueueScript( 'packetery-checkout', 'public/checkout.js', true, [ 'jquery' ] );
720 wp_localize_script( 'packetery-checkout', 'packeteryCheckoutSettings', $this->checkout->createSettings() );
721 }
722 }
723
724 /**
725 * Enqueues javascript files and stylesheets for administration.
726 */
727 public function enqueueAdminAssets(): void {
728 $page = $this->request->getQuery( 'page' );
729 $isOrderGridPage = $this->contextResolver->isOrderGridPage();
730 $isOrderDetailPage = $this->contextResolver->isOrderDetailPage();
731 $isProductCategoryPage = $this->contextResolver->isProductCategoryDetailPage() || $this->contextResolver->isProductCategoryGridPage();
732 $datePickerSettings = [
733 'deliverOnMinDate' => wp_date( \Packetery\Core\Helper::DATEPICKER_FORMAT, strtotime( 'tomorrow' ) ),
734 ];
735
736 if ( $isOrderGridPage || $isOrderDetailPage || in_array( $page, [ Carrier\OptionsPage::SLUG, Options\Page::SLUG ], true ) ) {
737 $this->enqueueScript( 'live-form-validation-options', 'public/live-form-validation-options.js', false );
738 $this->enqueueScript( 'live-form-validation', 'public/libs/live-form-validation/live-form-validation.js', false, [ 'live-form-validation-options' ] );
739 $this->enqueueScript( 'live-form-validation-extension', 'public/live-form-validation-extension.js', false, [ 'live-form-validation' ] );
740 }
741
742 if ( Carrier\OptionsPage::SLUG === $page ) {
743 $this->enqueueScript( 'packetery-admin-country-carrier', 'public/admin-country-carrier.js', true, [ 'jquery' ] );
744 }
745
746 $isProductPage = $this->contextResolver->isProductPage();
747 $screen = get_current_screen();
748 $isDashboard = ( $screen && 'dashboard' === $screen->id );
749
750 if (
751 $isOrderGridPage || $isOrderDetailPage || $isProductPage || $isProductCategoryPage || $isDashboard ||
752 in_array(
753 $page,
754 [
755 Options\Page::SLUG,
756 Carrier\OptionsPage::SLUG,
757 Log\Page::SLUG,
758 Order\labelPrint::MENU_SLUG,
759 ],
760 true
761 )
762 ) {
763 $this->enqueueStyle( 'packetery-admin-styles', 'public/admin.css' );
764 // We want to trigger the message on all pages and show it on first request.
765 $this->featureFlagManager->isSplitActive();
766 // It is placed here so that typenow in contextResolver works and there is no need to repeat the conditions.
767 if ( $this->featureFlagManager->hasSplitActivationNotice() ) {
768 add_action( 'admin_notices', [ $this->featureFlagManager, 'renderSplitActivationNotice' ] );
769 }
770 }
771
772 if ( $isOrderGridPage ) {
773 $this->enqueueScript( 'packetery-admin-grid-order-edit-js', 'public/admin-grid-order-edit.js', true, [ 'jquery', 'wp-util', 'backbone' ] );
774 wp_localize_script( 'packetery-admin-grid-order-edit-js', 'datePickerSettings', $datePickerSettings );
775 }
776
777 $pickupPointPickerSettings = null;
778 $addressPickerSettings = null;
779
780 if ( $isOrderDetailPage ) {
781 $this->enqueueScript( 'admin-order-detail', 'public/admin-order-detail.js', true, [ 'jquery' ] );
782 wp_localize_script( 'admin-order-detail', 'datePickerSettings', $datePickerSettings );
783 $pickupPointPickerSettings = $this->order_metabox->getPickupPointWidgetSettings();
784 $addressPickerSettings = $this->order_metabox->getAddressWidgetSettings();
785 }
786
787 if ( null !== $pickupPointPickerSettings || null !== $addressPickerSettings ) {
788 wp_enqueue_script( 'packetery-widget-library', 'https://widget.packeta.com/v6/www/js/library.js', [], self::VERSION, true );
789 }
790
791 if ( null !== $pickupPointPickerSettings ) {
792 $this->enqueueScript( 'packetery-admin-pickup-point-picker', 'public/admin-pickup-point-picker.js', true, [ 'jquery', 'packetery-widget-library' ] );
793 wp_localize_script( 'packetery-admin-pickup-point-picker', 'packeteryPickupPointPickerSettings', $pickupPointPickerSettings );
794 }
795
796 if ( null !== $addressPickerSettings ) {
797 $this->enqueueScript( 'packetery-admin-address-picker', 'public/admin-address-picker.js', true, [ 'jquery', 'packetery-widget-library' ] );
798 wp_localize_script( 'packetery-admin-address-picker', 'packeteryAddressPickerSettings', $addressPickerSettings );
799 }
800
801 if ( $this->contextResolver->isPacketeryConfirmPage() ) {
802 $this->enqueueScript( 'packetery-confirm', 'public/confirm.js', true, [ 'jquery', 'backbone' ] );
803 }
804 }
805
806 /**
807 * Add links to left admin menu.
808 */
809 public function add_menu_pages(): void {
810 $this->options_page->register();
811 $this->carrierOptionsPage->register();
812 $this->labelPrint->register();
813 $this->orderCollectionPrint->register();
814 $this->logPage->register();
815 }
816
817 /**
818 * Gets current locale.
819 */
820 public static function getLocale(): string {
821 /**
822 * Applies plugin_locale filters.
823 *
824 * @since 1.0.0
825 */
826 return (string) apply_filters(
827 'plugin_locale',
828 ( is_admin() ? get_user_locale() : get_locale() ),
829 self::DOMAIN
830 );
831 }
832
833 /**
834 * Loads plugin translation file by user locale.
835 */
836 public function loadTranslation(): void {
837 $domain = self::DOMAIN;
838 $locale = self::getLocale();
839
840 $moFile = PACKETERY_PLUGIN_DIR . "/languages/$domain-$locale.mo";
841 $result = load_textdomain( $domain, $moFile );
842
843 if ( false === $result ) {
844 $moFile = PACKETERY_PLUGIN_DIR . "/languages/$domain-en_US.mo";
845 load_textdomain( $domain, $moFile );
846 }
847 }
848
849 /**
850 * Inits plugin.
851 */
852 public function init(): void {
853 add_filter(
854 'plugin_action_links_' . plugin_basename( $this->main_file_path ),
855 [
856 $this,
857 'addPluginActionLinks',
858 ]
859 );
860 add_filter( 'plugin_row_meta', [ $this, 'addPluginRowMeta' ], 10, 2 );
861 }
862
863 /**
864 * Uninstalls plugin and drops custom database table.
865 * Only a static class method or function can be used in an uninstall hook.
866 */
867 public static function uninstall(): void {
868 if ( defined( 'PACKETERY_DEBUG' ) && PACKETERY_DEBUG === true ) {
869 return;
870 }
871
872 $container = require PACKETERY_PLUGIN_DIR . '/bootstrap.php';
873
874 $optionsRepository = $container->getByType( Options\Repository::class );
875 $pluginOptions = $optionsRepository->getPluginOptions();
876 foreach ( $pluginOptions as $option ) {
877 delete_option( $option->option_name );
878 }
879
880 $logRepository = $container->getByType( Log\Repository::class );
881 $logRepository->drop();
882
883 $carrierRepository = $container->getByType( Carrier\Repository::class );
884 $carrierRepository->drop();
885
886 $orderRepository = $container->getByType( Order\Repository::class );
887 $orderRepository->drop();
888 }
889
890 /**
891 * Adds action links visible at the plugin screen.
892 *
893 * @link https://developer.wordpress.org/reference/hooks/plugin_action_links_plugin_file/
894 *
895 * @param array $links Plugin Action links.
896 *
897 * @return array
898 */
899 public function addPluginActionLinks( array $links ): array {
900 $settingsLink = '<a href="' . esc_url( admin_url( 'admin.php?page=' . Options\Page::SLUG ) ) . '" aria-label="' .
901 esc_attr__( 'View the plugin documentation', 'packeta' ) . '">' .
902 esc_html__( 'Settings', 'packeta' ) . '</a>';
903
904 array_unshift( $links, $settingsLink );
905
906 return $links;
907 }
908
909 /**
910 * Show row meta on the plugin screen.
911 *
912 * @link https://developer.wordpress.org/reference/hooks/plugin_row_meta/
913 *
914 * @param array $links Plugin Row Meta.
915 * @param string $pluginFileName Plugin Base file.
916 *
917 * @return array
918 */
919 public function addPluginRowMeta( array $links, string $pluginFileName ): array {
920 if ( ! strpos( $pluginFileName, basename( $this->main_file_path ) ) ) {
921 return $links;
922 }
923 $links[] = '<a href="' . esc_url( 'https://github.com/Zasilkovna/WooCommerce/wiki' ) . '" aria-label="' .
924 esc_attr__( 'View Packeta documentation', 'packeta' ) . '">' .
925 esc_html__( 'Documentation', 'packeta' ) . '</a>';
926
927 return $links;
928 }
929
930 /**
931 * Adds Packeta method to available shipping methods.
932 *
933 * @param array $methods Previous state.
934 *
935 * @return array
936 */
937 public function add_shipping_method( array $methods ): array {
938 $methods[ ShippingMethod::PACKETERY_METHOD_ID ] = ShippingMethod::class;
939
940 return $methods;
941 }
942
943 /**
944 * Hides submenu item. Must not be called too early.
945 *
946 * @param string $itemSlug Item slug.
947 */
948 public static function hideSubmenuItem( string $itemSlug ): void {
949 global $submenu;
950 if ( isset( $submenu[ Options\Page::SLUG ] ) ) {
951 foreach ( $submenu[ Options\Page::SLUG ] as $key => $menu ) {
952 if ( $itemSlug === $menu[2] ) {
953 unset( $submenu[ Options\Page::SLUG ][ $key ] );
954 }
955 }
956 }
957 }
958
959 /**
960 * Gets software identity for Packeta APIs.
961 *
962 * @return string
963 */
964 public static function getAppIdentity(): string {
965 return 'WordPress-' . get_bloginfo( 'version' ) . '-Woocommerce-' . WC_VERSION . '-Packeta-' . self::VERSION;
966 }
967
968 /**
969 * Check for action parameter and process wanted action.
970 *
971 * @return void
972 */
973 public function handleActions(): void {
974 $action = $this->request->getQuery( self::PARAM_PACKETERY_ACTION );
975
976 if ( Order\PacketActionsCommonLogic::ACTION_SUBMIT_PACKET === $action ) {
977 $this->packetSubmitter->processAction();
978 }
979
980 if ( Order\PacketActionsCommonLogic::ACTION_CANCEL_PACKET === $action ) {
981 $this->packetCanceller->processAction();
982 }
983
984 if ( Options\FeatureFlagManager::ACTION_HIDE_SPLIT_MESSAGE === $action ) {
985 $this->featureFlagManager->dismissSplitActivationNotice();
986 }
987 }
988 }
989