PluginProbe
Sendy / 3.4.5
Sendy v3.4.5
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 / lib / Modules / Admin / Settings.php

Settings.php in Sendy 3.4.5, at lib/Modules/Admin/Settings.php

269 lines 8.6 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\Admin;
4
5 use Sendy\Api\ApiException;
6 use Sendy\WooCommerce\ApiClientFactory;
7 use Sendy\WooCommerce\Enums\ProcessingMethod;
8 use Sendy\WooCommerce\Modules\Admin\Fields\Checkbox;
9 use Sendy\WooCommerce\Modules\Admin\Fields\Dropdown;
10 use Sendy\WooCommerce\Plugin;
11 use Sendy\WooCommerce\Repositories\Shops;
12 use Sendy\WooCommerce\Utils\View;
13
14 class Settings
15 {
16 public function __construct()
17 {
18 if (! is_admin()) {
19 return;
20 }
21
22 add_action('admin_enqueue_scripts', [$this, 'enqueue_assets']);
23
24 add_action('admin_menu', [$this, 'register_menu']);
25 add_action('admin_init', [$this, 'register_settings']);
26 add_action('admin_init', [$this, 'logout_action']);
27 }
28
29 public function enqueue_assets(): void
30 {
31 wp_enqueue_script(
32 'sendy-admin-settings',
33 SENDY_WC_PLUGIN_DIR_URL . '/resources/js/admin-settings.js',
34 [],
35 Plugin::VERSION,
36 true,
37 );
38 }
39
40 /**
41 * Add the settings page for the module as a submenu item for the WooCommerce menu
42 */
43 public function register_menu(): void
44 {
45 add_submenu_page(
46 'woocommerce',
47 __('Sendy', 'sendy'),
48 __('Sendy', 'sendy'),
49 'manage_woocommerce',
50 'sendy',
51 [$this, 'render_settings_page'],
52 );
53 }
54
55 /**
56 * Render the settings page
57 */
58 public function render_settings_page(): void
59 {
60 $name = null;
61
62 if (sendy_is_authenticated()) {
63 try {
64 $result = ApiClientFactory::buildConnectionUsingTokens()->me->get();
65
66 $name = $result['name'];
67 } catch (ApiException $e) {
68 // When this action fails, it will be because the access token is invalid. The best option is to null
69 // the access token option and restart the authentication process from the start. Only resetting the
70 // access token is sufficient as it will not generate multiple instances of the WooCommerce integration
71 // in the Sendy application
72 update_option('sendy_access_token', null, false);
73 }
74 }
75
76 echo wp_kses(
77 View::fromTemplate('admin/settings.php')->render(['name' => $name]),
78 View::ALLOWED_TAGS,
79 );
80 }
81
82 public function register_settings(): void
83 {
84 $slug = 'sendy';
85
86 add_settings_section('sendy_section_id', '', '', $slug);
87
88 register_setting('sendy_general_settings', 'sendy_import_weight', fn($value) => $value === 'true');
89 register_setting('sendy_general_settings', 'sendy_import_products', fn($value) => $value === 'true');
90
91 register_setting('sendy_general_settings', 'sendy_mark_order_as_completed', [
92 'sanitize_callback' => function ($value): string {
93 $possibleValues = [
94 'manually',
95 'after-shipment-created',
96 'after-label-printed',
97 'after-shipment-delivered',
98 ];
99
100 if (! in_array($value, $possibleValues)) {
101 return 'manually';
102 }
103
104 return $value;
105 },
106 ]);
107
108 register_setting('sendy_general_settings', 'sendy_processing_method', [
109 'sanitize_callback' => function ($value): string {
110 if (! in_array($value, ProcessingMethod::cases())) {
111 return ProcessingMethod::WooCommerce;
112 }
113
114 return $value;
115 },
116 ]);
117
118 register_setting('sendy_general_settings', 'sendy_processable_order_status', [
119 'sanitize_callback' => function ($value): string {
120 $orderStatuses = wc_get_order_statuses();
121
122 $possibleValues = [];
123
124 foreach ($orderStatuses as $status => $label) {
125 // The 'wc-' prefix is stripped as it is intended only for WooCommerce internally.
126 $possibleValues[] = str_replace('wc-', '', $status);
127 }
128
129 if (! in_array($value, $possibleValues)) {
130 return $possibleValues[0];
131 }
132
133 return $value;
134 },
135 ]);
136
137 register_setting('sendy_general_settings', 'sendy_default_shop', fn($value) => $value);
138
139 add_settings_field(
140 'sendy_processing_method',
141 __('Processing method', 'sendy'),
142 [$this, 'render_processing_method_dropdown'],
143 $slug,
144 'sendy_section_id',
145 );
146
147 $hidden = get_option('sendy_processing_method') !== ProcessingMethod::Sendy ? 'hidden' : '';
148
149 add_settings_field(
150 'sendy_processable_order_status',
151 __('Send order to Sendy when status changed to', 'sendy'),
152 [$this, 'render_processable_order_status_dropdown'],
153 $slug,
154 'sendy_section_id',
155 ['class' => "sendy-processing-method-field {$hidden}"],
156 );
157
158 add_settings_field(
159 'sendy_default_shop',
160 __('Shop to use when orders are sent to Sendy', 'sendy'),
161 [$this, 'render_default_shop_dropdown'],
162 $slug,
163 'sendy_section_id',
164 ['class' => "sendy-processing-method-field {$hidden}"],
165 );
166
167 add_settings_field(
168 'sendy_import_weight',
169 __('Import weight', 'sendy'),
170 [$this, 'render_import_weight_field'],
171 $slug,
172 'sendy_section_id',
173 );
174
175 add_settings_field(
176 'sendy_import_products',
177 __('Import products', 'sendy'),
178 [$this, 'render_import_products_field'],
179 $slug,
180 'sendy_section_id',
181 );
182
183 add_settings_field(
184 'sendy_mark_order_as_completed',
185 __('Mark order as completed', 'sendy'),
186 [$this, 'render_status_after_shipping_field'],
187 $slug,
188 'sendy_section_id',
189 );
190 }
191
192 public function render_import_weight_field(): void
193 {
194 (new Checkbox('sendy_import_weight', __('Import weight when creating a shipment', 'sendy')))->render();
195 }
196
197 public function render_import_products_field(): void
198 {
199 (new Checkbox('sendy_import_products', __('Send products to Sendy when creating a shipment', 'sendy')))->render();
200 }
201
202 public function render_status_after_shipping_field(): void
203 {
204 $options = [
205 'manually' => __('Manually', 'sendy'),
206 'after-shipment-created' => __('After the shipment is created', 'sendy'),
207 ];
208
209 if (get_option('sendy_processing_method') === ProcessingMethod::WooCommerce) {
210 $options['after-label-printed'] = __('After the label is printed', 'sendy');
211 }
212
213 if (get_option('sendy_processing_method') === ProcessingMethod::Sendy) {
214 $options['after-shipment-delivered'] = __('After the shipment is delivered', 'sendy');
215 }
216
217 (new Dropdown('sendy_mark_order_as_completed'))->render(['options' => $options]);
218 }
219
220 public function render_processing_method_dropdown(): void
221 {
222 $options = ProcessingMethod::casesWithDescription();
223
224 (new Dropdown('sendy_processing_method'))->render(['options' => $options]);
225 }
226
227 public function render_processable_order_status_dropdown(): void
228 {
229 $orderStatuses = wc_get_order_statuses();
230
231 $options = [];
232
233 foreach ($orderStatuses as $status => $label) {
234 // The 'wc-' prefix is stripped as it is intended only for WooCommerce internally.
235 $status = str_replace('wc-', '', $status);
236
237 $options[$status] = $label;
238 }
239
240 (new Dropdown('sendy_processable_order_status'))->render(['options' => $options]);
241 }
242
243 public function render_default_shop_dropdown(): void
244 {
245 $options = (new Shops())->list();
246
247 (new Dropdown('sendy_default_shop'))->render(['options' => $options]);
248 }
249
250 public function logout_action(): void
251 {
252 if (isset($_GET['sendy_logout'])) {
253 if (! current_user_can('manage_woocommerce')) {
254 wp_die(esc_html__('You do not have sufficient permissions to access this page.', 'sendy'), 403);
255 }
256
257 if (! wp_verify_nonce($_GET['_wpnonce'] ?? '', 'sendy_logout')) {
258 wp_die(esc_html__('Nonce verification failed.', 'sendy'), 401);
259 }
260
261 update_option('sendy_access_token', null, false);
262
263 wp_safe_redirect(admin_url('admin.php?page=sendy'));
264 exit;
265 }
266 }
267
268 }
269