PluginProbe
Orderable – Restaurant & Food Ordering System / 0.2.0
Orderable – Restaurant & Food Ordering System v0.2.0
0.1.4 0.1.5 0.2.0 1.0.0 1.1.0 1.1.1 1.10.0 1.10.1 1.11.0 1.12.0 1.12.1 1.12.2 1.13.0 1.14.0 1.15.0 1.16.0 1.17.0 1.17.1 1.18.0 1.19.0 1.19.1 1.19.2 1.2.0 1.20.0 1.20.1 All 44 releases
orderable / inc / class-settings.php

class-settings.php in Orderable – Restaurant & Food Ordering System 0.2.0, at inc/class-settings.php

784 lines 28.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Settings methods.
4 *
5 * @package Orderable/Classes
6 */
7
8 defined( 'ABSPATH' ) || exit;
9
10 /**
11 * Settings class.
12 */
13 class Orderable_Settings {
14 /**
15 * Settings framework instance.
16 *
17 * @var null|Orderable_Settings_Framework
18 */
19 public static $settings_framework = null;
20
21 /**
22 * Settings.
23 *
24 * @var array
25 */
26 public static $settings = array();
27
28 /**
29 * Option group.
30 *
31 * @var string
32 */
33 protected static $option_group = 'orderable';
34
35 /**
36 * Run.
37 */
38 public static function run() {
39 add_action( 'init', array( __CLASS__, 'init_settings' ) );
40 add_filter( 'plugin_action_links_' . ORDERABLE_BASENAME, array( __CLASS__, 'plugin_settings_link' ) );
41 add_action( 'init', array( __CLASS__, 'init_onboarding' ) );
42 add_action( 'admin_menu', array( __CLASS__, 'add_settings_page' ), 1 );
43 add_filter( 'orderable_default_settings', array( __CLASS__, 'default_settings' ) );
44 add_filter( 'wpsf_register_settings_orderable', array( __CLASS__, 'register_settings' ) );
45 add_filter( 'wpsf_register_settings_orderable', array( __CLASS__, 'reorder_settings_tabs' ), 200 );
46 add_filter( 'iconic_onboard_save_orderable_result', array( __CLASS__, 'save_onboard_settings' ), 10, 2 );
47 add_filter( 'wpsf_title_orderable', array( __CLASS__, 'settings_logo' ) );
48 add_action( 'wpsf_after_title_orderable', array( __CLASS__, 'version_number' ) );
49
50 // Add category fields.
51 add_action( 'product_cat_add_form_fields', array( __CLASS__, 'add_category_fields' ), 20 );
52 add_action( 'product_cat_edit_form_fields', array( __CLASS__, 'edit_category_fields' ), 20 );
53 add_action( 'created_term', array( __CLASS__, 'save_category_fields' ), 10, 3 );
54 add_action( 'edit_term', array( __CLASS__, 'save_category_fields' ), 10, 3 );
55 }
56
57 /**
58 * Init settings.
59 */
60 public static function init_settings() {
61 require_once ORDERABLE_VENDOR_PATH . 'wp-settings-framework/wp-settings-framework.php';
62
63 self::$settings_framework = new Orderable_Settings_Framework( null, self::$option_group );
64 self::$settings = self::$settings_framework->get_settings();
65 }
66
67 /**
68 * Add settings page link to plugin listing.
69 *
70 * @param array $links
71 *
72 * @return array
73 */
74 public static function plugin_settings_link( $links = array() ) {
75 $settings_url = admin_url( 'admin.php?page=orderable-settings' );
76 $links[] = sprintf( '<a href="%s">%s</a>', esc_url( $settings_url ), esc_html( __( 'Settings', 'orderable' ) ) );
77
78 return $links;
79 }
80
81 /**
82 * Add settings page.
83 */
84 public static function add_settings_page() {
85 $icon = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQ0IiBoZWlnaHQ9IjE4MyIgdmlld0JveD0iMCAwIDI0NCAxODMiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+DQo8cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTE5MC40NzggMTY2LjdDMjI3LjM2MiAxNDIuNzEgMjUzLjI3MSA5MS44NDM4IDI0MC44NTYgNTYuMzA5NUMyMjguNDQyIDIwLjk1NTcgMTc3LjUyMyAwLjkzMzgzNSAxMjMuNzI3IDAuMDMxOTUxNEM3MC4xMDk3IC0wLjg2OTkzMyAxMy42MTQgMTcuMzQ4MSAyLjI3ODkxIDUxLjI1OUMtOS4yMzYxMyA4NS4xNjk4IDI0LjU4OTMgMTM0Ljk1NCA2NS40MzE3IDE2MS4yODlDMTA2LjA5NCAxODcuNjI0IDE1My43NzQgMTkwLjY5IDE5MC40NzggMTY2LjdaTTE4My4yMzQgNzguNzIwNkMxODMuMjM0IDgzLjkyNDEgMTc4LjEwOCA5MS42Mjg3IDE2Ny4zNDggOTEuNjI4N0MxNTYuNTg4IDkxLjYyODcgMTUxLjQ2MyA4My45MjQxIDE1MS40NjMgNzguNzIwNkMxNTEuNDYzIDczLjUxNzIgMTU2LjU4OCA2NS44MTI2IDE2Ny4zNDggNjUuODEyNkMxNzguMTA4IDY1LjgxMjYgMTgzLjIzNCA3My41MTcyIDE4My4yMzQgNzguNzIwNlpNMTY5LjExOCAxMjQuNjk3QzE5NS4zNDkgMTIzLjgyMiAyMTYuMzI4IDEwMy41NzIgMjE2LjMyOCA3OC43MjA2QzIxNi4zMjggNTMuMzEyNCAxOTQuMzk5IDMyLjcxNSAxNjcuMzQ4IDMyLjcxNUMxNjcuMjU3IDMyLjcxNSAxNjcuMTY3IDMyLjcxNTMgMTY3LjA3NiAzMi43MTU3SDg2LjczNUM4MS42NjMgMzIuNzE1NyA3Ny41NTEyIDM2LjgzNTIgNzcuNTUxMiA0MS45MTY4Qzc3LjU1MTIgNDYuOTk4NSA4MS42NjMgNTEuMTE4IDg2LjczNSA1MS4xMThIMTI4LjE2TDEyOC4xNDQgNTEuMTM3MUMxMzIuOTQyIDUxLjQ1MTEgMTM2LjczNiA1NS40NDE3IDEzNi43MzYgNjAuMzE4M0MxMzYuNzM2IDY1LjQgMTMyLjYxNiA2OS41MTk1IDEyNy41MzQgNjkuNTE5NUgxMTkuMzQ4TDExOS4zNDggNjkuNTIwMkg1My4wNjExQzQ3Ljk4OTEgNjkuNTIwMiA0My44NzczIDczLjYzOTcgNDMuODc3MyA3OC43MjEzQzQzLjg3NzMgODMuODAyOSA0Ny45ODkxIDg3LjkyMjQgNTMuMDYxMSA4Ny45MjI0SDEyNy42NTJDMTMyLjY4IDg3Ljk4NTQgMTM2LjczNiA5Mi4wODA0IDEzNi43MzYgOTcuMTIyOEMxMzYuNzM2IDEwMiAxMzIuOTQyIDEwNS45OSAxMjguMTQ0IDEwNi4zMDRMMTI4LjE2MSAxMDYuMzI1SDc0LjQ5QzY5LjQxNzkgMTA2LjMyNSA2NS4zMDYyIDExMC40NDQgNjUuMzA2MiAxMTUuNTI2QzY1LjMwNjIgMTIwLjYwNyA2OS40MTc5IDEyNC43MjcgNzQuNDkgMTI0LjcyN0gxNjguMzY5QzE2OC42MjEgMTI0LjcyNyAxNjguODcxIDEyNC43MTcgMTY5LjExOCAxMjQuNjk3Wk0xNTAuODY0IDEzNy41NDVDMTUyLjA2NSAxNDEuMTE4IDE0OS41NTggMTQ2LjIzMyAxNDUuOTg4IDE0OC42NDZDMTQyLjQzNSAxNTEuMDU4IDEzNy44MjEgMTUwLjc1IDEzMy44ODUgMTQ4LjEwMkMxMjkuOTMyIDE0NS40NTQgMTI2LjY1OSAxNDAuNDQ3IDEyNy43NzMgMTM3LjAzN0MxMjguODcgMTMzLjYyNyAxMzQuMzM4IDEzMS43OTUgMTM5LjUyNyAxMzEuODg2QzE0NC43MzQgMTMxLjk3NyAxNDkuNjYyIDEzMy45OSAxNTAuODY0IDEzNy41NDVaTTE2MS42NzYgMTM3LjU0NUMxNjAuNDc0IDE0MS4xMTggMTYyLjk4MiAxNDYuMjMzIDE2Ni41NTIgMTQ4LjY0NkMxNzAuMTA0IDE1MS4wNTggMTc0LjcxOSAxNTAuNzUgMTc4LjY1NCAxNDguMTAyQzE4Mi42MDcgMTQ1LjQ1NCAxODUuODgxIDE0MC40NDcgMTg0Ljc2NiAxMzcuMDM3QzE4My42NjkgMTMzLjYyNyAxNzguMjAyIDEzMS43OTUgMTczLjAxMiAxMzEuODg2QzE2Ny44MDYgMTMxLjk3NyAxNjIuODc3IDEzMy45OSAxNjEuNjc2IDEzNy41NDVaIiBmaWxsPSIjOUNBMUE4Ii8+DQo8L3N2Zz4=';
86
87 add_menu_page( 'Orderable', 'Orderable', 'manage_options', 'orderable', null, $icon, 54 );
88
89 self::$settings_framework->add_settings_page(
90 array(
91 'parent_slug' => 'orderable',
92 'page_title' => __( 'Orderable Settings', 'orderable' ),
93 'menu_title' => __( 'Settings', 'orderable' ),
94 'capability' => 'manage_options',
95 )
96 );
97
98 remove_submenu_page( 'orderable', 'orderable' );
99 }
100
101 /**
102 * Add default settings.
103 *
104 * @param array $default_settings
105 *
106 * @return array
107 */
108 public static function default_settings( $default_settings = array() ) {
109 $default_settings['style_style_color'] = '#000000';
110 $default_settings['style_style_buttons'] = 'rounded';
111 $default_settings['style_products_title_size'] = 20;
112 $default_settings['style_products_price_size'] = 18;
113
114 return $default_settings;
115 }
116
117 /**
118 * Register settings.
119 *
120 * @param array $settings
121 *
122 * @return array
123 */
124 public static function register_settings( $settings = array() ) {
125 $settings = array(
126 'tabs' => array(),
127 'sections' => array(),
128 );
129
130 $settings['tabs'] = array(
131 array(
132 'id' => 'dashboard',
133 'title' => __( 'Dashboard', 'orderable' ),
134 'priority' => 0,
135 ),
136 array(
137 'id' => 'style',
138 'title' => __( 'Style', 'orderable' ),
139 'priority' => 100,
140 ),
141 );
142
143 $settings['sections']['style'] = array(
144 'tab_id' => 'style',
145 'section_id' => 'style',
146 'section_title' => __( 'General', 'orderable' ),
147 'section_description' => '',
148 'section_order' => 10,
149 'fields' => array(
150 'color' => array(
151 'id' => 'color',
152 'title' => __( 'Brand Color', 'orderable' ),
153 'subtitle' => __( 'Select an accent color to be used for buttons and other elements.', 'orderable' ),
154 'type' => 'color',
155 'default' => self::get_setting_default( 'style_style_color' ),
156 ),
157 'buttons' => array(
158 'id' => 'buttons',
159 'title' => __( 'Button Style', 'orderable' ),
160 'subtitle' => __( 'Choose a button style which suits your theme.', 'orderable' ),
161 'type' => 'select',
162 'default' => self::get_setting_default( 'style_style_buttons' ),
163 'choices' => array(
164 'rounded' => __( 'Rounded', 'orderable' ),
165 'square' => __( 'Square', 'orderable' ),
166 ),
167 ),
168 ),
169 );
170
171 $settings['sections']['products_style'] = array(
172 'tab_id' => 'style',
173 'section_id' => 'products',
174 'section_title' => __( 'Product Cards', 'orderable' ),
175 'section_description' => '',
176 'section_order' => 15,
177 'fields' => array(
178 'title_size' => array(
179 'id' => 'title_size',
180 'title' => __( 'Product Title Size (px)', 'orderable' ),
181 'subtitle' => __( 'Set the product title font size in pixels.', 'orderable' ),
182 'type' => 'number',
183 'default' => Orderable_Settings::get_setting_default( 'style_products_title_size' ),
184 ),
185 'price_size' => array(
186 'id' => 'price_size',
187 'title' => __( 'Product Price Size (px)', 'orderable' ),
188 'subtitle' => __( 'Set the product price font size in pixels.', 'orderable' ),
189 'type' => 'number',
190 'default' => Orderable_Settings::get_setting_default( 'style_products_price_size' ),
191 ),
192 ),
193 );
194
195 return $settings;
196 }
197
198 /**
199 * Reorder settings tabs.
200 *
201 * @param array $settings
202 *
203 * @return array
204 */
205 public static function reorder_settings_tabs( $settings = array() ) {
206 usort( $settings['tabs'], function ( $a, $b ) {
207 $a['priority'] = empty( $a['priority'] ) ? 0 : absint( $a['priority'] );
208 $b['priority'] = empty( $b['priority'] ) ? 0 : absint( $b['priority'] );
209
210 return $a['priority'] - $b['priority'];
211 } );
212
213 return $settings;
214 }
215
216 /**
217 * Get setting default.
218 *
219 * @param string $setting_name
220 *
221 * @return bool|mixed
222 */
223 public static function get_setting_default( $setting_name = '' ) {
224 if ( empty( $setting_name ) ) {
225 return false;
226 }
227
228 $defaults = apply_filters( 'orderable_default_settings', array() );
229
230 if ( ! isset( $defaults[ $setting_name ] ) ) {
231 return false;
232 }
233
234 return $defaults[ $setting_name ];
235 }
236
237 /**
238 * Get setting.
239 *
240 * This method is accessible before the settings are assign to self::$settings.
241 *
242 * @param string $setting_name
243 *
244 * @return bool|mixed
245 */
246 public static function get_setting( $setting_name = '' ) {
247 if ( empty( $setting_name ) ) {
248 return false;
249 }
250
251 $settings = get_option( self::$option_group . '_settings' );
252
253 if ( isset( $settings[ $setting_name ] ) ) {
254 return $settings[ $setting_name ];
255 }
256
257 return self::get_setting_default( $setting_name );
258 }
259
260 /**
261 * @param string $suffix
262 *
263 * @return bool
264 */
265 public static function is_settings_page( $suffix = '' ) {
266 if ( ! is_admin() ) {
267 return false;
268 }
269
270 // Allow bypass from other modules.
271 if ( apply_filters( 'orderable_is_settings_page', false ) ) {
272 return true;
273 }
274
275 $valid_pages = apply_filters( 'orderable_valid_admin_pages', array(
276 self::$option_group . '-settings' . $suffix,
277 ) );
278 $page = filter_input( INPUT_GET, 'page', FILTER_SANITIZE_STRING );
279
280 if ( ! in_array( $page, $valid_pages, true ) ) {
281 return false;
282 }
283
284 return true;
285 }
286
287 /**
288 * Init onboarding.
289 */
290 public static function init_onboarding() {
291 if ( ! self::is_settings_page() || defined( 'WC_DOING_AJAX' ) ) {
292 if ( empty( $_REQUEST['plugin_slug'] ) || 'orderable' !== $_REQUEST['plugin_slug'] ) {
293 return;
294 }
295 }
296
297 include_once ORDERABLE_INC_PATH . 'vendor/iconic-onboard/class-iconic-onboard.php';
298
299 $slides = apply_filters( 'orderable_onboarding_slides', array(
300 'welcome' => array(
301 'header_image' => ORDERABLE_URL . '/assets/img/onboarding/orderable-onboarding-header.jpg',
302 'title' => 'Welcome',
303 'description' => 'Thank you for choosing Orderable to add local ordering to your website. This short setup wizard will guide you though configuring Orderable.',
304 'button_text' => 'Begin <span class="dashicons dashicons-arrow-right-alt2"></span>',
305 'button_icon' => '',
306 ),
307 'requirements' => array(
308 'title' => 'Requirements',
309 'description' => 'Orderable requires WooCommerce for the order checkout, management, and reporting. In this step we will install WooCommerce for you. This might take a couple of minutes.',
310 'button_text' => 'Install &amp; Activate WooCommerce',
311 'wait' => 'install_plugin',
312 'json_data' => array(
313 'wait_text' => __( 'Installing...', 'orderable' ),
314 'plugin_data' => array(
315 'name' => __( 'WooCommerce', 'orderable' ),
316 'repo-slug' => 'woocommerce',
317 'file' => 'woocommerce.php',
318 ),
319 ),
320 ),
321 'business' => array(
322 'title' => 'Business Info',
323 'description' => 'Orderable needs some basic business information that will be used when orders are placed.',
324 'button_text' => 'Continue <span class="dashicons dashicons-arrow-right-alt2"></span>',
325 'fields' => array(
326 'name' => array(
327 'id' => 'business_name',
328 'title' => __( 'Business Name', 'orderable' ),
329 'desc' => '',
330 'type' => 'text',
331 'default' => get_bloginfo( 'name' ),
332 ),
333 'address' => array(
334 'id' => 'business_address',
335 'title' => __( 'Address line 1', 'orderable' ),
336 'desc' => '',
337 'type' => 'text',
338 ),
339 'address_2' => array(
340 'id' => 'business_address_2',
341 'title' => __( 'Address line 2', 'orderable' ),
342 'desc' => '',
343 'type' => 'text',
344 ),
345 'city' => array(
346 'id' => 'business_city',
347 'title' => __( 'City', 'orderable' ),
348 'desc' => '',
349 'type' => 'text',
350 ),
351 'default_country' => array(
352 'id' => 'default_country',
353 'title' => __( 'Country / State', 'orderable' ),
354 'desc' => '',
355 'type' => 'select',
356 'choices' => array(),
357 ),
358 'postcode' => array(
359 'id' => 'business_postcode',
360 'title' => __( 'Postcode / ZIP', 'orderable' ),
361 'desc' => '',
362 'type' => 'text',
363 ),
364 'email' => array(
365 'id' => 'business_email',
366 'title' => __( 'Business Email', 'orderable' ),
367 'desc' => '',
368 'type' => 'text',
369 'default' => get_option( 'admin_email' ),
370 ),
371 array(
372 'id' => 'opt_in',
373 'title' => '',
374 'desc' => __( 'Please keep me up to date via email on new Orderable training and features', 'orderable' ),
375 'type' => 'checkbox',
376 'default' => 1,
377 ),
378 ),
379 ),
380 'location' => array(
381 "title" => "Location Info",
382 "description" => 'Help us set up your ordering system. You can refine these details further after completing the onboarding process.',
383 "button_text" => "Continue <span class='dashicons dashicons-arrow-right-alt2'></span>",
384 'fields' => array(
385 array(
386 'id' => 'services',
387 'title' => __( 'Which services do you offer?', 'orderable' ),
388 'desc' => '',
389 'type' => 'checkboxes',
390 'choices' => array(
391 'flat_rate' => __( 'Delivery', 'orderable' ),
392 'local_pickup' => __( 'Pickup', 'orderable' ),
393 ),
394 ),
395 array(
396 'id' => 'days',
397 'title' => __( 'Which days of the week are you open?', 'orderable' ),
398 'desc' => '',
399 'type' => 'checkboxes',
400 'choices' => array(
401 1 => __( 'Monday', 'orderable' ),
402 2 => __( 'Tuesday', 'orderable' ),
403 3 => __( 'Wednesday', 'orderable' ),
404 4 => __( 'Thursday', 'orderable' ),
405 5 => __( 'Friday', 'orderable' ),
406 6 => __( 'Saturday', 'orderable' ),
407 0 => __( 'Sunday', 'orderable' ),
408 ),
409 ),
410 array(
411 'id' => 'open_hours',
412 'title' => __( 'What are your normal opening hours?', 'orderable' ),
413 'desc' => '',
414 'type' => 'custom',
415 'default' => self::get_open_hours_fields(),
416 ),
417 ),
418 ),
419 'done' => array(
420 "title" => "All Done",
421 "description" => "Congratulations, You Did It! Orderable is ready to use on your website. You've successfully completed the setup process and all that is left for you to do is create/customize your products.",
422 "button_text" => "Save and Finish <span class='dashicons dashicons-yes'></span>",
423 ),
424 ) );
425
426 if ( function_exists( 'WC' ) ) {
427 unset( $slides['requirements'] );
428
429 $base = wc_get_base_location();
430
431 $slides['business']['fields']['default_country']['choices'] = self::get_countries_states();
432 $slides['business']['fields']['default_country']['default'] = implode( ':', array_filter( $base ) );
433 $slides['business']['fields']['address']['default'] = WC()->countries->get_base_address();
434 $slides['business']['fields']['address_2']['default'] = WC()->countries->get_base_address_2();
435 $slides['business']['fields']['city']['default'] = WC()->countries->get_base_city();
436 $slides['business']['fields']['postcode']['default'] = WC()->countries->get_base_postcode();
437 }
438
439 Orderable_Onboard::run(
440 array(
441 'version' => ORDERABLE_VERSION,
442 'plugin_slug' => 'orderable',
443 'plugin_url' => ORDERABLE_URL,
444 'plugin_path' => ORDERABLE_PATH,
445 'slides' => $slides,
446 )
447 );
448 }
449
450 /**
451 * Save the onboarding data in database.
452 *
453 * @param array $result Was the submission a success?
454 * @param array $fields Submitted fields.
455 *
456 * @return bool|array $result
457 */
458 public static function save_onboard_settings( $result, $fields ) {
459 if ( empty( $fields['orderable_settings'] ) ) {
460 return false;
461 }
462
463 // Get existing/default settings.
464 $settings = get_option( 'orderable_settings', array() );
465
466 // Assign opening hours.
467 if ( ! empty( $fields['orderable_settings']['iconic_onboard_days'] ) && is_array( $fields['orderable_settings']['iconic_onboard_days'] ) ) {
468 $from = array(
469 'hour' => filter_var( $fields['orderable_settings']['iconic_onboard_open_hours']['from']['hour'], FILTER_SANITIZE_STRING ),
470 'minute' => filter_var( $fields['orderable_settings']['iconic_onboard_open_hours']['from']['minute'], FILTER_SANITIZE_STRING ),
471 'period' => filter_var( $fields['orderable_settings']['iconic_onboard_open_hours']['from']['period'], FILTER_SANITIZE_STRING ),
472 );
473 $to = array(
474 'hour' => filter_var( $fields['orderable_settings']['iconic_onboard_open_hours']['to']['hour'], FILTER_SANITIZE_STRING ),
475 'minute' => filter_var( $fields['orderable_settings']['iconic_onboard_open_hours']['to']['minute'], FILTER_SANITIZE_STRING ),
476 'period' => filter_var( $fields['orderable_settings']['iconic_onboard_open_hours']['to']['period'], FILTER_SANITIZE_STRING ),
477 );
478
479 $settings['store_general_open_hours'] = array();
480
481 foreach ( $fields['orderable_settings']['iconic_onboard_days'] as $day ) {
482 $day = absint( $day );
483
484 if ( $day < 0 || $day > 6 ) {
485 continue;
486 }
487
488 $settings['store_general_open_hours'][ $day ] = array(
489 'enabled' => '1',
490 'from' => $from,
491 'to' => $to,
492 'max_orders' => '',
493 );
494 }
495 }
496
497 // Save Business details.
498 $name = isset( $fields['orderable_settings']['iconic_onboard_business_name'] ) ? wc_clean( wp_unslash( $fields['orderable_settings']['iconic_onboard_business_name'] ) ) : '';
499 $address = isset( $fields['orderable_settings']['iconic_onboard_business_address'] ) ? wc_clean( wp_unslash( $fields['orderable_settings']['iconic_onboard_business_address'] ) ) : '';
500 $address_2 = isset( $fields['orderable_settings']['iconic_onboard_business_address_2'] ) ? wc_clean( wp_unslash( $fields['orderable_settings']['iconic_onboard_business_address_2'] ) ) : '';
501 $city = isset( $fields['orderable_settings']['iconic_onboard_business_city'] ) ? wc_clean( wp_unslash( $fields['orderable_settings']['iconic_onboard_business_city'] ) ) : '';
502 $country_state = isset( $fields['orderable_settings']['iconic_onboard_default_country'] ) ? wc_clean( wp_unslash( $fields['orderable_settings']['iconic_onboard_default_country'] ) ) : '';
503 $stripped_country_state = $country_state ? str_replace( array( 'country:', 'state:' ), '', $country_state ) : '';
504 $postcode = isset( $fields['orderable_settings']['iconic_onboard_business_postcode'] ) ? wc_clean( wp_unslash( $fields['orderable_settings']['iconic_onboard_business_postcode'] ) ) : '';
505 $email = isset( $fields['orderable_settings']['iconic_onboard_business_email'] ) ? wc_clean( wp_unslash( $fields['orderable_settings']['iconic_onboard_business_email'] ) ) : '';
506 $opt_in = isset( $fields['orderable_settings']['iconic_onboard_opt_in'] );
507
508 if ( ! empty( $name ) ) {
509 update_option( 'blogname', $name );
510 }
511
512 update_option( 'woocommerce_store_address', $address );
513 update_option( 'woocommerce_store_address_2', $address_2 );
514 update_option( 'woocommerce_store_city', $city );
515 update_option( 'woocommerce_default_country', $stripped_country_state );
516 update_option( 'woocommerce_store_postcode', $postcode );
517 update_option( 'admin_email', $email );
518 update_option( 'orderable_opt_in', $opt_in );
519
520 // Restrict delivery area to country/state.
521 if ( ! empty( $stripped_country_state ) ) {
522 update_option( 'woocommerce_allowed_countries', 'specific' );
523 update_option( 'woocommerce_specific_allowed_countries', array( $stripped_country_state ) );
524 }
525
526 // Save store services.
527 if ( ! empty( $fields['orderable_settings']['iconic_onboard_services'] ) ) {
528 $settings['store_general_services'] = array();
529
530 $existing_zone_id = null;
531 $zone_name = __( 'Local', 'orderable' );
532 $zones = WC_Shipping_Zones::get_zones();
533
534 if ( ! empty( $zones ) ) {
535 foreach ( $zones as $zone ) {
536 if ( $zone_name !== $zone['zone_name'] ) {
537 continue;
538 }
539
540 $existing_zone_id = $zone['id'];
541 $shipping_method_instances = ! empty( $zone['shipping_methods'] ) ? array_keys( $zone['shipping_methods'] ) : false;
542 break;
543 }
544 }
545
546 $zone = new WC_Shipping_Zone( $existing_zone_id );
547 $zone->set_zone_name( $zone_name );
548
549 if ( ! empty( $country_state ) ) {
550 $zone->clear_locations();
551 $location_parts = explode( ':', $country_state );
552
553 switch ( $location_parts[0] ) {
554 case 'state':
555 $zone->add_location( $location_parts[1] . ':' . $location_parts[2], 'state' );
556 break;
557 case 'country':
558 $zone->add_location( $location_parts[1], 'country' );
559 break;
560 case 'continent':
561 $zone->add_location( $location_parts[1], 'continent' );
562 break;
563 }
564 }
565
566 if ( ! empty( $shipping_method_instances ) ) {
567 foreach ( $shipping_method_instances as $shipping_method_instance_id ) {
568 $zone->delete_shipping_method( $shipping_method_instance_id );
569 }
570 }
571
572 $service_types = array(
573 'flat_rate' => 'delivery',
574 'local_pickup' => 'pickup',
575 );
576
577 foreach ( $fields['orderable_settings']['iconic_onboard_services'] as $service ) {
578 $service = wc_clean( $service );
579 $zone->add_shipping_method( $service );
580
581 $settings['store_general_services'][] = $service_types[ $service ];
582 }
583
584 $zone->save();
585 }
586
587 // Misc.
588 $settings['store_general_service_hours_pickup_same'] = 1;
589
590 // Save settings.
591 update_option( 'orderable_settings', $settings );
592
593 // Return success.
594 return $result;
595 }
596
597 /**
598 * Get countries and states for select field.
599 *
600 * @return array
601 */
602 public static function get_countries_states() {
603 $countries_states = array();
604
605 if ( ! function_exists( 'WC' ) ) {
606 return $countries_states;
607 }
608
609 $countries = WC()->countries->get_countries();
610
611 if ( empty( $countries ) ) {
612 return $countries_states;
613 }
614
615 foreach ( $countries as $key => $value ) {
616 $countries_states[ 'country:' . $key ] = $value;
617 $states = WC()->countries->get_states( $key );
618
619 if ( empty( $states ) ) {
620 continue;
621 }
622
623 $countries_states[ $key ] = array(
624 'group_label' => $value,
625 'values' => array(),
626 );
627
628 foreach ( $states as $state_key => $state_value ) {
629 $state_key = sprintf( 'state:%s:%s', $key, $state_key );
630 $countries_states[ $key ]['values'][ $state_key ] = sprintf( '%s &mdash; %s', $value, $state_value );
631 }
632 }
633
634 return $countries_states;
635 }
636
637 /**
638 * Get open hours fields.
639 *
640 * @return string
641 */
642 public static function get_open_hours_fields() {
643 ob_start();
644 ?>
645 <div class="iconic-onboard-modal-setting__field-section">
646 <div style="margin: 0 0 8px;"><?php _e( 'From:', 'orderable' ); ?></div>
647 <?php echo Orderable_Timings_Settings::get_time_field( 'orderable_settings[iconic_onboard_open_hours][from]', array(
648 'hour' => 9,
649 'minute' => '00',
650 'period' => 'AM',
651 ) ); ?>
652 </div>
653 <div class="iconic-onboard-modal-setting__field-section">
654 <div style="margin: 0 0 8px;"><?php _e( 'To:', 'orderable' ); ?></div>
655 <?php echo Orderable_Timings_Settings::get_time_field( 'orderable_settings[iconic_onboard_open_hours][to]', array(
656 'hour' => 5,
657 'minute' => '00',
658 'period' => 'PM',
659 ) ); ?>
660 </div>
661 <?php
662
663 return ob_get_clean();
664 }
665
666 /**
667 * Category fields.
668 */
669 public static function add_category_fields() {
670 ?>
671 <div class="form-field term-display-type-wrap">
672 <label for="visibility"><?php esc_html_e( 'Visibility', 'orderable' ); ?></label>
673 <select id="visibility" name="visibility" class="postform">
674 <option value=""><?php esc_html_e( 'Default', 'orderable' ); ?></option>
675 <option value="hidden"><?php esc_html_e( 'Hidden', 'orderable' ); ?></option>
676 </select>
677 <p><?php _e( 'Choose whether to hide (on the frontend) this category archive and all single product pages within this category. Hiding them is recommended if using this category in the Orderable menu shortcode.', 'orderable' ); ?></p>
678 </div>
679 <?php
680 }
681
682 /**
683 * Edit category fields.
684 *
685 * @param mixed $term Term (category) being edited.
686 */
687 public static function edit_category_fields( $term ) {
688 $visibility = get_term_meta( $term->term_id, 'visibility', true );
689 ?>
690 <tr class="form-field term-display-type-wrap">
691 <th scope="row" valign="top">
692 <label for="visibility"><?php esc_html_e( 'Visibility', 'orderable' ); ?></label>
693 </th>
694 <td>
695 <select id="visibility" name="visibility" class="postform">
696 <option value="" <?php selected( '', $visibility ); ?>><?php esc_html_e( 'Default', 'orderable' ); ?></option>
697 <option value="hidden" <?php selected( 'hidden', $visibility ); ?>><?php esc_html_e( 'Hidden', 'orderable' ); ?></option>
698 </select>
699 <p><?php _e( 'Choose whether to hide (on the frontend) this category archive and all single product pages within this category. Hiding them is recommended if using this category in the Orderable menu shortcode.', 'orderable' ); ?></p>
700 </td>
701 </tr>
702 <?php
703 }
704
705 /**
706 * Save category fields.
707 *
708 * @param mixed $term_id Term ID being saved.
709 * @param mixed $tt_id Term taxonomy ID.
710 * @param string $taxonomy Taxonomy slug.
711 */
712 public static function save_category_fields( $term_id, $tt_id = '', $taxonomy = '' ) {
713 $visibility = filter_input( INPUT_POST, 'visibility', FILTER_SANITIZE_STRING );
714
715 if ( ! is_null( $visibility ) && 'product_cat' === $taxonomy ) {
716 update_term_meta( $term_id, 'visibility', sanitize_text_field( $visibility ) );
717 }
718 }
719
720 /**
721 * Get hidden category IDs.
722 *
723 * @return array
724 */
725 public static function get_hidden_categories() {
726 global $wpdb;
727
728 static $hidden_categories = null;
729
730 if ( ! is_null( $hidden_categories ) ) {
731 return apply_filters( 'orderable_hidden_categories', $hidden_categories );
732 }
733
734 $hidden_categories = array();
735
736 $results = $wpdb->get_results(
737 "SELECT DISTINCT tm.term_id
738 FROM $wpdb->term_taxonomy AS tt
739 INNER JOIN $wpdb->terms AS t ON tt.term_id = t.term_id
740 INNER JOIN $wpdb->termmeta AS tm ON t.term_id = tm.term_id
741 WHERE tt.taxonomy = 'product_cat'
742 AND tm.meta_key = 'visibility'
743 AND tm.meta_value IN ( 'hidden' )
744
745 UNION DISTINCT
746
747 SELECT DISTINCT term_id
748 FROM $wpdb->term_taxonomy
749 WHERE parent IN (
750 SELECT DISTINCT tm.term_id
751 FROM $wpdb->term_taxonomy AS tt
752 INNER JOIN $wpdb->terms AS t ON tt.term_id = t.term_id
753 INNER JOIN $wpdb->termmeta AS tm ON t.term_id = tm.term_id
754 WHERE tt.taxonomy = 'product_cat'
755 AND tm.meta_key = 'visibility'
756 AND tm.meta_value IN ( 'hidden' )
757 )",
758 ARRAY_A
759 );
760
761 if ( is_wp_error( $results ) || empty( $results ) ) {
762 return apply_filters( 'orderable_hidden_categories', $hidden_categories );
763 }
764
765 $hidden_categories = array_map( 'absint', wp_list_pluck( $results, 'term_id' ) );
766
767 return apply_filters( 'orderable_hidden_categories', $hidden_categories );
768 }
769
770 /**
771 * Add logo to settings page.
772 */
773 public static function settings_logo( $title = '' ) {
774 return sprintf( '<img src="%s" width="164" height="36" />', esc_url( ORDERABLE_ASSETS_URL . 'img/orderable-logo.svg' ) );
775 }
776
777 /**
778 * Add version number to settings page.
779 */
780 public static function version_number() {
781 printf( '<span style="margin: 0 0 0 auto; background: #f4f5f6; display: inline-block; padding: 0 10px; border-radius: 13px; height: 26px; line-height: 26px; white-space: nowrap; box-sizing: border-box; color: #65707b;">v%s</span>', ORDERABLE_VERSION );
782 }
783 }
784