PluginProbe
Sendy / 3.2.4
Sendy v3.2.4
3.4.6 3.4.7 trunk 3.0 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.1 3.1.2 3.1.3 3.2.0 3.2.1 3.2.2 3.2.3 3.2.4 3.2.5 3.2.6 3.2.7 All 32 releases
sendy / src / Modules / Checkout.php

Checkout.php in Sendy 3.2.4, at src/Modules/Checkout.php

192 lines 6.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Sendy\WooCommerce\Modules;
4
5 use Sendy\WooCommerce\Plugin;
6 use Sendy\WooCommerce\Utils\View;
7 use WP_Error;
8
9 final class Checkout
10 {
11 public function __construct()
12 {
13 add_action('wp_enqueue_scripts', [$this, 'enqueue_assets']);
14 add_action('woocommerce_review_order_after_shipping', [$this, 'render_pickup_point_field'], 10);
15
16 add_action('wp_ajax_sendy_set_pickup_point', [$this, 'store_selected_pickup_point_in_session']);
17 add_action('wp_ajax_nopriv_sendy_set_pickup_point', [$this, 'store_selected_pickup_point_in_session']);
18
19 add_action('woocommerce_checkout_create_order', [$this, 'store_selected_pickup_point_in_order'], 10, 3);
20
21 add_action('woocommerce_order_details_after_customer_address', [$this, 'show_selected_pickup_point_on_confirmation'], 10, 2);
22
23 add_action('woocommerce_after_checkout_validation', [$this, 'validate_pickup_point'], 10, 2);
24 }
25
26 /**
27 * Load the assets, but only on the checkout page
28 *
29 * @return void
30 */
31 public function enqueue_assets(): void
32 {
33 if (is_checkout()) {
34 wp_enqueue_script('wp-util');
35 wp_enqueue_script('sendy-api', 'https://app.sendy.nl/embed/api.js', [], Plugin::VERSION, ['in_footer' => true]);
36 wp_enqueue_script('sendy-checkout', SENDY_WC_PLUGIN_DIR_URL . '/resources/js/checkout.js', ['jquery', 'sendy-api'], Plugin::VERSION, ['in_footer' => true]);
37 }
38 }
39
40 /**
41 * Render the button to select a pick-up point in the checkout
42 *
43 * @return void
44 */
45 public function render_pickup_point_field(): void
46 {
47 if (in_array('sendy_pickup_point', wc_get_chosen_shipping_method_ids())) {
48 if (!is_null($this->get_shipping_method_instance_id())) {
49 $carrier = $this->get_carrier_for_shipping_method($this->get_shipping_method_instance_id());
50
51 $selectedPickupPoint = WC()->session->get("sendy_selected_parcelshop_{$this->get_shipping_method_instance_id()}");
52
53 echo wp_kses(
54 View::fromTemplate('checkout/pickup_point_selection.php')->render([
55 'carrier' => $carrier,
56 'instance_id' => $this->get_shipping_method_instance_id(),
57 'selected_pickup_point' => $selectedPickupPoint,
58 ]),
59 View::ALLOWED_TAGS
60 );
61 }
62 }
63 }
64
65 /**
66 * Store the selected pickup point in the session
67 *
68 * @return void
69 */
70 public function store_selected_pickup_point_in_session(): void
71 {
72 if (empty($_REQUEST['nonce']) || !wp_verify_nonce(sanitize_key($_REQUEST['nonce']), 'sendy_store_pickup_point')) {
73 wp_send_json_error('Nonce verification failed');
74 }
75
76 $data = [
77 'id' => sanitize_text_field(wp_unslash(isset($_REQUEST['id']) ? $_REQUEST['id'] : '')),
78 'name' => sanitize_text_field(wp_unslash(isset($_REQUEST['name']) ? $_REQUEST['name'] : '')),
79 'street' => sanitize_text_field(wp_unslash(isset($_REQUEST['street']) ? $_REQUEST['street'] : '')),
80 'number' => sanitize_text_field(wp_unslash(isset($_REQUEST['number']) ? $_REQUEST['number'] : '')),
81 'postal_code' => sanitize_text_field(wp_unslash(isset($_REQUEST['postal_code']) ? $_REQUEST['postal_code'] : '')),
82 'city' => sanitize_text_field(wp_unslash(isset($_REQUEST['city']) ? $_REQUEST['city'] : ''))
83 ];
84
85 WC()->session->set('sendy_selected_parcelshop_' . sanitize_key($_REQUEST['instance_id'] ?? ''), $data);
86
87 wp_send_json_success();
88 }
89
90 /**
91 * Add the selected pickup point to the order metadata
92 *
93 * @param \WC_Order $order
94 * @return void
95 */
96 public function store_selected_pickup_point_in_order(\WC_Order $order): void
97 {
98 $instanceId = $this->get_shipping_method_instance_id();
99
100 if ($data = WC()->session->get("sendy_selected_parcelshop_{$instanceId}")) {
101
102 $order->update_meta_data('_sendy_pickup_point_id', $data['id']);
103 $order->update_meta_data('_sendy_pickup_point_data', $data);
104
105 WC()->session->set("sendy_selected_parcelshop_{$instanceId}", null);
106 }
107 }
108
109 /**
110 * Display the address of the selected pickup point on the order confirmation page
111 *
112 * @param string $addressType
113 * @param \WC_Order $order
114 * @return void
115 */
116 public function show_selected_pickup_point_on_confirmation(string $addressType, \WC_Order $order): void
117 {
118 if ($addressType === 'shipping' && $order->meta_exists('_sendy_pickup_point_id')) {
119 echo wp_kses(
120 View::fromTemplate('checkout/order_confirmation.php')->render([
121 'pickup_point' => $order->get_meta('_sendy_pickup_point_data')
122 ]),
123 View::ALLOWED_TAGS
124 );
125 }
126 }
127
128 /**
129 * Validate if the pickup point is selected
130 *
131 * @param array $fields
132 * @param WP_Error $errors
133 */
134 public function validate_pickup_point(array $fields, WP_Error $errors): void
135 {
136 if (in_array('sendy_pickup_point', wc_get_chosen_shipping_method_ids())) {
137 $instanceId = $this->get_shipping_method_instance_id();
138
139 if (empty($instanceId)) {
140 $errors->add('sendy_pickup_point_error', __('Please select a pick-up point.', 'sendy'));
141 } else {
142 $selectedPickupPoint = WC()->session->get("sendy_selected_parcelshop_{$instanceId}");
143
144 if (empty($selectedPickupPoint)) {
145 $errors->add('sendy_pickup_point_error', __('Please select a pick-up point.', 'sendy'));
146 }
147 }
148 }
149 }
150
151 /**
152 * Get the instance id of the selected shipment method
153 *
154 * This ID is used to correctly store the selected pickup point and makes it possible to offer pickup point delivery
155 * for multiple carriers.
156 *
157 * @return int|null
158 */
159 private function get_shipping_method_instance_id(): ?int
160 {
161 $selectedMethods = WC()->session->get('chosen_shipping_methods') ?? [];
162
163 $pickupPointDelivery = array_filter(
164 $selectedMethods,
165 function ($item) { return str_starts_with($item, 'sendy_pickup_point'); }
166 );
167
168 if (count($pickupPointDelivery) > 0) {
169 [$name, $instanceId] = explode(':', $pickupPointDelivery[0]);
170
171 return (int) $instanceId;
172 }
173
174 return null;
175 }
176
177 /**
178 * Get the carrier for the shipping method
179 *
180 * This method is used to load the correct pick-up points for a carrier in the checkout
181 *
182 * @param int $instance_id
183 * @return string|null
184 */
185 private function get_carrier_for_shipping_method(int $instance_id): ?string
186 {
187 $options = get_option("woocommerce_sendy_pickup_point_{$instance_id}_settings");
188
189 return $options['carrier'] ?? null;
190 }
191 }
192