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 / live-view / class-live-view.php

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

361 lines 10.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Module: Live View.
4 *
5 * @package Orderable/Classes
6 */
7
8 defined( 'ABSPATH' ) || exit;
9
10 use Automattic\WooCommerce\Utilities\OrderUtil;
11
12 /**
13 * Live View module class.
14 */
15 class Orderable_Live_View {
16 /**
17 * Init.
18 */
19 public static function run() {
20 add_action( 'admin_enqueue_scripts', array( __CLASS__, 'admin_assets' ) );
21 add_action( 'admin_enqueue_scripts', array( __CLASS__, 'remove_filters' ) );
22 add_filter( 'heartbeat_received', array( __CLASS__, 'heartbeat_received' ), 10, 2 );
23 add_action( 'admin_footer', array( __CLASS__, 'add_live_view_button' ), 100 );
24 add_action( 'admin_footer', array( __CLASS__, 'embed_ding' ) );
25 add_action( 'restrict_manage_posts', array( __CLASS__, 'output_filter_orders_nonce_field' ), 50 );
26 add_action( 'restrict_manage_posts', array( __CLASS__, 'live_view_input' ), 60 );
27 // HPOS Compatibility.
28 add_action( 'woocommerce_order_list_table_restrict_manage_orders', array( __CLASS__, 'output_filter_orders_nonce_field' ), 50 );
29 add_action( 'woocommerce_order_list_table_restrict_manage_orders', array( __CLASS__, 'live_view_input' ), 60 );
30 add_action( 'admin_menu', array( __CLASS__, 'add_settings_page' ) );
31 add_action( 'init', array( __CLASS__, 'create_order_manager_role' ) );
32 add_action( 'current_screen', array( __CLASS__, 'restrict_order_manager_role_access' ) );
33 }
34
35 /**
36 * Is order live view.
37 *
38 * @return bool
39 */
40 public static function is_live_view() {
41 return self::is_orders_page() && isset( $_GET['orderable_live_view'] );
42 }
43
44 /**
45 * Is order page.
46 *
47 * @return bool
48 */
49 public static function is_orders_page() {
50 if ( ! function_exists( 'get_current_screen' ) ) {
51 return false;
52 }
53
54 $screen = get_current_screen();
55
56 if ( empty( $screen ) ) {
57 return false;
58 }
59
60 // HPOS Compatibility.
61 if ( OrderUtil::custom_orders_table_usage_is_enabled() ) {
62 return 'woocommerce_page_wc-orders' === $screen->id;
63 }
64
65 return 'edit' === $screen->base && 'shop_order' === $screen->post_type;
66 }
67
68 /**
69 * Enqueue Admin assets.
70 *
71 * @return void
72 */
73 public static function admin_assets() {
74 if ( ! self::is_live_view() ) {
75 return;
76 }
77
78 $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
79
80 // JS.
81 wp_enqueue_script( 'heartbeat' );
82 wp_enqueue_script( 'orderable-live-view-admin', ORDERABLE_URL . 'inc/modules/live-view/assets/admin/js/main' . $suffix . '.js', [ 'heartbeat', 'jquery' ], ORDERABLE_VERSION, true );
83
84 $order_page_url = OrderUtil::custom_orders_table_usage_is_enabled() ? admin_url( 'admin.php?orderable_live_view&page=wc-orders' ) : admin_url( 'edit.php?orderable_live_view&post_type=shop_order' );
85
86 $params = array(
87 'last_order_id' => self::get_last_order_id(),
88 'filtered_service' => Orderable_Services_Order::get_filtered_service(),
89 'filtered_due_date' => Orderable_Timings_Order::get_filtered_due_date(),
90 'orderby' => empty( $_GET['orderby'] ) ? '' : sanitize_text_field( wp_unslash( $_GET['orderby'] ) ), // phpcs:ignore WordPress.Security.NonceVerification
91 'url' => $order_page_url,
92 );
93
94 wp_localize_script( 'orderable-live-view-admin', 'orderable_live_view_vars', $params );
95
96 // CSS.
97 wp_enqueue_style( 'orderable-live-view-admin', ORDERABLE_URL . 'inc/modules/live-view/assets/admin/css/live-view' . $suffix . '.css', [], ORDERABLE_VERSION );
98 }
99
100 /**
101 * Remove order list filters.
102 */
103 public static function remove_filters() {
104 if ( ! self::is_live_view() ) {
105 return;
106 }
107
108 global $wc_list_table;
109
110 remove_action( 'restrict_manage_posts', array( $wc_list_table, 'restrict_manage_posts' ) );
111 }
112
113 /**
114 * Add to heartbeat response.
115 *
116 * @param array $response
117 * @param array $data
118 *
119 * @return mixed
120 */
121 public static function heartbeat_received( $response, $data ) {
122 if ( ! isset( $data['orderable_heartbeat'] ) || 'orderable_live_view' !== $data['orderable_heartbeat'] ) {
123 return $response;
124 }
125
126 $response['orderable'] = array(
127 'last_order_id' => self::get_last_order_id(),
128 'filtered_service' => $data['orderable_filtered_service'],
129 'due_date' => $data['orderable_filtered_due_date'],
130 );
131
132 return $response;
133 }
134
135 /**
136 * Get last order ID.
137 *
138 * @return int
139 */
140 public static function get_last_order_id() {
141 add_filter(
142 'woocommerce_order_data_store_cpt_get_orders_query',
143 array( __CLASS__, 'add_location_id_in_order_meta_query' ),
144 10,
145 2
146 );
147
148 // phpcs:ignore WordPress.Security.NonceVerification
149 $location_id = empty( $_POST['data']['orderable_location_id'] ) ? '' : sanitize_text_field( wp_unslash( $_POST['data']['orderable_location_id'] ) );
150
151 $orders = wc_get_orders(
152 array(
153 'limit' => 1,
154 'orderable_location_id' => $location_id,
155 )
156 );
157
158 remove_filter(
159 'woocommerce_order_data_store_cpt_get_orders_query',
160 array( __CLASS__, 'add_location_id_in_order_meta_query' )
161 );
162
163 if ( empty( $orders ) ) {
164 return 0;
165 }
166
167 return $orders[0]->get_id();
168 }
169
170 /**
171 * Update the order meta query to filter by location ID.
172 *
173 * @param array $query WP_Query args from WC_Order_Query.
174 * @param array $query_vars query vars from a WC_Order_Query.
175 * @return array
176 */
177 public static function add_location_id_in_order_meta_query( $query, $query_vars ) {
178 if ( empty( $query_vars['orderable_location_id'] ) ) {
179 return $query;
180 }
181
182 $location_id = $query_vars['orderable_location_id'];
183
184 $meta_query_args = array(
185 'key' => '_orderable_location_id',
186 );
187
188 $meta_query_args['value'] = $location_id;
189
190 $query['meta_query'][] = $meta_query_args;
191
192 return $query;
193 }
194
195 /**
196 * Embed ding sound.
197 */
198 public static function embed_ding() {
199 if ( ! self::is_live_view() ) {
200 return;
201 }
202
203 /**
204 * Allows to override the notification audio file.
205 */
206 $audio_url = apply_filters( 'orderable_live_view_new_order_audio_file_url', esc_url( ORDERABLE_URL ) . 'inc/modules/live-view/assets/audio/ding.wav' );
207 ?>
208 <audio id="orderable_ding" src="<?php echo esc_attr( $audio_url ); ?>" type="audio/wav"></audio>
209 <?php
210 }
211
212 /**
213 * Add live_view button.
214 */
215 public static function add_live_view_button() {
216 if ( ! function_exists( 'get_current_screen' ) ) {
217 return;
218 }
219
220 $screen = get_current_screen();
221 $shop_order_page_screen_id = OrderUtil::custom_orders_table_usage_is_enabled() ? wc_get_page_screen_id( 'shop-order' ) : 'edit-shop_order';
222
223 if ( $shop_order_page_screen_id !== $screen->id ) {
224 return;
225 }
226
227 $enable_button = sprintf( '<a href="%s" class="page-title-action orderable-live-view-button orderable-live-view-button--enable">%s</a>', admin_url( 'edit.php?post_type=shop_order&orderable_live_view' ), __( 'Enable Live View', 'orderable' ) );
228 $disable_button = '';
229 $enable_audio = '';
230
231 if ( self::is_live_view() ) {
232 $disable_button = sprintf( '<a href="%s" class="page-title-action orderable-live-view-button orderable-live-view-button--disable orderable-live-view-button--margin-left-6">%s</a>', admin_url( 'edit.php?post_type=shop_order' ), __( 'Exit Live View', 'orderable' ) );
233 $enable_audio = sprintf( '<button class="page-title-action orderable-live-view-button orderable-live-view-button--audio orderable-live-view-button--margin-left-6" data-orderable-alt-text="%1$s" data-orderable-mute-status="0">%2$s</a>', __( 'Unmute', 'orderable' ), __( 'Mute', 'orderable' ) );
234 }
235 ?>
236 <script>
237 jQuery( document ).ready( function() {
238 var $add_new_button = jQuery( '.page-title-action' );
239
240 if ( $add_new_button.length <= 0 ) {
241 return;
242 }
243
244 $add_new_button.after( '<?php echo $enable_audio; ?>' ).after( '<?php echo $disable_button; ?>' ).after( '<?php echo $enable_button; ?>' );
245 } );
246 </script>
247 <?php
248 }
249
250 /**
251 * Add hidden input so filtering maintains live view.
252 */
253 public static function live_view_input() {
254 if ( ! self::is_live_view() ) {
255 return;
256 }
257 ?>
258 <input type="hidden" name="orderable_live_view" value="1" />
259 <?php
260 }
261
262 /**
263 * Add settings page.
264 */
265 public static function add_settings_page() {
266 add_submenu_page( 'orderable', __( 'Live Order View', 'orderable' ), __( 'Live Order View', 'orderable' ), 'manage_shop_order_terms', 'edit.php?post_type=shop_order&orderable_live_view', '', 1 );
267 }
268
269 /**
270 * Add new user role
271 */
272 public static function create_order_manager_role() {
273 // Capabilities for order manager role.
274 $capabilities = array(
275 'edit_posts' => true,
276 'view_admin_dashboard' => true,
277 'read' => true,
278 'edit_shop_order' => true,
279 'read_shop_order' => true,
280 'delete_shop_order' => true,
281 'edit_shop_orders' => true,
282 'edit_others_shop_orders' => true,
283 'publish_shop_orders' => true,
284 'read_private_shop_orders' => true,
285 'delete_shop_orders' => true,
286 'delete_private_shop_orders' => true,
287 'delete_published_shop_orders' => true,
288 'delete_others_shop_orders' => true,
289 'edit_private_shop_orders' => true,
290 'edit_published_shop_orders' => true,
291 'manage_shop_order_terms' => true,
292 'edit_shop_order_terms' => true,
293 'delete_shop_order_terms' => true,
294 'assign_shop_order_terms' => true,
295 );
296
297 $role = get_role( 'order_manager' );
298 $removed_role = false;
299
300 // Ensure that we remove the legacy role that does not
301 // include the new `edit_posts` capability.
302 if ( $role && ! $role->has_cap( 'edit_posts' ) ) {
303 remove_role( 'order_manager' );
304 $removed_role = true;
305 }
306
307 if ( ! $role || $removed_role ) {
308 add_role( __( 'order_manager', 'orderable' ), __( 'Order Manager', 'orderable' ), $capabilities );
309 }
310 }
311
312 /**
313 * Restrict access to parts of the admin dashboard that
314 * the `edit_posts` capability makes available.
315 *
316 * @return void
317 */
318 public static function restrict_order_manager_role_access() {
319 global $pagenow, $current_screen;
320
321 $userdata = get_userdata( get_current_user_id() );
322
323 if ( ! $userdata || ! is_array( $userdata->roles ) || ! in_array( 'order_manager', $userdata->roles, true ) ) {
324 return;
325 }
326
327 // Remove access to menu pages made visible by the `edit_posts` cap.
328 remove_menu_page( 'edit.php' );
329 remove_menu_page( 'edit-comments.php' );
330
331 $order_page_url = OrderUtil::custom_orders_table_usage_is_enabled() ? admin_url( 'admin.php?page=wc-orders' ) : admin_url( 'edit.php?post_type=shop_order' );
332
333 if (
334 'edit-post' === $current_screen->id ||
335 'edit-comments' === $current_screen->id
336 ) {
337 wp_safe_redirect( $order_page_url );
338 exit;
339 }
340
341 if ( OrderUtil::custom_orders_table_usage_is_enabled() && 'post-new.php' === $pagenow ) {
342 wp_safe_redirect( $order_page_url );
343 exit;
344 }
345
346 if ( ! OrderUtil::custom_orders_table_usage_is_enabled() && 'post-new.php' === $pagenow && 'shop_order' !== $current_screen->id ) {
347 wp_safe_redirect( $order_page_url );
348 exit;
349 }
350 }
351
352 /**
353 * Output nonce field with the action `orderable_filter_orders`.
354 *
355 * @return void
356 */
357 public static function output_filter_orders_nonce_field() {
358 wp_nonce_field( 'orderable_filter_orders', '_orderable_filter_orders_nonce' );
359 }
360 }
361