PluginProbe
Orderable – Restaurant & Food Ordering System / 1.19.0
Orderable – Restaurant & Food Ordering System v1.19.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 / modules / location / admin / class-location-admin.php

class-location-admin.php in Orderable – Restaurant & Food Ordering System 1.19.0, at inc/modules/location/admin/class-location-admin.php

496 lines 15.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Module: Location.
4 *
5 * @package Orderable/Classes
6 */
7
8 defined( 'ABSPATH' ) || exit;
9
10 /**
11 * Addons module class.
12 */
13 class Orderable_Location_Admin {
14 /**
15 * Init.
16 */
17 public static function run() {
18 add_action( 'init', array( __CLASS__, 'load_classes' ) );
19 add_action( 'current_screen', array( __CLASS__, 'save_data' ) );
20 add_action( 'admin_menu', array( __CLASS__, 'add_settings_page' ) );
21 add_action( 'admin_enqueue_scripts', array( __CLASS__, 'load_styles' ) );
22 add_action( 'admin_enqueue_scripts', array( __CLASS__, 'load_scripts' ) );
23 add_filter( 'orderable_onboard_settings_saved', array( __CLASS__, 'onboard_settings_saved' ) );
24
25 add_filter( 'orderable_valid_admin_pages', array( __CLASS__, 'add_valid_admin_pages' ) );
26 }
27
28 /**
29 * Load classes.
30 *
31 * @return void
32 */
33 public static function load_classes() {
34 $meta_boxes = array(
35 'location-store-address-meta-box' => 'Orderable_Location_Store_Address_Meta_Box',
36 'location-open-hours-meta-box' => 'Orderable_Location_Open_Hours_Meta_Box',
37 'location-store-services-meta-box' => 'Orderable_Location_Store_Services_Meta_Box',
38 'location-order-options-meta-box' => 'Orderable_Location_Order_Options_Meta_Box',
39 'location-holidays-meta-box' => 'Orderable_Location_Holidays_Meta_Box',
40 );
41
42 Orderable_Helpers::load_classes(
43 $meta_boxes,
44 'location/admin/meta-boxes',
45 ORDERABLE_MODULES_PATH
46 );
47 }
48
49 /**
50 * Check if we should load the assets.
51 *
52 * @param string $asset_type The type of asset:`styles` or `scripts`.
53 * @return boolean
54 */
55 protected static function should_load_assets( $asset_type ) {
56 if ( ! function_exists( 'get_current_screen' ) ) {
57 return false;
58 }
59
60 $current_screen = get_current_screen();
61
62 if ( empty( $current_screen->id ) ) {
63 return false;
64 }
65
66 /**
67 * Filter the pages allowed to load the location assets.
68 *
69 * @since 1.18.0
70 * @hook orderable_location_allowed_pages_to_load_assets
71 * @param array $allowed_pages The allowed pages.
72 * @param string $asset_type The type of asset:`styles` or `scripts`.
73 * @param string $current_screen_id The ID of screen.
74 * @return array New value
75 */
76 $allowed_pages = apply_filters(
77 'orderable_location_allowed_pages_to_load_assets',
78 array(
79 'orderable_page_orderable-location',
80 'orderable_page_orderable-delivery-zones',
81 'edit-orderable_locations',
82 'woocommerce_page_wc-settings',
83 ),
84 $asset_type,
85 $current_screen->id
86 );
87
88 return is_array( $allowed_pages ) && in_array( $current_screen->id, $allowed_pages, true );
89 }
90
91 /**
92 * Enqueue admin styles.
93 *
94 * @return void
95 */
96 public static function load_styles() {
97 if ( ! self::should_load_assets( 'styles' ) ) {
98 return;
99 }
100
101 $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
102
103 wp_register_style(
104 'jquery-ui-css',
105 ORDERABLE_URL . 'inc/vendor/wp-settings-framework/assets/vendor/jquery-ui/jquery-ui.css',
106 array(),
107 ORDERABLE_VERSION
108 );
109
110 wp_enqueue_style(
111 'orderable-location-css',
112 ORDERABLE_URL . 'inc/modules/location/assets/admin/css/location' . $suffix . '.css',
113 array( 'woocommerce_admin_styles', 'jquery-ui-css' ),
114 ORDERABLE_VERSION
115 );
116 }
117
118 /**
119 * Enqueue admin scripts.
120 *
121 * @return void
122 */
123 public static function load_scripts() {
124 if ( ! self::should_load_assets( 'scripts' ) ) {
125 return;
126 }
127
128 $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
129
130 wp_enqueue_script(
131 'orderable-location-js',
132 ORDERABLE_URL . 'inc/modules/location/assets/admin/js/main' . $suffix . '.js',
133 array( 'wc-enhanced-select', 'jquery-ui-datepicker' ),
134 ORDERABLE_VERSION,
135 true
136 );
137
138 wp_localize_script(
139 'orderable-location-js',
140 'orderable_dz_js_vars',
141 array(
142 'ajax_url' => admin_url( 'admin-ajax.php' ),
143 'nonce' => wp_create_nonce( 'orderable-dz-nonce' ),
144 'action' => 'orderable_dz_crud',
145 'text' => array(
146 'modal_add' => esc_html__( 'Add Delivery Zone', 'orderable-pro' ),
147 'modal_update' => esc_html__( 'Update Delivery Zone', 'orderable-pro' ),
148 'zone_title' => esc_html__( 'Delivery Zone', 'orderable-pro' ),
149 'zone_edit' => esc_html__( 'Edit', 'orderable-pro' ),
150 'zone_remove' => esc_html__( 'Remove', 'orderable-pro' ),
151 'zone_confirm_remove' => esc_html__( 'Are you sure you want to remove this zone?', 'orderable-pro' ),
152 'zone_confirm_delete' => esc_html__( 'Are you sure you want to delete this zone?', 'orderable-pro' ),
153 'successfully_added' => esc_html__( 'successfully added!', 'orderable-pro' ),
154 'successfully_updated' => esc_html__( 'successfully updated!', 'orderable-pro' ),
155 'successfully_removed' => esc_html__( 'successfully removed!', 'orderable-pro' ),
156 ),
157 )
158 );
159 }
160
161 /**
162 * Add valid admin page.
163 *
164 * @param array $pages The admin pages slug.
165 */
166 public static function add_valid_admin_pages( $pages = array() ) {
167 $pages[] = 'orderable-location';
168
169 return $pages;
170 }
171
172 /**
173 * Add settings page.
174 */
175 public static function add_settings_page() {
176 add_submenu_page(
177 'orderable',
178 __( 'Location', 'orderable' ),
179 __( 'Location', 'orderable' ),
180 'manage_options',
181 'orderable-location',
182 array( __CLASS__, 'page_content' ),
183 3
184 );
185 }
186
187 /**
188 * Page content.
189 */
190 public static function page_content() {
191 if ( ! current_user_can( 'manage_options' ) ) {
192 wp_die( esc_html__( 'You do not have sufficient permissions to access this page.', 'orderable' ) );
193 }
194 ?>
195 <div class="wrap">
196 <h1 class="wp-heading-inline">
197 <?php echo esc_html__( 'Location', 'orderable' ); ?>
198 </h1>
199
200 <form method="post">
201 <?php self::save_location_nonce_field(); ?>
202 <div id="poststuff">
203 <div id="post-body" class="metabox-holder columns-2">
204 <div id="post-body-content">
205 <?php self::metabox_ui_wrapper( Orderable_Location_Store_Address_Meta_Box::class ); ?>
206 <?php self::metabox_ui_wrapper( Orderable_Location_Open_Hours_Meta_Box::class ); ?>
207 <?php self::metabox_ui_wrapper( Orderable_Location_Store_Services_Meta_Box::class ); ?>
208 <?php self::metabox_ui_wrapper( Orderable_Location_Order_Options_Meta_Box::class ); ?>
209 <?php self::metabox_ui_wrapper( Orderable_Location_Holidays_Meta_Box::class ); ?>
210 </div>
211 <div id="postbox-container-1" class="postbox-container">
212 <div id="major-publishing-actions" style="overflow: hidden; margin-bottom: 20px; border: 1px solid #DCDCDE;">
213 <button class="button button-primary button-large" type="submit">
214 <?php echo esc_html__( 'Save Changes', 'orderable' ); ?>
215 </button>
216 </div>
217
218 <div class="orderable-cta">
219 <h3 class="orderable-cta__title"><?php _e( 'Unlock Multi-Location Power with Orderable Pro', 'orderable' ); ?></h3>
220 <p class="orderable-cta__description"><?php _e( 'Manage multiple locations effortlessly with Orderable Pro, perfect for businesses with more than one location. Take control of your delivery and pickup services like never before.', 'orderable' ); ?></p>
221 <p><a href="<?php echo esc_url( Orderable_Helpers::get_pro_url( 'multi-location', 'pricing' ) ); ?>" class="orderable-admin-button orderable-admin-button--pro" target="_blank"><span class="dashicons dashicons-star-filled"></span> <?php _e( 'Upgrade Now', 'orderable' ); ?></a></p>
222 <p><?php _e( 'or', 'orderable' ); ?> <a href="<?php echo esc_url( Orderable_Helpers::get_pro_url( 'multi-location' ) ); ?>" target="_blank"><?php _e( 'learn more', 'orderable' ); ?></a></p>
223 </div>
224 </div>
225 </div>
226 </div>
227 </form>
228 </div>
229 <?php
230 }
231
232 /**
233 * Add meta box HTML elements wrapper.
234 *
235 * @param string $meta_box_class The meta box class.
236 * @return void
237 */
238 public static function metabox_ui_wrapper( $meta_box_class ) {
239 if ( ! class_exists( $meta_box_class ) ) {
240 return;
241 }
242
243 if ( ! is_callable( $meta_box_class, 'output' ) ) {
244 return;
245 }
246
247 $title = is_callable( $meta_box_class, 'get_title' ) ? call_user_func( array( $meta_box_class, 'get_title' ) ) : '';
248 ?>
249 <div id="<?php echo esc_attr( strtolower( $meta_box_class ) ); ?>" class="postbox">
250 <div class="postbox-header">
251 <h2>
252 <?php echo esc_html( $title ); ?>
253 </h2>
254 </div>
255 <div class="inside">
256 <?php call_user_func( array( $meta_box_class, 'output' ) ); ?>
257 </div>
258 </div>
259 <?php
260 }
261
262 /**
263 * Save the orderable location data.
264 *
265 * @return void
266 */
267 public static function save_data() {
268 global $post;
269
270 if ( ! function_exists( 'get_current_screen' ) ) {
271 return;
272 }
273
274 $current_screen = get_current_screen();
275
276 if ( empty( $current_screen->id ) ) {
277 return;
278 }
279
280 if (
281 'orderable_page_orderable-location' !== $current_screen->id &&
282 ( empty( $post ) || 'orderable_locations' !== $post->post_type )
283 ) {
284 return;
285 }
286
287 if ( empty( $_POST ) || ! check_admin_referer( 'orderable_location_save', '_wpnonce_orderable_location' ) ) {
288 return;
289 }
290
291 /**
292 * Filter the location data to be saved.
293 *
294 * @since 1.8.0
295 * @hook orderable_location_get_save_data
296 * @param array $data The data to be saved.
297 * @return array New value
298 */
299 $data = apply_filters( 'orderable_location_get_save_data', get_option( 'orderable_settings', array() ) );
300
301 if ( empty( $data ) ) {
302 return;
303 }
304
305 /**
306 * Fires when location data is saved.
307 *
308 * @since 1.8.0
309 * @hook orderable_location_save_data
310 * @param array $data The location data.
311 */
312 do_action( 'orderable_location_save_data', $data );
313
314 self::clear_location_data_cache( $data );
315 }
316
317 /**
318 * Clear location cache when updated.
319 *
320 * @param array $data The data saved.
321 * @return void
322 */
323 protected static function clear_location_data_cache( $data ) {
324 global $post;
325
326 $post_id = ! empty( $post ) ? $post->ID : null;
327 $location_id = Orderable_Location::get_location_id( $post_id );
328
329 if ( empty( $location_id ) ) {
330 return;
331 }
332
333 $location_data_cache_key = 'orderable_get_location_data_' . $location_id;
334 $time_slots_cache_key = 'orderable_time_slots_' . $location_id;
335
336 wp_cache_delete( $location_data_cache_key );
337 wp_cache_delete( $time_slots_cache_key . '_delivery' );
338 wp_cache_delete( $time_slots_cache_key . '_pickup' );
339 wp_cache_delete( 'orderable_zones' );
340
341 foreach ( WC_Shipping_Zones::get_zones() as $zone ) {
342 wp_cache_delete( 'orderable_time_slots_for_zone_' . $zone['zone_id'] );
343 wp_cache_delete( "has_zone_{$location_id}_{$zone['zone_id']}_true" );
344 wp_cache_delete( "has_zone_{$location_id}_{$zone['zone_id']}_false" );
345 wp_cache_delete( "{$time_slots_cache_key}_delivery_{$zone['zone_id']}" );
346 wp_cache_delete( "{$time_slots_cache_key}_pickup_{$zone['zone_id']}" );
347 }
348
349 if ( empty( $data['store_general_service_hours_delivery'] ) || ! is_array( $data['store_general_service_hours_delivery'] ) ) {
350 return;
351 }
352
353 foreach ( $data['store_general_service_hours_delivery'] as $time_slot ) {
354 if ( empty( $time_slot['time_slot_id'] ) ) {
355 continue;
356 }
357
358 wp_cache_delete( 'orderable_zones_time_slot_' . $time_slot['time_slot_id'] );
359 }
360 }
361
362 /**
363 * Output a nonce field to save the location data.
364 *
365 * @return void
366 */
367 public static function save_location_nonce_field() {
368 wp_nonce_field( 'orderable_location_save', '_wpnonce_orderable_location' );
369 }
370
371 /**
372 * Get the field value sent via POST.
373 *
374 * @param string $field_name The field name to retrieve.
375 * @return string
376 */
377 public static function get_posted_value( $field_name ) {
378 $nonce = empty( $_POST['_wpnonce_orderable_location'] ) ? false : sanitize_text_field( wp_unslash( $_POST['_wpnonce_orderable_location'] ) );
379
380 if ( ! wp_verify_nonce( $nonce, 'orderable_location_save' ) ) {
381 return '';
382 }
383
384 if ( ! is_string( $field_name ) || empty( $_POST[ $field_name ] ) ) {
385 return '';
386 }
387
388 return sanitize_text_field( wp_unslash( $_POST[ $field_name ] ) );
389 }
390
391 /**
392 * Add location data when onboard settings are saved.
393 *
394 * @param array $fields Field data.
395 */
396 public static function onboard_settings_saved( $fields = array() ) {
397 $orderable_fields = isset( $fields['orderable_settings'] ) ? $fields['orderable_settings'] : array();
398
399 if ( empty( $orderable_fields ) ) {
400 return;
401 }
402
403 global $wpdb;
404
405 // Format open days.
406 $open_days = ! empty( $orderable_fields['iconic_onboard_days'] ) ? array_map( 'absint', $orderable_fields['iconic_onboard_days'] ) : array();
407
408 // Create an array with 7 items, each containing $orderable_fields['iconic_onboard_open_hours'].
409 $posted_open_hours = ! empty( $orderable_fields['iconic_onboard_open_hours'] ) ? $orderable_fields['iconic_onboard_open_hours'] : array();
410
411 if ( ! empty( $posted_open_hours ) ) {
412 $posted_open_hours['enabled'] = false;
413 $posted_open_hours['max_orders'] = '';
414
415 $open_hours = array_fill( 0, 7, $posted_open_hours );
416
417 // Update the 'enabled' key for each day based on the existence of the day key in $open_days
418 foreach ( $open_hours as $day_key => $day_data ) {
419 $open_hours[ $day_key ]['enabled'] = in_array( $day_key, $open_days, true );
420 }
421 }
422
423 $data = array(
424 'override_default_open_hours' => 1,
425 'open_hours' => maybe_serialize( $open_hours ),
426 'delivery' => ! empty( $orderable_fields['iconic_onboard_services'] ) && in_array( 'flat_rate', $orderable_fields['iconic_onboard_services'], true ),
427 'pickup' => ! empty( $orderable_fields['iconic_onboard_services'] ) && in_array( 'local_pickup', $orderable_fields['iconic_onboard_services'], true ),
428 'address_line_1' => isset( $orderable_fields['iconic_onboard_business_address'] ) ? $orderable_fields['iconic_onboard_business_address'] : '',
429 'address_line_2' => isset( $orderable_fields['iconic_onboard_business_address_2'] ) ? $orderable_fields['iconic_onboard_business_address_2'] : '',
430 'city' => isset( $orderable_fields['iconic_onboard_business_city'] ) ? $orderable_fields['iconic_onboard_business_city'] : '',
431 'country_state' => isset( $orderable_fields['iconic_onboard_default_country'] ) ? $orderable_fields['iconic_onboard_default_country'] : '',
432 'postcode_zip' => isset( $orderable_fields['iconic_onboard_business_postcode'] ) ? $orderable_fields['iconic_onboard_business_postcode'] : '',
433 'is_main_location' => 1,
434 );
435
436 // Get main location ID.
437 $main_location_id = Orderable_Location::get_main_location_id();
438
439 if ( empty( $main_location_id ) ) {
440 $update = $wpdb->insert(
441 $wpdb->orderable_locations,
442 $data
443 );
444 } else {
445 $update = $wpdb->update(
446 $wpdb->orderable_locations,
447 $data,
448 array(
449 'location_id' => $main_location_id,
450 ),
451 null,
452 array(
453 'location_id' => '%d',
454 )
455 );
456 }
457
458 if ( ! $update || is_wp_error( $update ) ) {
459 return;
460 }
461
462 if ( ! empty( $open_hours ) && ! empty( $open_days ) ) {
463 $main_location_id = $main_location_id ? $main_location_id : Orderable_Location::get_main_location_id();
464
465 // Check if any time slots exists for this location.
466 $existing_time_slots = intval(
467 $wpdb->get_var(
468 $wpdb->prepare(
469 "SELECT COUNT(*) FROM {$wpdb->orderable_location_time_slots} WHERE location_id = %d",
470 $main_location_id
471 )
472 )
473 );
474
475 // If not, let's add one.
476 if ( $existing_time_slots <= 0 ) {
477 $wpdb->insert(
478 $wpdb->orderable_location_time_slots,
479 array(
480 'location_id' => $main_location_id,
481 'service_type' => 'delivery',
482 'days' => maybe_serialize( array_map( 'strval', $open_days ) ),
483 'period' => 'all-day',
484 'time_from' => '',
485 'time_to' => '',
486 'frequency' => '',
487 'cutoff' => '',
488 'max_orders' => '',
489 'has_zones' => 0,
490 )
491 );
492 }
493 }
494 }
495 }
496