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 / Product / Single.php

Single.php in PostNL for WooCommerce 5.9.12, at src/Product/Single.php

287 lines 8.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Class Product\Single file.
4 *
5 * @package PostNLWooCommerce\Product
6 */
7
8 namespace PostNLWooCommerce\Product;
9
10 if ( ! defined( 'ABSPATH' ) ) {
11 exit;
12 }
13
14 use PostNLWooCommerce\Utils;
15 use WC_Admin_Meta_Boxes;
16 use WC_Product;
17
18 /**
19 * Class Single
20 *
21 * @package PostNLWooCommerce\Product
22 */
23 class Single {
24 /**
25 * Saved shipping settings.
26 *
27 * @var shipping_settings
28 */
29 protected $shipping_settings = array();
30
31 /**
32 * Current service.
33 *
34 * @var service
35 */
36 protected $service = POSTNL_SERVICE_NAME;
37
38 /**
39 * Letterbox field name.
40 *
41 * @var letterbox_parcel
42 */
43 const LETTERBOX_PARCEL = '_postnl_letterbox_parcel';
44
45 /**
46 * Letterbox field name.
47 *
48 * @var max_qty_per_letterbox
49 */
50 const MAX_QTY_PER_LETTERBOX = '_postnl_max_qty_per_letterbox';
51
52 /**
53 * Origin field name.
54 *
55 * @var origin_field
56 */
57 const ORIGIN_FIELD = '_postnl_country_origin';
58
59 /**
60 * HS Tariff Code field name.
61 *
62 * @var hs_code_field
63 */
64 const HS_CODE_FIELD = '_postnl_hs_tariff_code';
65
66 /**
67 * Adults Only (18+) field.
68 *
69 * @var adults_only
70 */
71 const ADULTS_ONLY_FIELD = '_postnl_adult_product';
72
73 /**
74 * Init and hook in the integration.
75 */
76 public function __construct() {
77 $this->init_hooks();
78 }
79
80 /**
81 * Mapping the product field.
82 *
83 * @param String $service Service name for the product fields.
84 *
85 * @return array
86 */
87 public static function product_field_maps( $service ) {
88 return array(
89 array(
90 'id' => self::ADULTS_ONLY_FIELD,
91 'type' => 'checkbox',
92 // translators: %s will be replaced by service name.
93 'label' => sprintf( esc_html__( 'Mark as 18+ (Adults Only) (%s)', 'postnl-for-woocommerce' ), $service ),
94 'description' => esc_html__( 'Enable this for products intended only for adults (18+).', 'postnl-for-woocommerce' ),
95 'desc_tip' => 'true',
96 ),
97 array(
98 'id' => self::LETTERBOX_PARCEL,
99 'type' => 'checkbox',
100 // translators: %s will be replaced by service name.
101 'label' => sprintf( esc_html__( 'Enable Letterbox Parcel (%s)', 'postnl-for-woocommerce' ), $service ),
102 'description' => esc_html__( 'When this setting is enabled the PostNL plug-in automatically determines whether a shipment fits through a letterbox. This choice can be overridden when creating a shipment manually via the Label & Tracking menu. This only works for orders with destination Netherlands.', 'postnl-for-woocommerce' ),
103 'desc_tip' => 'true',
104 ),
105 array(
106 'id' => self::MAX_QTY_PER_LETTERBOX,
107 'type' => 'number',
108 // translators: %s will be replaced by service name.
109 'label' => sprintf( esc_html__( 'Maximum amount per letterbox parcel (%s)', 'postnl-for-woocommerce' ), $service ),
110 'description' => esc_html__( 'Please fill in how many times this product fits in a letterbox parcel. A letterbox parcel may weigh a maximum of 2 kilograms and has the following maximum dimensions: 38x26.5x3.2 cm', 'postnl-for-woocommerce' ),
111 'desc_tip' => 'true',
112 'placeholder' => esc_html__( 'Enter max quantity', 'postnl-for-woocommerce' ),
113 'custom_attributes' => array(
114 'min' => 1,
115 ),
116 ),
117 array(
118 'id' => self::ORIGIN_FIELD,
119 'type' => 'select',
120 // translators: %s will be replaced by service name.
121 'label' => sprintf( esc_html__( 'Country of Origin (%s)', 'postnl-for-woocommerce' ), $service ),
122 'description' => esc_html__( 'Country of Origin.', 'postnl-for-woocommerce' ),
123 'desc_tip' => 'true',
124 'options' => array_merge(
125 array( '0' => esc_html__( '- select country -', 'postnl-for-woocommerce' ) ),
126 WC()->countries->get_countries(),
127 ),
128 ),
129 array(
130 'id' => self::HS_CODE_FIELD,
131 'type' => 'text',
132 // translators: %s will be replaced by service name.
133 'label' => sprintf( esc_html__( 'HS Tariff Code (%s)', 'postnl-for-woocommerce' ), $service ),
134 'description' => esc_html__( 'HS Tariff Code is a number assigned to every possible commodity that can be imported or exported from any country.', 'postnl-for-woocommerce' ),
135 'desc_tip' => 'true',
136 'placeholder' => esc_html__( 'HS Code', 'postnl-for-woocommerce' ),
137 ),
138
139 );
140 }
141
142 /**
143 * Collection of hooks when initiation.
144 */
145 public function init_hooks() {
146 add_action( 'woocommerce_product_options_shipping', array( $this, 'additional_product_shipping_options' ), 8 );
147 add_action( 'woocommerce_process_product_meta', array( $this, 'save_additional_product_parent_options' ) );
148 add_action( 'woocommerce_variation_options_pricing', array( $this, 'additional_product_variation_shipping_options' ), 10, 3 );
149 add_action( 'woocommerce_save_product_variation', array( $this, 'save_additional_product_variation_options' ), 10, 2 );
150 add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_product_edit_script' ) );
151 add_action( 'woocommerce_before_product_object_save', array( $this, 'validate_conflicting_options' ), 100, 1 );
152 }
153
154 /**
155 * Enqueue JS file in product single page.
156 */
157 public function enqueue_admin_product_edit_script() {
158 if ( ! is_admin() ) {
159 return;
160 }
161
162 wp_enqueue_script(
163 'admin-product-single',
164 POSTNL_WC_PLUGIN_DIR_URL . '/assets/js/admin-product-single.js',
165 array( 'jquery' ),
166 POSTNL_WC_VERSION,
167 true
168 );
169 }
170
171 /**
172 * Add the meta box for shipment info on the product page.
173 *
174 * @access public
175 */
176 public function additional_product_shipping_options() {
177 $fields = self::product_field_maps( $this->service );
178 Utils::fields_generator( $fields );
179 }
180
181 /**
182 * Add the meta box for shipment info on the product variation.
183 *
184 * @param int $loop Iteration of the product variations.
185 * @param Array $variation_data Variation data.
186 * @param Array $variation Variation object.
187 *
188 * @access public
189 */
190 public function additional_product_variation_shipping_options( $loop, $variation_data, $variation ) {
191 if ( empty( $variation->ID ) ) {
192 return;
193 }
194
195 $product = wc_get_product( $variation->ID );
196
197 if ( empty( $product ) ) {
198 return;
199 }
200
201 $fields = self::product_field_maps( $this->service );
202 $variation_fields = array();
203
204 foreach ( $fields as $field ) {
205 $field['value'] = $product->get_meta( $field['id'] );
206 $field['id'] = $field['id'] . '[' . $loop . ']';
207 $variation_fields[] = $field;
208 }
209
210 Utils::fields_generator( $variation_fields );
211 }
212
213 /**
214 * Saving meta box in product admin page.
215 *
216 * @param int $product_id Product post ID.
217 * @param int $i Iteration of product variations.
218 */
219 public function save_additional_product_shipping_options( $product_id, $i = '' ) {
220 $product = wc_get_product( $product_id );
221
222 if ( empty( $product ) ) {
223 \WC_Admin_Meta_Boxes::add_error( esc_html__( 'Product ID does not exists!', 'postnl-for-woocommerce' ) );
224 return;
225 }
226
227 $fields = self::product_field_maps( $this->service );
228
229 foreach ( $fields as $field ) {
230 if ( ! isset( $_POST[ $field['id'] ] ) ) {
231 $product->delete_meta_data( $field['id'] );
232 continue;
233 }
234
235 if ( ( '' === $i ) && ! is_array( $_POST[ $field['id'] ] ) && 0 === $product->get_parent_id() ) {
236 $product->update_meta_data( $field['id'], sanitize_text_field( wp_unslash( $_POST[ $field['id'] ] ) ) );
237 } elseif ( ! ( '' === $i ) && 0 !== $product->get_parent_id() ) {
238 $field_value = ! empty( $_POST[ $field['id'] ][ $i ] ) ? $_POST[ $field['id'] ][ $i ] : '';
239 $product->update_meta_data( $field['id'], sanitize_text_field( wp_unslash( $field_value ) ) );
240 }
241 }
242
243 $product->save();
244 }
245
246 /**
247 * Saving meta box in product admin page.
248 *
249 * @param int $product_id Product post ID.
250 */
251 public function save_additional_product_parent_options( $product_id ) {
252 $this->save_additional_product_shipping_options( $product_id );
253 }
254
255 /**
256 * Saving meta box in product admin page.
257 *
258 * @param int $product_id Product post ID.
259 * @param int $i Iteration of product variations.
260 */
261 public function save_additional_product_variation_options( $product_id, $i ) {
262 $this->save_additional_product_shipping_options( $product_id, $i );
263 }
264
265 /**
266 * Prevent a product from being marked as both "18+" and "Letterbox Parcel".
267 *
268 * @param \WC_Product $product Current product object.
269 */
270 public static function validate_conflicting_options( WC_Product $product ) {
271 // Read the current meta values.
272 $is_adult = Utils::is_adults_only_product( $product );
273 $is_letterbox = Utils::is_letterbox_parcel_product( $product );
274
275 // If both check-boxes are turned on, remove letterbox metadata.
276 if ( $is_adult && $is_letterbox ) {
277 $product->delete_meta_data( self::LETTERBOX_PARCEL );
278 $product->save_meta_data();
279
280 // Show a notice in the admin screen.
281 WC_Admin_Meta_Boxes::add_error(
282 __( '“18+” and “Letterbox Parcel” cannot be enabled together. Letterbox has been disabled automatically.', 'postnl-for-woocommerce' )
283 );
284 }
285 }
286 }
287