PluginProbe
PostNL for WooCommerce / trunk
PostNL for WooCommerce vtrunk
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 4.4.2 All 71 releases
woo-postnl / src / Main.php

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

541 lines 13.4 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.11';
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
229 /**
230 * Collection of hooks.
231 */
232 public function init_hooks() {
233 add_action( 'init', array( $this, 'init' ), 5 );
234 add_action( 'init', array( $this, 'load_textdomain' ) );
235
236 // Locate woocommerce template.
237 add_filter( 'woocommerce_locate_template', array( $this, 'woocommerce_locate_template' ), 20, 3 );
238
239 add_filter( 'woocommerce_email_classes', array( $this, 'add_wc_smart_return_email' ) );
240
241 // Register the block category.
242 add_action( 'block_categories_all', array( $this, 'register_postnl_block_category' ), 10, 2 );
243
244 add_filter( 'plugin_row_meta', array( $this, 'add_row_meta' ), 10, 2 );
245 add_filter( 'plugin_action_links_' . POSTNL_WC_PLUGIN_BASENAME, array( $this, 'add_action_links' ), 10, 1 );
246 }
247
248 /**
249 * Add the smart return email class.
250 *
251 * @param array $email_classes Array of existing WC emails.
252 *
253 * @return array $email_classes
254 */
255 public function add_wc_smart_return_email( $email_classes ) {
256 // Add the smart return email to the list of email classes.
257 $email_classes['WC_Smart_Return_Email'] = new Emails\WC_Email_Smart_Return();
258
259 return $email_classes;
260 }
261
262 /**
263 * Localisation.
264 */
265 public function load_textdomain() {
266 load_plugin_textdomain( 'postnl-for-woocommerce', false, untrailingslashit( dirname( POSTNL_WC_PLUGIN_BASENAME ) ) . '/languages' );
267 }
268
269 /**
270 * Add PostNL Shipping Method to WooCommerce.
271 *
272 * @param array<WC_Shipping_Method> $shipping_methods Array of existing WC shipping methods.
273 *
274 * @return array<WC_Shipping_Method>
275 */
276 public function add_shipping_method( $shipping_methods ) {
277 $shipping_methods[ $this->settings_id ] = 'PostNLWooCommerce\Shipping_Method\PostNL';
278 return $shipping_methods;
279 }
280
281 /**
282 * Get order single class.
283 *
284 * @return Order\Single
285 */
286 public function get_shipping_order() {
287 if ( empty( $this->shipping_order ) ) {
288 $this->shipping_order = new Order\Single();
289 }
290
291 return $this->shipping_order;
292 }
293
294 /**
295 * Get product editor class.
296 *
297 * @return Product\Product_Editor
298 */
299 public function get_product_editor() {
300 if ( empty( $this->product_editor ) ) {
301 $this->product_editor = new Product\Product_Editor();
302 }
303
304 return $this->product_editor;
305 }
306
307 /**
308 * Get order bulk class.
309 *
310 * @return Order\Bulk
311 */
312 public function get_shipping_order_bulk() {
313 if ( empty( $this->shipping_order_bulk ) ) {
314 $this->shipping_order_bulk = new Order\Bulk();
315 }
316
317 return $this->shipping_order_bulk;
318 }
319
320 /**
321 * Get order bulk class.
322 *
323 * @return Order\OrdersList
324 */
325 public function get_orders_list() {
326 if ( empty( $this->orders_list ) ) {
327 $this->shipping_order_bulk = new Order\OrdersList();
328 }
329
330 return $this->orders_list;
331 }
332
333 /**
334 * Get product class.
335 *
336 * @return Product\Single
337 */
338 public function get_shipping_product() {
339 if ( empty( $this->shipping_product ) ) {
340 $this->shipping_product = new Product\Single();
341 }
342
343 return $this->shipping_product;
344 }
345
346 /**
347 * Get frontend class.
348 */
349 public function get_frontend() {
350 new Frontend\Container();
351 new Frontend\Delivery_Day();
352 new Frontend\Dropoff_Points();
353 new Frontend\Checkout_Fields();
354 new Frontend\Fill_In_With_Postnl();
355 new Frontend\Fill_In_With_Postnl_Handler();
356 }
357
358 /**
359 * Get settings class.
360 *
361 * @return Shipping_Method\Settings
362 */
363 public function get_shipping_settings() {
364 if ( empty( $this->shipping_settings ) ) {
365 $this->shipping_settings = new Shipping_Method\Settings();
366 }
367
368 return $this->shipping_settings;
369 }
370
371 public function load_fill_in_with_postnl_settings() {
372 if ( class_exists( 'PostNLWooCommerce\Shipping_Method\Fill_In_With_PostNL_Settings' ) ) {
373 new Fill_In_With_PostNL_Settings();
374 }
375 }
376
377 /**
378 * Define constant if not already set.
379 *
380 * @param string $name Name of constant variable.
381 * @param string|bool $value Value of constant variable.
382 */
383 public function define( $name, $value ) {
384 if ( ! defined( $name ) ) {
385 define( $name, $value );
386 }
387 }
388
389 /**
390 * Admin error notifying user that WC is required.
391 */
392 public function notice_wc_required() {
393 if ( ! class_exists( 'WooCommerce' ) ) {
394 ?>
395 <div class="error">
396 <p><?php esc_html_e( 'PostNL plugin requires WooCommerce to be installed and activated!', 'postnl-for-woocommerce' ); ?></p>
397 </div>
398 <?php
399 }
400 }
401
402 /**
403 * Admin error notifying user that Country must be using Netherlands or Belgium.
404 */
405 public function notice_nl_be_required() {
406 if ( ! Utils::use_available_country() ) {
407 ?>
408 <div class="error">
409 <p><?php esc_html_e( 'PostNL plugin requires store country to be Netherlands (NL) or Belgium (BE)!', 'postnl-for-woocommerce' ); ?></p>
410 </div>
411 <?php
412 }
413 }
414
415 /**
416 * Manipulate the WooCommerce template file location.
417 *
418 * @param string $template Template filename before manipulated.
419 * @param string $template_name Template filename to be manipulated.
420 * @param string $template_path Template new path.
421 *
422 * @return String
423 */
424 public function woocommerce_locate_template( $template, $template_name, $template_path ) {
425
426 global $woocommerce;
427
428 $_template = $template;
429
430 if ( ! $template_path ) {
431 $template_path = $woocommerce->template_url;
432 }
433
434 $plugin_path = untrailingslashit( POSTNL_WC_PLUGIN_DIR_PATH ) . '/templates/';
435
436 // Look within passed path within the theme - this is priority.
437 $template = locate_template(
438 array(
439 $template_path . $template_name,
440 $template_name,
441 )
442 );
443
444 // Modification: Get the template from this plugin, if it exists.
445 if ( ! $template && file_exists( $plugin_path . $template_name ) ) {
446 $template = $plugin_path . $template_name;
447 }
448
449 // Use default template.
450
451 if ( ! $template ) {
452 $template = $_template;
453 }
454
455 // Return what we found.
456 return $template;
457 }
458
459 public function checkout_blocks() {
460 if ( ! Utils::is_blocks_checkout() ) {
461 return;
462 }
463
464 // Initialize classes that depend on WooCommerce
465 new Extend_Block_Core();
466 Extend_Store_Endpoint::init();
467 // Register the blocks integration
468 add_action(
469 'woocommerce_blocks_checkout_block_registration',
470 function ( $integration_registry ) {
471 $integration_registry->register( new Blocks_Integration() );
472 }
473 );
474 }
475 /**
476 * Registers the slug as a block category with WordPress.
477 *
478 * @param array $categories Existing categories.
479 * @return array Modified categories.
480 */
481 public function register_postnl_block_category( $categories ) {
482 return array_merge(
483 $categories,
484 array(
485 array(
486 'slug' => 'postnl',
487 'title' => __( 'Postnl Checkout Blocks', 'postnl-for-woocommerce' ),
488 ),
489 )
490 );
491 }
492
493 /**
494 * Add row meta links.
495 *
496 * @param string[] $links Existing links.
497 * @param string $file Plugin file name.
498 *
499 * @return string[]
500 */
501 public function add_row_meta( array $links, string $file ): array {
502 if ( $file === POSTNL_WC_PLUGIN_BASENAME ) {
503 $links[] = sprintf(
504 '<a href="%s" target="_blank" rel="noopener">%s</a>',
505 esc_url( 'https://wordpress.org/support/plugin/woo-postnl/reviews/#new-post' ),
506 esc_html__( 'Leave a review', 'postnl-for-woocommerce' )
507 );
508 }
509
510 return $links;
511 }
512
513 /**
514 * Add action links.
515 *
516 * @param string[] $links Existing links.
517 *
518 * @return string[]
519 */
520 public function add_action_links( array $links ): array {
521 array_unshift(
522 $links,
523 sprintf(
524 '<a href="%s">%s</a>',
525 esc_url( admin_url( 'admin.php?page=wc-settings&tab=shipping&section=postnl' ) ),
526 esc_html__( 'Settings', 'postnl-for-woocommerce' )
527 )
528 );
529
530 return $links;
531 }
532
533 /**
534 * Get logger object.
535 */
536 public static function get_logger() {
537 $settings = Shipping_Method\Settings::get_instance();
538 return new Logger( $settings->is_logging_enabled() );
539 }
540 }
541