PluginProbe
Packeta / 1.4.2
Packeta v1.4.2
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.4.2, at src/Packetery/Module/Plugin.php

873 lines 24.9 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.4.1';
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 * Plugin constructor.
221 *
222 * @param Order\Metabox $order_metabox Order metabox.
223 * @param MessageManager $message_manager Message manager.
224 * @param Options\Page $options_page Options page.
225 * @param Checkout $checkout Checkout class.
226 * @param Engine $latte_engine PacketeryLatte engine.
227 * @param OptionsPage $carrierOptionsPage Carrier options page.
228 * @param Order\BulkActions $orderBulkActions Order BulkActions.
229 * @param Order\LabelPrint $labelPrint Label printing.
230 * @param Order\GridExtender $gridExtender Order grid extender.
231 * @param Product\DataTab $productTab Product tab.
232 * @param Log\Page $logPage Log page.
233 * @param ILogger $logger Log manager.
234 * @param Order\Controller $orderController Order controller.
235 * @param Order\Modal $orderModal Order modal.
236 * @param Options\Exporter $exporter Options exporter.
237 * @param Order\CollectionPrint $orderCollectionPrint Order collection print.
238 * @param Request $request HTTP request.
239 * @param Order\Repository $orderRepository Order repository.
240 * @param Upgrade $upgrade Plugin upgrade.
241 * @param QueryProcessor $queryProcessor QueryProcessor.
242 * @param Options\Provider $optionsProvider Options provider.
243 * @param CronService $cronService Cron service.
244 * @param Order\PacketCanceller $packetCanceller Packet canceller.
245 * @param ContextResolver $contextResolver Context resolver.
246 * @param DashboardWidget $dashboardWidget Dashboard widget.
247 */
248 public function __construct(
249 Order\Metabox $order_metabox,
250 MessageManager $message_manager,
251 Options\Page $options_page,
252 Checkout $checkout,
253 Engine $latte_engine,
254 OptionsPage $carrierOptionsPage,
255 Order\BulkActions $orderBulkActions,
256 Order\LabelPrint $labelPrint,
257 Order\GridExtender $gridExtender,
258 Product\DataTab $productTab,
259 Log\Page $logPage,
260 ILogger $logger,
261 Order\Controller $orderController,
262 Order\Modal $orderModal,
263 Options\Exporter $exporter,
264 Order\CollectionPrint $orderCollectionPrint,
265 Request $request,
266 Order\Repository $orderRepository,
267 Upgrade $upgrade,
268 QueryProcessor $queryProcessor,
269 Options\Provider $optionsProvider,
270 CronService $cronService,
271 Order\PacketCanceller $packetCanceller,
272 ContextResolver $contextResolver,
273 DashboardWidget $dashboardWidget
274 ) {
275 $this->options_page = $options_page;
276 $this->latte_engine = $latte_engine;
277 $this->main_file_path = PACKETERY_PLUGIN_DIR . '/packeta.php';
278 $this->order_metabox = $order_metabox;
279 $this->message_manager = $message_manager;
280 $this->checkout = $checkout;
281 $this->carrierOptionsPage = $carrierOptionsPage;
282 $this->orderBulkActions = $orderBulkActions;
283 $this->labelPrint = $labelPrint;
284 $this->gridExtender = $gridExtender;
285 $this->productTab = $productTab;
286 $this->logPage = $logPage;
287 $this->logger = $logger;
288 $this->orderController = $orderController;
289 $this->orderModal = $orderModal;
290 $this->exporter = $exporter;
291 $this->orderCollectionPrint = $orderCollectionPrint;
292 $this->request = $request;
293 $this->orderRepository = $orderRepository;
294 $this->upgrade = $upgrade;
295 $this->queryProcessor = $queryProcessor;
296 $this->optionsProvider = $optionsProvider;
297 $this->cronService = $cronService;
298 $this->packetCanceller = $packetCanceller;
299 $this->contextResolver = $contextResolver;
300 $this->dashboardWidget = $dashboardWidget;
301 }
302
303 /**
304 * Method to register hooks
305 */
306 public function run(): void {
307 add_action( 'init', [ $this, 'loadTranslation' ] );
308
309 if ( ! self::isWooCommercePluginActive() ) {
310 add_action( 'admin_notices', [ $this, 'echoInactiveWooCommerceNotice' ] );
311
312 return;
313 }
314
315 add_action( 'init', [ $this->upgrade, 'check' ] );
316 add_action( 'init', [ $this->logger, 'register' ] );
317 add_action( 'init', [ $this->message_manager, 'init' ] );
318 add_action( 'rest_api_init', [ $this->orderController, 'registerRoutes' ] );
319
320 add_action( 'admin_enqueue_scripts', array( $this, 'enqueueAdminAssets' ) );
321 add_action( 'wp_enqueue_scripts', [ $this, 'enqueueFrontAssets' ] );
322
323 add_action(
324 'admin_notices',
325 function () {
326 $this->message_manager->render( MessageManager::RENDERER_WORDPRESS );
327 },
328 self::MIN_LISTENER_PRIORITY
329 );
330 add_action( 'init', array( $this, 'init' ) );
331
332 // TODO: deactivation_hook.
333 register_deactivation_hook(
334 $this->main_file_path,
335 static function () {
336 CronService::deactivate();
337 }
338 );
339
340 register_uninstall_hook( $this->main_file_path, array( __CLASS__, 'uninstall' ) );
341
342 add_action( 'woocommerce_email_footer', [ $this, 'renderEmailFooter' ] );
343 add_filter( 'woocommerce_shipping_methods', array( $this, 'add_shipping_method' ) );
344
345 add_filter( 'views_edit-shop_order', [ $this->gridExtender, 'addFilterLinks' ] );
346 add_action( 'restrict_manage_posts', [ $this->gridExtender, 'renderOrderTypeSelect' ] );
347 $this->queryProcessor->register();
348
349 add_filter( 'manage_edit-shop_order_columns', [ $this->gridExtender, 'addOrderListColumns' ] );
350 add_action( 'manage_shop_order_posts_custom_column', [ $this->gridExtender, 'fillCustomOrderListColumns' ] );
351
352 add_filter( 'woocommerce_order_data_store_cpt_get_orders_query', [ $this->upgrade, 'handleCustomQueryVar' ], 10, 2 );
353
354 add_action( 'admin_menu', array( $this, 'add_menu_pages' ) );
355 add_action( 'admin_head', array( $this->labelPrint, 'hideFromMenus' ) );
356 add_action( 'admin_head', array( $this->orderCollectionPrint, 'hideFromMenus' ) );
357 add_action( 'admin_head', [ $this, 'renderConfirmModalTemplate' ] );
358 $this->orderModal->register();
359 $this->order_metabox->register();
360
361 $this->checkout->register_hooks();
362 $this->productTab->register();
363 $this->cronService->register();
364
365 add_action( 'woocommerce_admin_order_data_after_shipping_address', [ $this, 'renderDeliveryDetail' ] );
366 add_action( 'woocommerce_order_details_after_order_table', [ $this, 'renderOrderDetail' ] );
367
368 // Adding custom actions to dropdown in admin order list.
369 add_filter( 'bulk_actions-edit-shop_order', [ $this->orderBulkActions, 'addActions' ], 20, 1 );
370 // Execute the action for selected orders.
371 add_filter(
372 'handle_bulk_actions-edit-shop_order',
373 [
374 $this->orderBulkActions,
375 'handleActions',
376 ],
377 10,
378 3
379 );
380 // Print packets export result.
381 add_action( 'admin_notices', [ $this->orderBulkActions, 'renderPacketsExportResult' ], self::MIN_LISTENER_PRIORITY );
382
383 add_action( 'admin_init', [ $this->labelPrint, 'outputLabelsPdf' ] );
384 add_action( 'admin_init', [ $this->orderCollectionPrint, 'print' ] );
385
386 add_action( 'admin_init', [ $this->exporter, 'outputExportTxt' ] );
387 add_action( 'admin_init', [ $this->packetCanceller, 'processActions' ] );
388 add_filter( 'woocommerce_order_data_store_cpt_get_orders_query', [ $this, 'transformGetOrdersQuery' ] );
389
390 add_action( 'deleted_post', [ $this->orderRepository, 'deletedPostHook' ], 10, 2 );
391 $this->dashboardWidget->register();
392 }
393
394 /**
395 * Print inactive WooCommerce notice.
396 *
397 * @return void
398 */
399 public function echoInactiveWooCommerceNotice(): void {
400 if ( self::isWooCommercePluginActive() ) {
401 // When Packeta plugin is active and WooCommerce plugin is inactive.
402 // If user decides to activate WooCommerce plugin then invalid notice will not be rendered.
403 // Packeta plugin probably bootstraps twice in such case.
404 return;
405 }
406
407 $this->latte_engine->render(
408 PACKETERY_PLUGIN_DIR . '/template/admin-notice.latte',
409 [
410 'message' => [
411 'type' => 'error',
412 'message' => __( 'Packeta plugin requires WooCommerce. Please install and activate it first.', 'packeta' ),
413 ],
414 ]
415 );
416 }
417
418 /**
419 * Is WC plugin active.
420 *
421 * @return bool
422 */
423 private static function isWooCommercePluginActive(): bool {
424 return Helper::isPluginActive( 'woocommerce/woocommerce.php' );
425 }
426
427 /**
428 * Creates HTML link parts in array.
429 *
430 * @param string $href Href.
431 *
432 * @return string[]
433 */
434 public static function createLinkParts( string $href ): array {
435 $link = Html::el( 'a' )->href( $href );
436 return [ $link->startTag(), $link->endTag() ];
437 }
438
439 /**
440 * Filter queries.
441 *
442 * @param array $query Query.
443 *
444 * @return array
445 */
446 public function transformGetOrdersQuery( array $query ): array {
447 if ( ! empty( $query['packetery_meta_query'] ) ) {
448 // @codingStandardsIgnoreStart
449 $query['meta_query'] = $query['packetery_meta_query'];
450 // @codingStandardsIgnoreEnd
451 }
452
453 return $query;
454 }
455
456 /**
457 * Renders delivery detail for packetery orders.
458 *
459 * @param WC_Order $order WordPress order.
460 */
461 public function renderDeliveryDetail( WC_Order $order ): void {
462 $orderEntity = $this->orderRepository->getByWcOrder( $order );
463 if ( null === $orderEntity ) {
464 return;
465 }
466
467 $carrierId = $orderEntity->getCarrierId();
468 $carrierOptions = Carrier\Options::createByCarrierId( $carrierId );
469
470 $this->latte_engine->render(
471 PACKETERY_PLUGIN_DIR . '/template/order/delivery-detail.latte',
472 [
473 'pickupPoint' => $orderEntity->getPickupPoint(),
474 'validatedDeliveryAddress' => $orderEntity->getValidatedDeliveryAddress(),
475 'carrierAddressValidation' => $carrierOptions->getAddressValidation(),
476 'isExternalCarrier' => $orderEntity->isExternalCarrier(),
477 'translations' => [
478 'packeta' => __( 'Packeta', 'packeta' ),
479 'pickupPointDetail' => __( 'Pickup Point Detail', 'packeta' ),
480 'name' => __( 'Name', 'packeta' ),
481 'address' => __( 'Address', 'packeta' ),
482 'pickupPointDetailCaps' => __( 'Pickup Point Detail', 'packeta' ),
483 'addressWasNotValidated' => __( 'Address was not validated', 'packeta' ),
484 'validatedAddress' => __( 'Validated address', 'packeta' ),
485 'street' => __( 'Street', 'packeta' ),
486 'houseNumber' => __( 'House number', 'packeta' ),
487 'city' => __( 'City', 'packeta' ),
488 'zip' => __( 'Zip', 'packeta' ),
489 'county' => __( 'County', 'packeta' ),
490 'gps' => __( 'GPS', 'packeta' ),
491 ],
492 ]
493 );
494 }
495
496 /**
497 * Renders delivery detail for packetery orders, on "thank you" page and in frontend detail.
498 *
499 * @param WC_Order $wcOrder WordPress order.
500 */
501 public function renderOrderDetail( WC_Order $wcOrder ): void {
502 $order = $this->orderRepository->getById( $wcOrder->get_id() );
503 if ( null === $order ) {
504 return;
505 }
506
507 $pickupPoint = $order->getPickupPoint();
508 $validatedDeliveryAddress = $order->getValidatedDeliveryAddress();
509 if ( null === $pickupPoint && null === $validatedDeliveryAddress ) {
510 return;
511 }
512
513 $this->latte_engine->render(
514 PACKETERY_PLUGIN_DIR . '/template/order/detail.latte',
515 [
516 'displayPickupPointInfo' => $this->shouldDisplayPickupPointInfo(),
517 'pickupPoint' => $pickupPoint,
518 'validatedDeliveryAddress' => $validatedDeliveryAddress,
519 'isExternalCarrier' => $order->isExternalCarrier(),
520 'translations' => [
521 'packeta' => __( 'Packeta', 'packeta' ),
522 'selectedPickupPoint' => __( 'Selected pickup point', 'packeta' ),
523 'pickupPointName' => __( 'Pickup Point Name', 'packeta' ),
524 'pickupPointDetail' => __( 'Pickup Point Detail', 'packeta' ),
525 'validatedAddress' => __( 'Validated address', 'packeta' ),
526 'address' => __( 'Address', 'packeta' ),
527 ],
528 ]
529 );
530 }
531
532 /**
533 * Renders email footer.
534 *
535 * @param mixed $email Email data.
536 */
537 public function renderEmailFooter( $email ): void {
538 if ( ! $email instanceof WC_Email || ! $email->object instanceof WC_Order ) {
539 return;
540 }
541
542 $packeteryOrder = $this->orderRepository->getByWcOrder( $email->object );
543 if ( null === $packeteryOrder ) {
544 return;
545 }
546
547 $pickupPoint = $packeteryOrder->getPickupPoint();
548 $validatedDeliveryAddress = $packeteryOrder->getValidatedDeliveryAddress();
549
550 $this->latte_engine->render(
551 PACKETERY_PLUGIN_DIR . '/template/email/footer.latte',
552 [
553 'displayPickupPointInfo' => $this->shouldDisplayPickupPointInfo(),
554 'pickupPoint' => $pickupPoint,
555 'validatedDeliveryAddress' => $validatedDeliveryAddress,
556 'isExternalCarrier' => $packeteryOrder->isExternalCarrier(),
557 'translations' => [
558 'packeta' => __( 'Packeta', 'packeta' ),
559 'pickupPointDetail' => __( 'Pickup Point Detail', 'packeta' ),
560 'pickupPointName' => __( 'Pickup Point Name', 'packeta' ),
561 'link' => __( 'Link', 'packeta' ),
562 'pickupPointAddress' => __( 'Pickup Point Address', 'packeta' ),
563 'validatedDeliveryAddress' => __( 'validated delivery address', 'packeta' ),
564 'street' => __( 'Street', 'packeta' ),
565 'houseNumber' => __( 'House number', 'packeta' ),
566 'city' => __( 'City', 'packeta' ),
567 'zip' => __( 'Zip', 'packeta' ),
568 'county' => __( 'County', 'packeta' ),
569 ],
570 ]
571 );
572 }
573
574 /**
575 * Tells if pickup point info should be displayed.
576 *
577 * @return bool
578 */
579 public function shouldDisplayPickupPointInfo(): bool {
580 return ! $this->optionsProvider->replaceShippingAddressWithPickupPointAddress() || wc_ship_to_billing_address_only();
581 }
582
583 /**
584 * Renders confirm modal template.
585 */
586 public function renderConfirmModalTemplate(): void {
587 if ( $this->contextResolver->isPacketeryConfirmPage() ) {
588 $this->latte_engine->render(
589 PACKETERY_PLUGIN_DIR . '/template/confirm-modal-template.latte',
590 [
591 'translations' => [
592 'closeModalPanel' => __( 'Close modal panel', 'packeta' ),
593 'no' => __( 'No', 'packeta' ),
594 'yes' => __( 'Yes', 'packeta' ),
595 ],
596 ]
597 );
598 }
599 }
600
601 /**
602 * Enqueues admin JS file.
603 *
604 * @param string $name Name of script.
605 * @param string $file Relative file path.
606 * @param bool $inFooter Tells where to include script.
607 * @param array $deps Script dependencies.
608 */
609 private function enqueueScript( string $name, string $file, bool $inFooter, array $deps = [] ): void {
610 wp_enqueue_script(
611 $name,
612 plugin_dir_url( $this->main_file_path ) . $file,
613 $deps,
614 md5( (string) filemtime( PACKETERY_PLUGIN_DIR . '/' . $file ) ),
615 $inFooter
616 );
617 }
618
619 /**
620 * Enqueues CSS file.
621 *
622 * @param string $name Name of script.
623 * @param string $file Relative file path.
624 */
625 private function enqueueStyle( string $name, string $file ): void {
626 wp_enqueue_style(
627 $name,
628 plugin_dir_url( $this->main_file_path ) . $file,
629 [],
630 md5( (string) filemtime( PACKETERY_PLUGIN_DIR . '/' . $file ) )
631 );
632 }
633
634 /**
635 * Builds asset URL.
636 *
637 * @param string $asset Relative asset path without leading slash.
638 *
639 * @return string
640 */
641 public static function buildAssetUrl( string $asset ): string {
642 $url = plugin_dir_url( PACKETERY_PLUGIN_DIR . '/packeta.php' ) . $asset;
643 $filename = PACKETERY_PLUGIN_DIR . '/' . $asset;
644
645 return add_query_arg( [ 'v' => md5( (string) filemtime( $filename ) ) ], $url );
646 }
647
648 /**
649 * Enqueues javascript files and stylesheets for checkout.
650 */
651 public function enqueueFrontAssets(): void {
652 if ( is_checkout() ) {
653 $this->enqueueStyle( 'packetery-front-styles', 'public/front.css' );
654 $this->enqueueStyle( 'packetery-custom-front-styles', 'public/custom-front.css' );
655 $this->enqueueScript( 'packetery-checkout', 'public/checkout.js', true, [ 'jquery' ] );
656 wp_localize_script( 'packetery-checkout', 'packeteryCheckoutSettings', $this->checkout->createSettings() );
657 }
658 }
659
660 /**
661 * Enqueues javascript files and stylesheets for administration.
662 */
663 public function enqueueAdminAssets(): void {
664 $page = $this->request->getQuery( 'page' );
665 $isOrderGridPage = $this->contextResolver->isOrderGridPage();
666 $isOrderDetailPage = $this->contextResolver->isOrderDetailPage();
667
668 if ( $isOrderGridPage || $isOrderDetailPage || in_array( $page, [ Carrier\OptionsPage::SLUG, Options\Page::SLUG ], true ) ) {
669 $this->enqueueScript( 'live-form-validation-options', 'public/live-form-validation-options.js', false );
670 $this->enqueueScript( 'live-form-validation', 'public/libs/live-form-validation/live-form-validation.js', false, [ 'live-form-validation-options' ] );
671 $this->enqueueScript( 'live-form-validation-extension', 'public/live-form-validation-extension.js', false, [ 'live-form-validation' ] );
672 }
673
674 if ( Carrier\OptionsPage::SLUG === $page ) {
675 $this->enqueueScript( 'packetery-admin-country-carrier', 'public/admin-country-carrier.js', true, [ 'jquery' ] );
676 }
677
678 $isProductPage = $this->contextResolver->isProductPage();
679 $screen = get_current_screen();
680 $isDashboard = ( $screen && 'dashboard' === $screen->id );
681
682 if (
683 $isOrderGridPage || $isOrderDetailPage || $isProductPage || $isDashboard ||
684 in_array(
685 $page,
686 [
687 Options\Page::SLUG,
688 Carrier\OptionsPage::SLUG,
689 Log\Page::SLUG,
690 Order\labelPrint::MENU_SLUG,
691 ],
692 true
693 )
694 ) {
695 $this->enqueueStyle( 'packetery-admin-styles', 'public/admin.css' );
696 }
697
698 if ( $isOrderGridPage ) {
699 $this->enqueueScript( 'packetery-admin-grid-order-edit-js', 'public/admin-grid-order-edit.js', true, [ 'jquery', 'wp-util', 'backbone' ] );
700 }
701
702 if ( $isOrderDetailPage ) {
703 $this->enqueueScript( 'packetery-admin-pickup-point-picker', 'public/admin-pickup-point-picker.js', false, [ 'jquery' ] );
704 }
705
706 if ( $this->contextResolver->isPacketeryConfirmPage() ) {
707 $this->enqueueScript( 'packetery-confirm', 'public/confirm.js', true, [ 'jquery', 'backbone' ] );
708 }
709 }
710
711 /**
712 * Add links to left admin menu.
713 */
714 public function add_menu_pages(): void {
715 $this->options_page->register();
716 $this->carrierOptionsPage->register();
717 $this->labelPrint->register();
718 $this->orderCollectionPrint->register();
719 $this->logPage->register();
720 }
721
722 /**
723 * Gets current locale.
724 */
725 private function getLocale(): string {
726 /**
727 * Applies plugin_locale filters.
728 *
729 * @since 1.0.0
730 */
731 return apply_filters(
732 'plugin_locale',
733 ( is_admin() ? get_user_locale() : get_locale() ),
734 self::DOMAIN
735 );
736 }
737
738 /**
739 * Loads plugin translation file by user locale.
740 */
741 public function loadTranslation(): void {
742 $domain = self::DOMAIN;
743 $locale = $this->getLocale();
744
745 $moFile = PACKETERY_PLUGIN_DIR . "/languages/$domain-$locale.mo";
746 $result = load_textdomain( $domain, $moFile );
747
748 if ( false === $result ) {
749 $moFile = PACKETERY_PLUGIN_DIR . "/languages/$domain-en_US.mo";
750 load_textdomain( $domain, $moFile );
751 }
752 }
753
754 /**
755 * Inits plugin.
756 */
757 public function init(): void {
758 add_filter(
759 'plugin_action_links_' . plugin_basename( $this->main_file_path ),
760 [
761 $this,
762 'addPluginActionLinks',
763 ]
764 );
765 add_filter( 'plugin_row_meta', [ $this, 'addPluginRowMeta' ], 10, 2 );
766 }
767
768 /**
769 * Uninstalls plugin and drops custom database table.
770 * Only a static class method or function can be used in an uninstall hook.
771 */
772 public static function uninstall(): void {
773 if ( defined( 'PACKETERY_DEBUG' ) && PACKETERY_DEBUG === true ) {
774 return;
775 }
776
777 $container = require PACKETERY_PLUGIN_DIR . '/bootstrap.php';
778
779 $optionsRepository = $container->getByType( Options\Repository::class );
780 $pluginOptions = $optionsRepository->getPluginOptions();
781 foreach ( $pluginOptions as $option ) {
782 delete_option( $option->option_name );
783 }
784
785 $logRepository = $container->getByType( Log\Repository::class );
786 $logRepository->drop();
787
788 $carrierRepository = $container->getByType( Carrier\Repository::class );
789 $carrierRepository->drop();
790
791 $orderRepository = $container->getByType( Order\Repository::class );
792 $orderRepository->drop();
793 }
794
795 /**
796 * Adds action links visible at the plugin screen.
797 *
798 * @link https://developer.wordpress.org/reference/hooks/plugin_action_links_plugin_file/
799 *
800 * @param array $links Plugin Action links.
801 *
802 * @return array
803 */
804 public function addPluginActionLinks( array $links ): array {
805 $settingsLink = '<a href="' . esc_url( admin_url( 'admin.php?page=' . Options\Page::SLUG ) ) . '" aria-label="' .
806 esc_attr__( 'View the plugin documentation', 'packeta' ) . '">' .
807 esc_html__( 'Settings', 'packeta' ) . '</a>';
808
809 array_unshift( $links, $settingsLink );
810
811 return $links;
812 }
813
814 /**
815 * Show row meta on the plugin screen.
816 *
817 * @link https://developer.wordpress.org/reference/hooks/plugin_row_meta/
818 *
819 * @param array $links Plugin Row Meta.
820 * @param string $pluginFileName Plugin Base file.
821 *
822 * @return array
823 */
824 public function addPluginRowMeta( array $links, string $pluginFileName ): array {
825 if ( ! strpos( $pluginFileName, basename( $this->main_file_path ) ) ) {
826 return $links;
827 }
828 $links[] = '<a href="' . esc_url( 'https://github.com/Zasilkovna/WooCommerce/wiki' ) . '" aria-label="' .
829 esc_attr__( 'View Packeta documentation', 'packeta' ) . '">' .
830 esc_html__( 'Documentation', 'packeta' ) . '</a>';
831
832 return $links;
833 }
834
835 /**
836 * Adds Packeta method to available shipping methods.
837 *
838 * @param array $methods Previous state.
839 *
840 * @return array
841 */
842 public function add_shipping_method( array $methods ): array {
843 $methods[ ShippingMethod::PACKETERY_METHOD_ID ] = ShippingMethod::class;
844
845 return $methods;
846 }
847
848 /**
849 * Hides submenu item. Must not be called too early.
850 *
851 * @param string $itemSlug Item slug.
852 */
853 public static function hideSubmenuItem( string $itemSlug ): void {
854 global $submenu;
855 if ( isset( $submenu[ Options\Page::SLUG ] ) ) {
856 foreach ( $submenu[ Options\Page::SLUG ] as $key => $menu ) {
857 if ( $itemSlug === $menu[2] ) {
858 unset( $submenu[ Options\Page::SLUG ][ $key ] );
859 }
860 }
861 }
862 }
863
864 /**
865 * Gets software identity for Packeta APIs.
866 *
867 * @return string
868 */
869 public static function getAppIdentity(): string {
870 return 'WordPress-' . get_bloginfo( 'version' ) . '-Woocommerce-' . WC_VERSION . '-Packeta-' . self::VERSION;
871 }
872 }
873