PluginProbe
Product Labels, Quick View, Buy Now, Pre-Orders, Frequently Bought Together & More for WooCommerce – Merchant / trunk
Product Labels, Quick View, Buy Now, Pre-Orders, Frequently Bought Together & More for WooCommerce – Merchant vtrunk
2.3.1 2.3.0 2.2.8 2.2.7 trunk 1.10.0 1.10.1 1.10.2 1.10.3 1.10.4 1.10.5 1.11.0 1.11.1 1.11.2 1.6 1.7 1.8 1.8.1 1.8.2 1.8.3 1.9.0 1.9.1 1.9.10 1.9.11 1.9.12 All 59 releases
merchant / admin / classes / class-merchant-admin-options.php

class-merchant-admin-options.php in Product Labels, Quick View, Buy Now, Pre-Orders, Frequently Bought Together & More for WooCommerce – Merchant trunk, at admin/classes/class-merchant-admin-options.php

406 lines 11.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Merchant Admin Options.
4 *
5 * Thin orchestrator that manages module settings. Delegates rendering
6 * to {@see Merchant_Settings_Renderer}, saving to {@see Merchant_Settings_Saver},
7 * asset enqueueing to {@see Merchant_Admin_Assets}, and Select2 data
8 * to {@see Merchant_Select2_Choices}.
9 *
10 * @package Merchant
11 * @since 1.0
12 */
13
14 if ( ! defined( 'ABSPATH' ) ) {
15 exit; // Exit if accessed directly
16 }
17
18 if ( ! class_exists( 'Merchant_Admin_Options' ) ) {
19 /**
20 * Merchant_Admin_Options
21 *
22 * Orchestrates the Merchant admin settings panel. Core responsibilities:
23 * - CRUD operations for module settings (`get`, `set`, `delete`, `get_all`)
24 * - Wiring admin hooks (assets, cache, cleanup, Pro activation)
25 * - Backward-compatible facades that delegate to extracted classes
26 *
27 * This class is a singleton; use {@see Merchant_Admin_Options::instance()} to retrieve it.
28 *
29 * @since 1.0
30 */
31 class Merchant_Admin_Options {
32
33 /**
34 * The single class instance.
35 *
36 * @since 1.0
37 * @var Merchant_Admin_Options|null
38 */
39 private static $instance = null;
40
41 /**
42 * Get the singleton instance.
43 *
44 * @since 1.0
45 *
46 * @return Merchant_Admin_Options
47 */
48 public static function instance() {
49 if ( is_null( self::$instance ) ) {
50 self::$instance = new self();
51 }
52
53 return self::$instance;
54 }
55
56 /**
57 * Constructor.
58 *
59 * Registers admin hooks for script enqueueing, cache clearance,
60 * legacy data cleanup, and Pro plugin activation.
61 *
62 * @since 1.0
63 */
64 public function __construct() {
65 $assets = new Merchant_Admin_Assets();
66 $choices = new Merchant_Select2_Choices();
67
68 add_action( 'admin_enqueue_scripts', array( $assets, 'enqueue_scripts' ) );
69 add_action( 'clean_user_cache', array( $choices, 'clear_customer_choices_cache' ), 10, 2 );
70
71 add_action( 'admin_init', array( $this, 'delete_module_data' ) );
72 add_action( 'admin_init', array( $this, 'activate_pro_plugin' ) );
73 }
74
75 // ──────────────────────────────────────────────────────
76 // CRUD — core orchestrator responsibility.
77 // ──────────────────────────────────────────────────────
78
79 /**
80 * Get a single module setting value.
81 *
82 * Retrieves the value of a specific setting for a given module
83 * from the `merchant` option. Falls back to `$default_val` if
84 * the setting does not exist.
85 *
86 * @since 1.0
87 *
88 * @param string $module The module ID (e.g. 'buy-x-get-y').
89 * @param string $setting The setting key within the module.
90 * @param mixed $default_val The default value if the setting is not found.
91 *
92 * @return mixed The setting value, filtered via `merchant_get_option`.
93 */
94 public static function get( $module, $setting, $default_val ) {
95 $options = get_option( 'merchant', array() );
96
97 $value = $default_val;
98
99 if ( isset( $options[ $module ][ $setting ] ) ) {
100 $value = $options[ $module ][ $setting ];
101 }
102
103 /**
104 * Hook: merchant_get_option filter.
105 * Fires after getting module option.
106 *
107 * @param mixed $value Option value.
108 * @param string $module Module ID.
109 * @param string $setting Setting ID.
110 * @param mixed $default_val Default value.
111 *
112 * @since 1.9.3
113 */
114 return apply_filters( 'merchant_get_option', $value, $module, $setting, $default_val );
115 }
116
117 /**
118 * Set a single module setting value.
119 *
120 * @since 1.0
121 *
122 * @param string $module The module ID.
123 * @param string $setting The setting key.
124 * @param mixed $value The value to store.
125 *
126 * @return void
127 */
128 public static function set( $module, $setting, $value ) {
129 $options = get_option( 'merchant', array() );
130 $options[ $module ][ $setting ] = $value;
131 update_option( 'merchant', $options );
132 }
133
134 /**
135 * Delete a single module setting.
136 *
137 * @since 1.0
138 *
139 * @param string $module The module ID.
140 * @param string $setting The setting key to remove.
141 *
142 * @return void
143 */
144 public static function delete( $module, $setting ) {
145 $options = get_option( 'merchant', array() );
146 unset( $options[ $module ][ $setting ] );
147 update_option( 'merchant', $options );
148 }
149
150 /**
151 * Get all settings for a module.
152 *
153 * @since 1.0
154 *
155 * @param string $module The module ID.
156 *
157 * @return array All settings for the module.
158 */
159 public static function get_all( $module ) {
160 $options = get_option( 'merchant', array() );
161 $value = array();
162
163 if ( isset( $options[ $module ] ) ) {
164 $value = $options[ $module ];
165 }
166
167 return $value;
168 }
169
170 // ──────────────────────────────────────────────────────
171 // Delegation facades — backward compatibility.
172 // ──────────────────────────────────────────────────────
173
174 /**
175 * Create and render a module settings panel.
176 *
177 * @since 1.0
178 * @see Merchant_Settings_Renderer::create()
179 *
180 * @param array $settings Module settings configuration.
181 *
182 * @return void
183 */
184 public static function create( $settings ) {
185 Merchant_Settings_Renderer::create( $settings );
186 }
187
188 /**
189 * Render a single field.
190 *
191 * @since 1.0
192 * @see Merchant_Settings_Renderer::field()
193 *
194 * @param array $settings The field configuration array.
195 * @param mixed $value The current saved value.
196 * @param string $module_id The module ID.
197 *
198 * @return void
199 */
200 public static function field( $settings, $value, $module_id = '' ) {
201 Merchant_Settings_Renderer::field( $settings, $value, $module_id );
202 }
203
204 /**
205 * Render a disabled (pro-gated) field.
206 *
207 * @since 1.0
208 * @see Merchant_Settings_Renderer::disabled_field()
209 *
210 * @param array $settings Field settings.
211 * @param mixed $value Field value.
212 * @param string $module_id Module ID.
213 *
214 * @return void
215 */
216 public static function disabled_field( $settings, $value, $module_id = '' ) {
217 Merchant_Settings_Renderer::disabled_field( $settings, $value, $module_id );
218 }
219
220 /**
221 * Save module options from a form submission.
222 *
223 * @since 1.0
224 * @see Merchant_Settings_Saver::save_options()
225 *
226 * @param array $settings Module settings configuration.
227 *
228 * @return void
229 */
230 public static function save_options( $settings ) {
231 Merchant_Settings_Saver::save_options( $settings );
232 }
233
234 /**
235 * Sanitize options.
236 *
237 * @since 1.9.3
238 * @see Merchant_Settings_Saver::sanitize()
239 *
240 * @param array $field The field configuration.
241 * @param mixed $value The raw submitted value.
242 *
243 * @return mixed The sanitized value.
244 */
245 public static function sanitize( $field, $value ) {
246 return Merchant_Settings_Saver::sanitize( $field, $value );
247 }
248
249 /**
250 * Get product category choices for Select2.
251 *
252 * @since 1.9.3
253 * @see Merchant_Select2_Choices::get_category_select2_choices()
254 *
255 * @return array Formatted category choices.
256 */
257 public static function get_category_select2_choices() {
258 return Merchant_Select2_Choices::get_category_select2_choices();
259 }
260
261 /**
262 * Get product tag choices for Select2.
263 *
264 * @since 1.9.3
265 * @see Merchant_Select2_Choices::get_tag_select2_choices()
266 *
267 * @return array Formatted tag choices.
268 */
269 public static function get_tag_select2_choices() {
270 return Merchant_Select2_Choices::get_tag_select2_choices();
271 }
272
273 /**
274 * Get product brand choices for Select2.
275 *
276 * @since 1.9.3
277 * @see Merchant_Select2_Choices::get_brand_select2_choices()
278 *
279 * @return array Formatted brand choices.
280 */
281 public static function get_brand_select2_choices() {
282 return Merchant_Select2_Choices::get_brand_select2_choices();
283 }
284
285 /**
286 * Get user role choices for Select2.
287 *
288 * @since 1.9.3
289 * @see Merchant_Select2_Choices::get_user_roles_select2_choices()
290 *
291 * @return array Formatted role choices.
292 */
293 public static function get_user_roles_select2_choices() {
294 return Merchant_Select2_Choices::get_user_roles_select2_choices();
295 }
296
297 /**
298 * Get customer user choices for Select2.
299 *
300 * @since 1.9.3
301 * @see Merchant_Select2_Choices::get_customers_select2_choices()
302 *
303 * @return array Formatted customer choices.
304 */
305 public static function get_customers_select2_choices() {
306 return Merchant_Select2_Choices::get_customers_select2_choices();
307 }
308
309 // ──────────────────────────────────────────────────────
310 // Admin hooks — small one-off actions.
311 // ──────────────────────────────────────────────────────
312
313 /**
314 * Delete stale module data from the database.
315 *
316 * Cleans up data for removed modules (e.g., the deprecated
317 * `code-snippets` module). Hooked to `admin_init`.
318 *
319 * @since 1.9.3
320 *
321 * @return void
322 */
323 public function delete_module_data() {
324 $options = get_option( 'merchant', array() );
325
326 if ( isset( $options['code-snippets'] ) ) {
327 unset( $options['code-snippets'] );
328 update_option( 'merchant', $options );
329 }
330 }
331
332 /**
333 * Activate the Merchant Pro plugin.
334 *
335 * Handles the `merchant_activate_pro` admin action: verifies
336 * nonce and capabilities, activates the Pro plugin, and
337 * redirects back to the originating Merchant page.
338 *
339 * @since 1.0
340 *
341 * @return void
342 */
343 public function activate_pro_plugin() {
344 if ( ! isset( $_GET['action'] ) || 'merchant_activate_pro' !== $_GET['action'] ) {
345 return;
346 }
347
348 if (
349 ! isset( $_GET['nonce'] )
350 || ! wp_verify_nonce(
351 sanitize_text_field( wp_unslash( $_GET['nonce'] ) ),
352 'merchant_activate_pro'
353 )
354 ) {
355 return;
356 }
357
358 if ( ! current_user_can( 'activate_plugins' ) ) {
359 return;
360 }
361
362 $result = activate_plugin( 'merchant-pro/merchant-pro.php' );
363
364 if ( is_wp_error( $result ) ) {
365 wp_die( esc_html( $result->get_error_message() ) );
366 }
367
368 wp_safe_redirect( $this->get_safe_merchant_redirect_url() );
369 exit;
370 }
371
372 /**
373 * Get a safe redirect URL pointing to a Merchant admin page.
374 *
375 * Validates the HTTP referer is a Merchant page. Falls back
376 * to the main Merchant dashboard if the referer is invalid
377 * or points to a non-Merchant page.
378 *
379 * @since 1.9.3
380 *
381 * @return string Safe redirect URL.
382 */
383 private function get_safe_merchant_redirect_url() {
384 $fallback_url = admin_url( 'admin.php?page=merchant' );
385 $referer = wp_get_referer();
386 $redirect_to = wp_validate_redirect( $referer, $fallback_url );
387
388 if ( $redirect_to === $fallback_url ) {
389 return $fallback_url;
390 }
391
392 $parsed_url = wp_parse_url( $redirect_to );
393 $query_params = array();
394 parse_str( $parsed_url['query'] ?? '', $query_params );
395
396 if ( empty( $query_params['page'] ) || strpos( $query_params['page'], 'merchant' ) !== 0 ) {
397 return $fallback_url;
398 }
399
400 return $redirect_to;
401 }
402 }
403
404 Merchant_Admin_Options::instance();
405 }
406