PluginProbe
PostNL for WooCommerce / 5.9.12
PostNL for WooCommerce v5.9.12
5.9.12 5.9.11 5.9.10 5.9.9 5.9.8 5.9.7 5.9.6 trunk 2.5.0 2.5.1 2.5.2 2.5.3 2.5.4 2.5.5 3.1.4 3.1.5 3.1.6 3.1.7 4.0.0 4.0.1 4.0.2 4.3.2 4.3.3 4.4.0 4.4.1 All 72 releases
woo-postnl / src / Main.php

Main.php in PostNL for WooCommerce 5.9.12, at src/Main.php

546 lines 13.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Class Main file.
4 *
5 * @package PostNLWooCommerce
6 */
7
8 namespace PostNLWooCommerce;
9
10 if ( ! defined( 'ABSPATH' ) ) {
11 exit;
12 }
13
14 use PostNLWooCommerce\Product\Product_Editor;
15 use PostNLWooCommerce\Checkout_Blocks\Extend_Block_Core;
16 use PostNLWooCommerce\Checkout_Blocks\Blocks_Integration;
17 use PostNLWooCommerce\Checkout_Blocks\Extend_Store_Endpoint;
18 use PostNLWooCommerce\Shipping_Method\Fill_In_With_PostNL_Settings;
19
20 /**
21 * Class Main
22 *
23 * @package PostNLWooCommerce
24 */
25 class Main {
26 /**
27 * Version of this plugin.
28 *
29 * @var _version
30 */
31 private $version = '5.9.12';
32
33 /**
34 * The ID of this plugin settings.
35 *
36 * @var settings_id
37 */
38 public $settings_id = 'postnl';
39
40 /**
41 * The name of this plugin service.
42 *
43 * @var service_name
44 */
45 public $service_name = 'PostNL';
46
47 /**
48 * Shipping Product.
49 *
50 * @var PostNLWooCommerce\Product\PostNL
51 */
52 public $shipping_product = null;
53
54 /**
55 * Shipping Order.
56 *
57 * @var PostNLWooCommerce\Order\Single
58 */
59 public $shipping_order = null;
60
61 /**
62 * Shipping Order Bulk.
63 *
64 * @var PostNLWooCommerce\Order\Bulk
65 */
66 public $shipping_order_bulk = null;
67
68 /**
69 * Orders List
70 *
71 * @var PostNLWooCommerce\Order\OrdersList
72 */
73 public $orders_list = null;
74
75 /**
76 * Shipping Settings.
77 *
78 * @var PostNLWooCommerce\Shipping_Method\Settings
79 */
80 public $shipping_settings = null;
81
82
83 /**
84 * Instance to call certain functions globally within the plugin
85 *
86 * @var _instance
87 */
88 protected static $instance = null;
89
90 /**
91 * Product Editor.
92 *
93 * @var PostNLWooCommerce\Product\Product_Editor
94 */
95 public $product_editor = null;
96
97 /**
98 * Construct the plugin.
99 */
100 public function __construct() {
101 $this->define_constants();
102 // Throw an admin error informing the user this plugin needs WooCommerce to function.
103 add_action( 'admin_notices', array( $this, 'notice_wc_required' ) );
104
105 if ( ! class_exists( 'WooCommerce' ) ) {
106 return;
107 }
108
109 // Declare WooCommerce features compatibility.
110 add_action( 'before_woocommerce_init', array( $this, 'declare_wc_hpos_compatibility' ) );
111 add_action( 'before_woocommerce_init', array( $this, 'declare_product_editor_compatibility' ) );
112
113 // Throw an admin error informing the user this plugin needs country settings to be NL and BE.
114 add_action( 'admin_notices', array( $this, 'notice_nl_be_required' ) );
115
116 if ( ! Utils::use_available_country() ) {
117 return;
118 }
119
120 add_action( 'init', array( $this, 'load_plugin' ), 1 );
121 add_filter( 'woocommerce_shipping_methods', array( $this, 'add_shipping_method' ) );
122 }
123
124 /**
125 * Declare WooCommerce HPOS feature compatibility.
126 */
127 public function declare_wc_hpos_compatibility() {
128 if ( class_exists( '\Automattic\WooCommerce\Utilities\FeaturesUtil' ) ) {
129 \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'custom_order_tables', POSTNL_WC_PLUGIN_BASENAME, true );
130 }
131 }
132
133 /**
134 * Declare Product Editor compatibility.
135 */
136 public function declare_product_editor_compatibility() {
137 if ( class_exists( '\Automattic\WooCommerce\Utilities\FeaturesUtil' ) ) {
138 \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'product_block_editor', POSTNL_WC_PLUGIN_BASENAME, true );
139 }
140 }
141
142 /**
143 * Main PostNL for WooCommerce.
144 *
145 * Ensures only one instance is loaded or can be loaded.
146 *
147 * @static
148 * @return self Main instance.
149 */
150 public static function instance() {
151 if ( is_null( self::$instance ) ) {
152 self::$instance = new self();
153 }
154 return self::$instance;
155 }
156
157 /**
158 * Define WC Constants.
159 */
160 private function define_constants() {
161 $upload_dir = wp_upload_dir();
162
163 // Path related defines.
164 $this->define( 'POSTNL_WC_PLUGIN_FILE', POSTNL_WC_PLUGIN_FILE );
165 $this->define( 'POSTNL_WC_PLUGIN_DIR_PATH', untrailingslashit( plugin_dir_path( POSTNL_WC_PLUGIN_FILE ) ) );
166 $this->define( 'POSTNL_WC_PLUGIN_DIR_URL', untrailingslashit( plugins_url( '/', POSTNL_WC_PLUGIN_FILE ) ) );
167
168 $this->define( 'POSTNL_WC_SANDBOX_API_URL', esc_url( 'https://api-sandbox.postnl.nl' ) );
169 $this->define( 'POSTNL_WC_PROD_API_URL', esc_url( 'https://api.postnl.nl' ) );
170
171 $this->define( 'POSTNL_WC_VERSION', $this->version );
172 $this->define( 'POSTNL_SETTINGS_ID', $this->settings_id );
173 $this->define( 'POSTNL_SERVICE_NAME', $this->service_name );
174 $this->define( 'POSTNL_WC_LOG_DIR', $upload_dir['basedir'] . '/wc-logs/' );
175 $this->define( 'POSTNL_UPLOADS_DIR', $upload_dir['basedir'] . '/postnl/' );
176 }
177
178 /**
179 * Determine which plugin to load.
180 */
181 public function load_plugin() {
182 $this->init_hooks();
183 $this->checkout_blocks();
184 $this->maybe_revert_discontinued_return_option();
185 }
186
187 /**
188 * Switch the discontinued "Shipment & Return" return option back to "None".
189 *
190 * PostNL discontinues the Shipment & Return Label product on 1 July 2026.
191 * Stores that still have it selected are reverted to "None" so outbound
192 * label generation does not fail against the API. Runs once per install.
193 *
194 * @since 5.9.7
195 */
196 public function maybe_revert_discontinued_return_option() {
197 if ( 'done' === get_option( 'postnl_shipping_return_reverted' ) ) {
198 return;
199 }
200
201 $settings = get_option( 'woocommerce_postnl_settings', array() );
202 $reverted = true;
203
204 if ( is_array( $settings ) && 'shipping_return' === ( $settings['return_shipment_and_labels'] ?? null ) ) {
205 $settings['return_shipment_and_labels'] = 'none';
206 $reverted = update_option( 'woocommerce_postnl_settings', $settings );
207 }
208
209 // Only mark the migration complete when nothing needed reverting or the
210 // revert write succeeded, so a failed write retries on the next request.
211 if ( $reverted ) {
212 update_option( 'postnl_shipping_return_reverted', 'done' );
213 }
214 }
215
216 /**
217 * Initialize the plugin.
218 */
219 public function init() {
220 $this->get_shipping_order();
221 $this->get_shipping_order_bulk();
222 $this->get_orders_list();
223 $this->get_shipping_product();
224 $this->load_fill_in_with_postnl_settings();
225 $this->get_frontend();
226 $this->get_product_editor();
227
228 if ( is_admin() ) {
229 new Admin\Api_Key_Banner();
230 new Admin\Api_Key_Check();
231 }
232 }
233
234 /**
235 * Collection of hooks.
236 */
237 public function init_hooks() {
238 add_action( 'init', array( $this, 'init' ), 5 );
239 add_action( 'init', array( $this, 'load_textdomain' ) );
240
241 // Locate woocommerce template.
242 add_filter( 'woocommerce_locate_template', array( $this, 'woocommerce_locate_template' ), 20, 3 );
243
244 add_filter( 'woocommerce_email_classes', array( $this, 'add_wc_smart_return_email' ) );
245
246 // Register the block category.
247 add_action( 'block_categories_all', array( $this, 'register_postnl_block_category' ), 10, 2 );
248
249 add_filter( 'plugin_row_meta', array( $this, 'add_row_meta' ), 10, 2 );
250 add_filter( 'plugin_action_links_' . POSTNL_WC_PLUGIN_BASENAME, array( $this, 'add_action_links' ), 10, 1 );
251 }
252
253 /**
254 * Add the smart return email class.
255 *
256 * @param array $email_classes Array of existing WC emails.
257 *
258 * @return array $email_classes
259 */
260 public function add_wc_smart_return_email( $email_classes ) {
261 // Add the smart return email to the list of email classes.
262 $email_classes['WC_Smart_Return_Email'] = new Emails\WC_Email_Smart_Return();
263
264 return $email_classes;
265 }
266
267 /**
268 * Localisation.
269 */
270 public function load_textdomain() {
271 load_plugin_textdomain( 'postnl-for-woocommerce', false, untrailingslashit( dirname( POSTNL_WC_PLUGIN_BASENAME ) ) . '/languages' );
272 }
273
274 /**
275 * Add PostNL Shipping Method to WooCommerce.
276 *
277 * @param array<WC_Shipping_Method> $shipping_methods Array of existing WC shipping methods.
278 *
279 * @return array<WC_Shipping_Method>
280 */
281 public function add_shipping_method( $shipping_methods ) {
282 $shipping_methods[ $this->settings_id ] = 'PostNLWooCommerce\Shipping_Method\PostNL';
283 return $shipping_methods;
284 }
285
286 /**
287 * Get order single class.
288 *
289 * @return Order\Single
290 */
291 public function get_shipping_order() {
292 if ( empty( $this->shipping_order ) ) {
293 $this->shipping_order = new Order\Single();
294 }
295
296 return $this->shipping_order;
297 }
298
299 /**
300 * Get product editor class.
301 *
302 * @return Product\Product_Editor
303 */
304 public function get_product_editor() {
305 if ( empty( $this->product_editor ) ) {
306 $this->product_editor = new Product\Product_Editor();
307 }
308
309 return $this->product_editor;
310 }
311
312 /**
313 * Get order bulk class.
314 *
315 * @return Order\Bulk
316 */
317 public function get_shipping_order_bulk() {
318 if ( empty( $this->shipping_order_bulk ) ) {
319 $this->shipping_order_bulk = new Order\Bulk();
320 }
321
322 return $this->shipping_order_bulk;
323 }
324
325 /**
326 * Get order bulk class.
327 *
328 * @return Order\OrdersList
329 */
330 public function get_orders_list() {
331 if ( empty( $this->orders_list ) ) {
332 $this->shipping_order_bulk = new Order\OrdersList();
333 }
334
335 return $this->orders_list;
336 }
337
338 /**
339 * Get product class.
340 *
341 * @return Product\Single
342 */
343 public function get_shipping_product() {
344 if ( empty( $this->shipping_product ) ) {
345 $this->shipping_product = new Product\Single();
346 }
347
348 return $this->shipping_product;
349 }
350
351 /**
352 * Get frontend class.
353 */
354 public function get_frontend() {
355 new Frontend\Container();
356 new Frontend\Delivery_Day();
357 new Frontend\Dropoff_Points();
358 new Frontend\Checkout_Fields();
359 new Frontend\Fill_In_With_Postnl();
360 new Frontend\Fill_In_With_Postnl_Handler();
361 }
362
363 /**
364 * Get settings class.
365 *
366 * @return Shipping_Method\Settings
367 */
368 public function get_shipping_settings() {
369 if ( empty( $this->shipping_settings ) ) {
370 $this->shipping_settings = new Shipping_Method\Settings();
371 }
372
373 return $this->shipping_settings;
374 }
375
376 public function load_fill_in_with_postnl_settings() {
377 if ( class_exists( 'PostNLWooCommerce\Shipping_Method\Fill_In_With_PostNL_Settings' ) ) {
378 new Fill_In_With_PostNL_Settings();
379 }
380 }
381
382 /**
383 * Define constant if not already set.
384 *
385 * @param string $name Name of constant variable.
386 * @param string|bool $value Value of constant variable.
387 */
388 public function define( $name, $value ) {
389 if ( ! defined( $name ) ) {
390 define( $name, $value );
391 }
392 }
393
394 /**
395 * Admin error notifying user that WC is required.
396 */
397 public function notice_wc_required() {
398 if ( ! class_exists( 'WooCommerce' ) ) {
399 ?>
400 <div class="error">
401 <p><?php esc_html_e( 'PostNL plugin requires WooCommerce to be installed and activated!', 'postnl-for-woocommerce' ); ?></p>
402 </div>
403 <?php
404 }
405 }
406
407 /**
408 * Admin error notifying user that Country must be using Netherlands or Belgium.
409 */
410 public function notice_nl_be_required() {
411 if ( ! Utils::use_available_country() ) {
412 ?>
413 <div class="error">
414 <p><?php esc_html_e( 'PostNL plugin requires store country to be Netherlands (NL) or Belgium (BE)!', 'postnl-for-woocommerce' ); ?></p>
415 </div>
416 <?php
417 }
418 }
419
420 /**
421 * Manipulate the WooCommerce template file location.
422 *
423 * @param string $template Template filename before manipulated.
424 * @param string $template_name Template filename to be manipulated.
425 * @param string $template_path Template new path.
426 *
427 * @return String
428 */
429 public function woocommerce_locate_template( $template, $template_name, $template_path ) {
430
431 global $woocommerce;
432
433 $_template = $template;
434
435 if ( ! $template_path ) {
436 $template_path = $woocommerce->template_url;
437 }
438
439 $plugin_path = untrailingslashit( POSTNL_WC_PLUGIN_DIR_PATH ) . '/templates/';
440
441 // Look within passed path within the theme - this is priority.
442 $template = locate_template(
443 array(
444 $template_path . $template_name,
445 $template_name,
446 )
447 );
448
449 // Modification: Get the template from this plugin, if it exists.
450 if ( ! $template && file_exists( $plugin_path . $template_name ) ) {
451 $template = $plugin_path . $template_name;
452 }
453
454 // Use default template.
455
456 if ( ! $template ) {
457 $template = $_template;
458 }
459
460 // Return what we found.
461 return $template;
462 }
463
464 public function checkout_blocks() {
465 if ( ! Utils::is_blocks_checkout() ) {
466 return;
467 }
468
469 // Initialize classes that depend on WooCommerce
470 new Extend_Block_Core();
471 Extend_Store_Endpoint::init();
472 // Register the blocks integration
473 add_action(
474 'woocommerce_blocks_checkout_block_registration',
475 function ( $integration_registry ) {
476 $integration_registry->register( new Blocks_Integration() );
477 }
478 );
479 }
480 /**
481 * Registers the slug as a block category with WordPress.
482 *
483 * @param array $categories Existing categories.
484 * @return array Modified categories.
485 */
486 public function register_postnl_block_category( $categories ) {
487 return array_merge(
488 $categories,
489 array(
490 array(
491 'slug' => 'postnl',
492 'title' => __( 'Postnl Checkout Blocks', 'postnl-for-woocommerce' ),
493 ),
494 )
495 );
496 }
497
498 /**
499 * Add row meta links.
500 *
501 * @param string[] $links Existing links.
502 * @param string $file Plugin file name.
503 *
504 * @return string[]
505 */
506 public function add_row_meta( array $links, string $file ): array {
507 if ( $file === POSTNL_WC_PLUGIN_BASENAME ) {
508 $links[] = sprintf(
509 '<a href="%s" target="_blank" rel="noopener">%s</a>',
510 esc_url( 'https://wordpress.org/support/plugin/woo-postnl/reviews/#new-post' ),
511 esc_html__( 'Leave a review', 'postnl-for-woocommerce' )
512 );
513 }
514
515 return $links;
516 }
517
518 /**
519 * Add action links.
520 *
521 * @param string[] $links Existing links.
522 *
523 * @return string[]
524 */
525 public function add_action_links( array $links ): array {
526 array_unshift(
527 $links,
528 sprintf(
529 '<a href="%s">%s</a>',
530 esc_url( admin_url( 'admin.php?page=wc-settings&tab=shipping&section=postnl' ) ),
531 esc_html__( 'Settings', 'postnl-for-woocommerce' )
532 )
533 );
534
535 return $links;
536 }
537
538 /**
539 * Get logger object.
540 */
541 public static function get_logger() {
542 $settings = Shipping_Method\Settings::get_instance();
543 return new Logger( $settings->is_logging_enabled() );
544 }
545 }
546