--- a/restropress/includes/admin/add-ons.php
+++ b/restropress/includes/admin/add-ons.php
@@ -214,10 +214,11 @@
echo ob_get_clean();
}
function rpress_fetch_items() {
- $url = 'https://www.restropress.com/wp-json/restropress-server/';
- $version = '1.0';
- $remote_url = $url . 'v' . $version;
- $feed = wp_remote_get( esc_url_raw( $remote_url ), array( 'sslverify' => false ) );
+ $url = 'https://www.restropress.com/wp-json/restropress-server/';
+ $version = '1.0';
+ $remote_url = $url . 'v' . $version;
+ $verify_ssl = (bool) apply_filters( 'rpress_remote_request_verify_ssl', true );
+ $feed = wp_remote_get( esc_url_raw( $remote_url ), array( 'sslverify' => $verify_ssl ) );
$items = array();
if ( ! is_wp_error( $feed ) ) {
if ( isset( $feed['body'] ) && strlen( $feed['body'] ) > 0 ) {
@@ -229,4 +230,4 @@
$items = '<div class="error"><p>' . esc_html__( 'There was an error retrieving the extensions list from the server. Please try again later.', 'restropress' ) . '</div>';
}
return $items;
-}
No newline at end of file
+}
--- a/restropress/includes/admin/admin-actions.php
+++ b/restropress/includes/admin/admin-actions.php
@@ -17,14 +17,24 @@
* @since 1.0.0
* @return void
*/
-function rpress_process_actions() {
- if ( isset( $_POST['rpress-action'] ) ) {
- do_action( 'rpress_' . sanitize_text_field( $_POST['rpress-action'] ), rpress_sanitize_array( $_POST ) );
- }
- if ( isset( $_GET['rpress-action'] ) ) {
- do_action( 'rpress_' . sanitize_text_field( $_GET['rpress-action'] ), rpress_sanitize_array( $_GET ) );
- }
-}
+function rpress_process_actions() {
+ if ( ! is_admin() || ! is_user_logged_in() ) {
+ return;
+ }
+
+ if ( isset( $_POST['rpress-action'] ) ) {
+ $action = sanitize_key( wp_unslash( $_POST['rpress-action'] ) );
+ if ( ! empty( $action ) ) {
+ do_action( 'rpress_' . $action, rpress_sanitize_array( $_POST ) );
+ }
+ }
+ if ( isset( $_GET['rpress-action'] ) ) {
+ $action = sanitize_key( wp_unslash( $_GET['rpress-action'] ) );
+ if ( ! empty( $action ) ) {
+ do_action( 'rpress_' . $action, rpress_sanitize_array( $_GET ) );
+ }
+ }
+}
add_action( 'admin_init', 'rpress_process_actions' );
/**
* Display notices to admins
--- a/restropress/includes/admin/class-rp-admin-assets.php
+++ b/restropress/includes/admin/class-rp-admin-assets.php
@@ -22,14 +22,10 @@
add_action( 'admin_enqueue_scripts', array( $this, 'register_styles' ), 100 );
add_action( 'admin_head', array( $this, 'admin_icons_buttons' ) );
add_action( 'wp_ajax_selected_filter', array( $this, 'selected_filter' ) );
- add_action( 'wp_ajax_nopriv_selected_filter',array( $this, 'selected_filter' ) );
add_action( 'wp_ajax_rpress_do_ajax_export', array($this, 'rpress_do_ajax_export' ) );
add_action( 'wp_ajax_order_graph_filter', array( $this, 'order_graph_filter' ) );
- add_action( 'wp_ajax_nopriv_order_graph_filter', array( $this, 'order_graph_filter') );
add_action( 'wp_ajax_revenue_graph_filter', array( $this, 'revenue_graph_filter' ) );
- add_action( 'wp_ajax_nopriv_revenue_graph_filter',array( $this, 'revenue_graph_filter' ) );
add_action( 'wp_ajax_customers_data_filter', array( $this, 'customers_data_filter') );
- add_action( 'wp_ajax_nopriv_customers_data_filter', array( $this, 'customers_data_filter') );
}
/**
* Enqueue styles.
@@ -166,9 +162,13 @@
'load_admin_addon_nonce' => wp_create_nonce( 'load-admin-addon' ),
'preview_nonce' => wp_create_nonce( 'rpress-preview-order' ),
'order_nonce' => wp_create_nonce( 'rpress-order' ),
+ 'reports_nonce' => wp_create_nonce( 'rpress-admin-reports' ),
+ 'payment_note_nonce' => wp_create_nonce( 'rpress-payment-note' ),
+ 'check_new_orders_nonce' => wp_create_nonce( 'rpress-check-new-orders' ),
'activate_license' => wp_create_nonce( 'activate-license' ),
'deactivate_license' => wp_create_nonce( 'deactivate-license' ),
'selected_filter_nonce' => wp_create_nonce( 'selected-filter' ),
+ 'bulk_edit_nonce' => wp_create_nonce( 'rpress-bulk-edit' ),
);
wp_localize_script( 'rp-admin', 'rpress_vars',
$admin_params
@@ -228,6 +228,12 @@
* @return void
*/
public function revenue_graph_filter(){
+ if ( ! current_user_can( apply_filters( 'rpress_dashboard_stats_cap', 'view_shop_reports' ) ) ) {
+ wp_send_json_error( array( 'message' => esc_html__( 'You do not have permission to access this resource.', 'restropress' ) ), 403 );
+ }
+
+ check_ajax_referer( 'rpress-admin-reports', 'nonce' );
+
$filter_type = isset( $_POST['select_filter'] ) ? $_POST['select_filter'] : '';
$SalesByDate = [];
if( $filter_type == 'yearly') {
@@ -586,6 +592,10 @@
}
public function selected_filter() {
+ if ( ! current_user_can( apply_filters( 'rpress_dashboard_stats_cap', 'view_shop_reports' ) ) ) {
+ wp_send_json_error( array( 'message' => esc_html__( 'You do not have permission to access this resource.', 'restropress' ) ), 403 );
+ }
+
check_ajax_referer( 'selected-filter', 'nonce' );
$pdate = isset( $_POST['date'] ) ? sanitize_text_field( wp_unslash( $_POST['date'] ) ) : 'today';
@@ -1800,6 +1810,12 @@
}
}
public function order_graph_filter() {
+ if ( ! current_user_can( apply_filters( 'rpress_dashboard_stats_cap', 'view_shop_reports' ) ) ) {
+ wp_send_json_error( array( 'message' => esc_html__( 'You do not have permission to access this resource.', 'restropress' ) ), 403 );
+ }
+
+ check_ajax_referer( 'rpress-admin-reports', 'nonce' );
+
$filter_type = isset( $_POST[ 'select_filter' ] ) ? $_POST[ 'select_filter' ] : '';
$SalesByDate = [];
if ( $filter_type === 'monthly' || $filter_type === 'weekly' || $filter_type === 'yearly' ) {
@@ -1856,6 +1872,12 @@
return $SalesByDate;
}
public function customers_data_filter(){
+ if ( ! current_user_can( apply_filters( 'rpress_dashboard_stats_cap', 'view_shop_reports' ) ) ) {
+ wp_send_json_error( array( 'message' => esc_html__( 'You do not have permission to access this resource.', 'restropress' ) ), 403 );
+ }
+
+ check_ajax_referer( 'rpress-admin-reports', 'nonce' );
+
$customer_filter = isset( $_POST['selected_option'] ) ? sanitize_text_field( wp_unslash( $_POST['selected_option'] ) ) : 'monthly';
$today = gmdate( 'Y-m-d' );
--- a/restropress/includes/admin/class-rpress-notices.php
+++ b/restropress/includes/admin/class-rpress-notices.php
@@ -50,7 +50,7 @@
),
esc_url( admin_url( 'admin.php?page=rpress-settings' ) )
); ?></p>
- <p><a href="<?php echo esc_url( esc_url( add_query_arg( array( 'rpress_action' => 'dismiss_notices', 'rpress_notice' => 'set_menupage' ) ) ) ); ?>"><?php esc_html_e( 'Dismiss Notice', 'restropress' ); ?></a></p>
+ <p><a href="<?php echo esc_url( esc_url( add_query_arg( array( 'rpress_action' => 'dismiss_notices', 'rpress_notice' => 'set_menupage', '_wpnonce' => wp_create_nonce( 'rpress-dismiss-notice' ) ) ) ) ); ?>"><?php esc_html_e( 'Dismiss Notice', 'restropress' ); ?></a></p>
</div>
<?php
$allowed_html = array(
@@ -80,7 +80,7 @@
)
),
esc_url ( admin_url( 'admin.php?page=rpress-settings' ) ) ); ?></p>
- <p><a href="<?php echo esc_url( add_query_arg( array( 'rpress_action' => 'dismiss_notices', 'rpress_notice' => 'set_checkout' ) ) ); ?>"><?php esc_html_e( 'Dismiss Notice', 'restropress' ); ?></a></p>
+ <p><a href="<?php echo esc_url( add_query_arg( array( 'rpress_action' => 'dismiss_notices', 'rpress_notice' => 'set_checkout', '_wpnonce' => wp_create_nonce( 'rpress-dismiss-notice' ) ) ) ); ?>"><?php esc_html_e( 'Dismiss Notice', 'restropress' ); ?></a></p>
</div>
<?php
$allowed_html = array(
@@ -255,12 +255,24 @@
* @since 1.0.0
* @return void
*/
- function dismiss_notices() {
- if( isset( $_GET['rpress_notice'] ) ) {
- update_user_meta( get_current_user_id(), '_rpress_' . sanitize_text_field( $_GET['rpress_notice'] ) . '_dismissed', 1 );
- wp_redirect( remove_query_arg( array( 'rpress_action', 'rpress_notice' ) ) );
- exit;
- }
- }
+ function dismiss_notices() {
+ if( ! isset( $_GET['rpress_notice'] ) ) {
+ return;
+ }
+
+ if ( ! current_user_can( 'manage_shop_settings' ) && ! current_user_can( 'edit_pages' ) && ! current_user_can( 'view_shop_reports' ) ) {
+ return;
+ }
+
+ $nonce = isset( $_GET['_wpnonce'] ) ? sanitize_text_field( wp_unslash( $_GET['_wpnonce'] ) ) : '';
+ if ( ! wp_verify_nonce( $nonce, 'rpress-dismiss-notice' ) ) {
+ return;
+ }
+
+ $notice_key = sanitize_text_field( wp_unslash( $_GET['rpress_notice'] ) );
+ update_user_meta( get_current_user_id(), '_rpress_' . $notice_key . '_dismissed', 1 );
+ wp_redirect( remove_query_arg( array( 'rpress_action', 'rpress_notice', '_wpnonce' ) ) );
+ exit;
+ }
}
new RPRESS_Notices;
--- a/restropress/includes/admin/customers/customer-actions.php
+++ b/restropress/includes/admin/customers/customer-actions.php
@@ -216,31 +216,36 @@
* @since 1.0.0
* @return void
*/
-function rpress_remove_customer_email() {
- if ( empty( $_GET['id'] ) || ! is_numeric( $_GET['id'] ) ) {
- return false;
- }
+function rpress_remove_customer_email() {
+ $customer_edit_role = apply_filters( 'rpress_edit_customers_role', 'edit_shop_payments' );
+ if ( ! is_admin() || ! current_user_can( $customer_edit_role ) ) {
+ wp_die( esc_html__( 'You do not have permission to edit this customer.', 'restropress' ) );
+ }
+
+ if ( empty( $_GET['id'] ) || ! is_numeric( $_GET['id'] ) ) {
+ return false;
+ }
if ( empty( $_GET['email'] ) || ! is_email( $_GET['email'] ) ) {
return false;
}
if ( empty( $_GET['_wpnonce'] ) ) {
return false;
}
- $nonce = sanitize_text_field( $_GET['_wpnonce'] );
+ $nonce = sanitize_text_field( wp_unslash( $_GET['_wpnonce'] ) );
if ( ! wp_verify_nonce( $nonce, 'rpress-remove-customer-email' ) ) {
wp_die( esc_html__( 'Nonce verification failed', 'restropress' ), esc_html__( 'Error', 'restropress' ), array( 'response' => 403 ) );
}
- $customer = new RPRESS_Customer( absint( $_GET['id'] ) );
- if ( $customer->remove_email( sanitize_email( $_GET['email'] ) ) ) {
- $url = add_query_arg( 'rpress-message', 'email-removed', admin_url( 'admin.php?page=rpress-customers&view=overview&id=' . $customer->id ) );
- $user = wp_get_current_user();
- $user_login = ! empty( $user->user_login ) ? $user->user_login : 'RPRESSBot';
- $customer_note = sprintf(
- /* translators: 1: text, 2: admin url */
- esc_html__( 'Email address %1$s removed by %2$s', 'restropress' ), sanitize_email( $_GET['email'] ), $user_login );
- $customer->add_note( $customer_note );
- } else {
- $url = add_query_arg( 'rpress-message', 'email-remove-failed', admin_url( 'admin.php?page=rpress-customers&view=overview&id=' . $customer->id ) );
+ $customer = new RPRESS_Customer( absint( wp_unslash( $_GET['id'] ) ) );
+ if ( $customer->remove_email( sanitize_email( wp_unslash( $_GET['email'] ) ) ) ) {
+ $url = add_query_arg( 'rpress-message', 'email-removed', admin_url( 'admin.php?page=rpress-customers&view=overview&id=' . $customer->id ) );
+ $user = wp_get_current_user();
+ $user_login = ! empty( $user->user_login ) ? $user->user_login : 'RPRESSBot';
+ $customer_note = sprintf(
+ /* translators: 1: text, 2: admin url */
+ esc_html__( 'Email address %1$s removed by %2$s', 'restropress' ), sanitize_email( wp_unslash( $_GET['email'] ) ), $user_login );
+ $customer->add_note( $customer_note );
+ } else {
+ $url = add_query_arg( 'rpress-message', 'email-remove-failed', admin_url( 'admin.php?page=rpress-customers&view=overview&id=' . $customer->id ) );
}
wp_safe_redirect( $url );
exit;
@@ -253,32 +258,37 @@
* @since 1.0.0
* @return void
*/
-function rpress_set_customer_primary_email() {
- if ( empty( $_GET['id'] ) || ! is_numeric( $_GET['id'] ) ) {
- return false;
- }
+function rpress_set_customer_primary_email() {
+ $customer_edit_role = apply_filters( 'rpress_edit_customers_role', 'edit_shop_payments' );
+ if ( ! is_admin() || ! current_user_can( $customer_edit_role ) ) {
+ wp_die( esc_html__( 'You do not have permission to edit this customer.', 'restropress' ) );
+ }
+
+ if ( empty( $_GET['id'] ) || ! is_numeric( $_GET['id'] ) ) {
+ return false;
+ }
if ( empty( $_GET['email'] ) || ! is_email( $_GET['email'] ) ) {
return false;
}
if ( empty( $_GET['_wpnonce'] ) ) {
return false;
}
- $nonce = sanitize_text_field( $_GET['_wpnonce'] );
+ $nonce = sanitize_text_field( wp_unslash( $_GET['_wpnonce'] ) );
if ( ! wp_verify_nonce( $nonce, 'rpress-set-customer-primary-email' ) ) {
wp_die( esc_html__( 'Nonce verification failed', 'restropress' ), esc_html__( 'Error', 'restropress' ), array( 'response' => 403 ) );
}
- $customer = new RPRESS_Customer( absint( $_GET['id'] ) );
- if ( $customer->set_primary_email( sanitize_email( $_GET['email'] ) ) ){
- $url = add_query_arg( 'rpress-message', 'primary-email-updated', admin_url( 'admin.php?page=rpress-customers&view=overview&id=' . $customer->id ) );
- /* translators: 1: text, 2: admin url */
- $user = wp_get_current_user();
- $user_login = ! empty( $user->user_login ) ? $user->user_login : 'RPRESSBot';
- $customer_note = sprintf
- /* translators: 1: text, 2: admin url */
- ( esc_html__( 'Email address %1$s set as primary by %2$s', 'restropress' ), sanitize_email( $_GET['email'] ), $user_login );
- $customer->add_note( $customer_note );
- } else {
- $url = add_query_arg( 'rpress-message', 'primary-email-failed', admin_url( 'admin.php?page=rpress-customers&view=overview&id=' . $customer->id ) );
+ $customer = new RPRESS_Customer( absint( wp_unslash( $_GET['id'] ) ) );
+ if ( $customer->set_primary_email( sanitize_email( wp_unslash( $_GET['email'] ) ) ) ){
+ $url = add_query_arg( 'rpress-message', 'primary-email-updated', admin_url( 'admin.php?page=rpress-customers&view=overview&id=' . $customer->id ) );
+ /* translators: 1: text, 2: admin url */
+ $user = wp_get_current_user();
+ $user_login = ! empty( $user->user_login ) ? $user->user_login : 'RPRESSBot';
+ $customer_note = sprintf
+ /* translators: 1: text, 2: admin url */
+ ( esc_html__( 'Email address %1$s set as primary by %2$s', 'restropress' ), sanitize_email( wp_unslash( $_GET['email'] ) ), $user_login );
+ $customer->add_note( $customer_note );
+ } else {
+ $url = add_query_arg( 'rpress-message', 'primary-email-failed', admin_url( 'admin.php?page=rpress-customers&view=overview&id=' . $customer->id ) );
}
wp_safe_redirect( $url );
exit;
@@ -445,18 +455,23 @@
* @since 1.0.0
* @return void
*/
-function rpress_process_admin_user_verification() {
- if ( empty( $_GET['id'] ) || ! is_numeric( $_GET['id'] ) ) {
- return false;
- }
+function rpress_process_admin_user_verification() {
+ $customer_edit_role = apply_filters( 'rpress_edit_customers_role', 'edit_shop_payments' );
+ if ( ! is_admin() || ! current_user_can( $customer_edit_role ) ) {
+ wp_die( esc_html__( 'You do not have permission to verify this customer.', 'restropress' ) );
+ }
+
+ if ( empty( $_GET['id'] ) || ! is_numeric( $_GET['id'] ) ) {
+ return false;
+ }
if ( empty( $_GET['_wpnonce'] ) ) {
return false;
}
- $nonce = sanitize_text_field( $_GET['_wpnonce'] );
+ $nonce = sanitize_text_field( wp_unslash( $_GET['_wpnonce'] ) );
if ( ! wp_verify_nonce( $nonce, 'rpress-verify-user' ) ) {
wp_die( esc_html__( 'Nonce verification failed', 'restropress' ), esc_html__( 'Error', 'restropress' ), array( 'response' => 403 ) );
}
- $customer = new RPRESS_Customer( absint( $_GET['id'] ) );
+ $customer = new RPRESS_Customer( absint( wp_unslash( $_GET['id'] ) ) );
rpress_set_user_to_verified( $customer->user_id );
$url = add_query_arg( 'rpress-message', 'user-verified', admin_url( 'admin.php?page=rpress-customers&view=overview&id=' . $customer->id ) );
wp_safe_redirect( esc_url( $url ) );
--- a/restropress/includes/admin/fooditems/dashboard-columns.php
+++ b/restropress/includes/admin/fooditems/dashboard-columns.php
@@ -318,13 +318,19 @@
* @since 1.0.0
* @return void
*/
-function rpress_save_bulk_edit() {
- $post_ids = ( isset( $_POST['post_ids'] ) && ! empty( $_POST['post_ids'] ) ) ? rpress_sanitize_array( $_POST['post_ids'] ) : array();
- if ( ! empty( $post_ids ) && is_array( $post_ids ) ) {
- $price = isset( $_POST['price'] ) ? strip_tags( stripslashes( sanitize_text_field( $_POST['price'] ) ) ) : 0;
- foreach ( $post_ids as $post_id ) {
- if( ! current_user_can( 'edit_post', $post_id ) ) {
- continue;
+function rpress_save_bulk_edit() {
+ check_ajax_referer( 'rpress-bulk-edit', 'rpress_bulk_nonce' );
+
+ if ( ! current_user_can( 'edit_products' ) ) {
+ wp_die( esc_html__( 'You do not have permission to edit food items.', 'restropress' ), esc_html__( 'Error', 'restropress' ), array( 'response' => 403 ) );
+ }
+
+ $post_ids = ( isset( $_POST['post_ids'] ) && ! empty( $_POST['post_ids'] ) ) ? rpress_sanitize_array( wp_unslash( $_POST['post_ids'] ) ) : array();
+ if ( ! empty( $post_ids ) && is_array( $post_ids ) ) {
+ $price = isset( $_POST['price'] ) ? strip_tags( stripslashes( sanitize_text_field( wp_unslash( $_POST['price'] ) ) ) ) : 0;
+ foreach ( $post_ids as $post_id ) {
+ if( ! current_user_can( 'edit_post', $post_id ) ) {
+ continue;
}
if ( ! empty( $price ) ) {
update_post_meta( $post_id, 'rpress_price', rpress_sanitize_amount( $price ) );
@@ -356,4 +362,4 @@
}
return $content;
}
-add_filter( 'manage_addon_category_custom_column', 'add_addons_price_type_column_content', 10, 3 );
No newline at end of file
+add_filter( 'manage_addon_category_custom_column', 'add_addons_price_type_column_content', 10, 3 );
--- a/restropress/includes/admin/home/rpress-home.php
+++ b/restropress/includes/admin/home/rpress-home.php
@@ -14,7 +14,15 @@
function rpress_admin_home_page()
{
// Handle form submission before any output
- if ($_SERVER['REQUEST_METHOD'] === 'POST') {
+ if ( 'POST' === $_SERVER['REQUEST_METHOD'] ) {
+ if ( ! current_user_can( 'manage_shop_settings' ) ) {
+ wp_die( esc_html__( 'You do not have permission to update these settings.', 'restropress' ) );
+ }
+
+ $nonce = isset( $_POST['rpress_admin_home_nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['rpress_admin_home_nonce'] ) ) : '';
+ if ( ! wp_verify_nonce( $nonce, 'rpress_admin_home_save' ) ) {
+ wp_die( esc_html__( 'Security check failed. Please try again.', 'restropress' ) );
+ }
if (isset($_POST['service-pickup']) && isset($_POST['service-delivery'])) {
$enable_service = 'delivery_and_pickup';
@@ -149,6 +157,7 @@
<div class="card-body">
<!-- tab -->
<form class="multiStep" action="" method="POST">
+ <?php wp_nonce_field( 'rpress_admin_home_save', 'rpress_admin_home_nonce' ); ?>
<div class="tab">
<div class="welcome-step-1">
<!-- tab1_content -->
--- a/restropress/includes/admin/payments/actions.php
+++ b/restropress/includes/admin/payments/actions.php
@@ -317,6 +317,8 @@
}
add_action( 'rpress_delete_order', 'rpress_trigger_destroy_order' );
function rpress_ajax_store_payment_note() {
+ check_ajax_referer( 'rpress-payment-note', 'security' );
+
$payment_id = absint( $_POST['payment_id'] );
$note = wp_kses( $_POST['note'], array() );
if( ! current_user_can( 'edit_shop_payments', $payment_id ) ) {
@@ -371,6 +373,8 @@
* @return void
*/
function rpress_ajax_delete_payment_note() {
+ check_ajax_referer( 'rpress-payment-note', 'security' );
+
if( ! current_user_can( 'edit_shop_payments', absint( $_POST['payment_id'] ) ) ) {
wp_die( esc_html__( 'You do not have permission to edit this payment record', 'restropress' ), esc_html__( 'Error', 'restropress' ), array( 'response' => 403 ) );
}
@@ -390,87 +394,123 @@
* @since 3.0
*/
function rpress_orders_list_table_process_bulk_actions() {
- // Bail if this method was called directly.
- if (isset($_GET['page']) && $_GET['page'] === 'rpress-payment-history') {
- $action = isset( $_REQUEST['action'] ) // WPCS: CSRF ok.
- ? sanitize_text_field( $_REQUEST['action'] )
+ $page = isset( $_GET['page'] ) ? sanitize_key( wp_unslash( $_GET['page'] ) ) : '';
+ if ( 'rpress-payment-history' !== $page ) {
+ return;
+ }
+
+ $action = isset( $_REQUEST['action'] ) // phpcs:ignore WordPress.Security.NonceVerification.Recommended
+ ? sanitize_text_field( wp_unslash( $_REQUEST['action'] ) )
: '';
- // If this is a 'delete' action, the capability changes from edit to delete.
- $cap = 'delete' === $action ? 'delete_shop_payments' : 'edit_shop_payments';
- // Check the current user's capability.
- if ( ! current_user_can( $cap ) ) {
- return;
- }
-
- // Bail if we aren't processing bulk actions.
- if ( '-1' === $action ) {
- return;
- }
- $ids = isset( $_GET['payment'] ) // WPCS: CSRF ok.
- ? $_GET['payment']
- : false;
- if ( ! is_array( $ids ) ) {
- $ids = array( $ids );
+
+ // Bail if we aren't processing bulk actions.
+ if ( empty( $action ) || '-1' === $action ) {
+ return;
+ }
+
+ $nonce = isset( $_REQUEST['_wpnonce'] ) // phpcs:ignore WordPress.Security.NonceVerification.Recommended
+ ? sanitize_text_field( wp_unslash( $_REQUEST['_wpnonce'] ) )
+ : '';
+ $plural = rpress_get_label_plural();
+ $bulk_nonce_actions = array(
+ 'bulk-' . $plural,
+ 'bulk-' . strtolower( $plural ),
+ 'bulk-' . sanitize_key( $plural ),
+ 'bulk-payments',
+ 'bulk-orders',
+ );
+ $has_valid_bulk_nonce = false;
+
+ foreach ( $bulk_nonce_actions as $nonce_action ) {
+ if ( ! empty( $nonce_action ) && wp_verify_nonce( $nonce, $nonce_action ) ) {
+ $has_valid_bulk_nonce = true;
+ break;
}
- if ( empty( $action ) ) {
- return;
+ }
+
+ if ( ! $has_valid_bulk_nonce ) {
+ return;
+ }
+
+ // If this is a 'delete' action, the capability changes from edit to delete.
+ $cap = 'delete' === $action ? 'delete_shop_payments' : 'edit_shop_payments';
+ if ( ! current_user_can( $cap ) ) {
+ return;
+ }
+
+ $ids = isset( $_GET['payment'] ) // phpcs:ignore WordPress.Security.NonceVerification.Recommended
+ ? $_GET['payment'] // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
+ : false;
+ if ( ! is_array( $ids ) ) {
+ $ids = array( $ids );
+ }
+
+ $ids = wp_parse_id_list( $ids );
+ foreach ( $ids as $id ) {
+ if ( ! current_user_can( $cap, $id ) ) {
+ continue;
}
- $ids = wp_parse_id_list( $ids );
- foreach ( $ids as $id ) {
- switch ( $action ) {
- case 'trash':
- rpress_trash_order( $id );
- break;
- case 'restore':
- rpress_restore_order( $id );
- break;
- case 'delete':
- rpress_delete_order( $id );
- break;
- case 'set-payment-status-paid':
- rpress_update_payment_status( $id, 'complete' );
- break;
- case 'set-payment-status-pending':
- rpress_update_payment_status( $id, 'pending' );
- break;
- case 'set-payment-status-processing':
- rpress_update_payment_status( $id, 'processing' );
- break;
- case 'set-payment-status-failed':
- rpress_update_payment_status( $id, 'failed' );
- break;
- case 'set-payment-status-refunded':
- rpress_update_payment_status( $id, 'refunded' );
- break;
- case 'set-order-status-pending':
- rpress_update_order_status( $id, 'pending' );
- break;
- case 'set-order-status-accepted':
- rpress_update_order_status( $id, 'accepted' );
- break;
- case 'set-order-status-processing':
- rpress_update_order_status( $id, 'processing' );
- break;
- case 'set-order-status-ready':
- rpress_update_order_status( $id, 'ready' );
- break;
- case 'set-order-status-transit':
- rpress_update_order_status( $id, 'transit' );
- break;
-
- case 'set-order-status-cancelled':
- rpress_update_order_status( $id, 'cancelled' );
- break;
- case 'set-order-status-completed':
- rpress_update_order_status( $id, 'completed' );
- break;
- case 'resend-receipt':
- rpress_email_purchase_receipt( $id, false );
- break;
- }
- do_action( 'rpress_payments_table_do_bulk_action', $id, $action );
+
+ switch ( $action ) {
+ case 'trash':
+ rpress_trash_order( $id );
+ break;
+ case 'restore':
+ rpress_restore_order( $id );
+ break;
+ case 'delete':
+ rpress_delete_order( $id );
+ break;
+ case 'set-payment-status-paid':
+ rpress_update_payment_status( $id, 'complete' );
+ break;
+ case 'set-payment-status-pending':
+ rpress_update_payment_status( $id, 'pending' );
+ break;
+ case 'set-payment-status-processing':
+ rpress_update_payment_status( $id, 'processing' );
+ break;
+ case 'set-payment-status-failed':
+ rpress_update_payment_status( $id, 'failed' );
+ break;
+ case 'set-payment-status-refunded':
+ rpress_update_payment_status( $id, 'refunded' );
+ break;
+ case 'set-order-status-pending':
+ rpress_update_order_status( $id, 'pending' );
+ break;
+ case 'set-order-status-accepted':
+ rpress_update_order_status( $id, 'accepted' );
+ break;
+ case 'set-order-status-processing':
+ rpress_update_order_status( $id, 'processing' );
+ break;
+ case 'set-order-status-ready':
+ rpress_update_order_status( $id, 'ready' );
+ break;
+ case 'set-order-status-transit':
+ rpress_update_order_status( $id, 'transit' );
+ break;
+ case 'set-order-status-cancelled':
+ rpress_update_order_status( $id, 'cancelled' );
+ break;
+ case 'set-order-status-completed':
+ rpress_update_order_status( $id, 'completed' );
+ break;
+ case 'resend-receipt':
+ rpress_email_purchase_receipt( $id, false );
+ break;
}
- wp_safe_redirect( wp_get_referer() );
+
+ do_action( 'rpress_payments_table_do_bulk_action', $id, $action );
+ }
+
+ $redirect_url = wp_get_referer();
+ if ( empty( $redirect_url ) ) {
+ $redirect_url = admin_url( 'admin.php?page=rpress-payment-history' );
}
+
+ wp_safe_redirect( $redirect_url );
+ exit;
}
add_action( 'admin_init', 'rpress_orders_list_table_process_bulk_actions' );
--- a/restropress/includes/class-rpress-addon-updater.php
+++ b/restropress/includes/class-rpress-addon-updater.php
@@ -381,20 +381,26 @@
}
public function show_changelog() {
// global $edd_plugin_data;
- if( empty( $_REQUEST['edd_sl_action'] ) || 'view_plugin_changelog' != $_REQUEST['edd_sl_action'] ) {
+ $action = isset( $_REQUEST['edd_sl_action'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['edd_sl_action'] ) ) : '';
+ if ( empty( $action ) || 'view_plugin_changelog' !== $action ) {
return;
}
- if( empty( $_REQUEST['plugin'] ) ) {
+ $plugin = isset( $_REQUEST['plugin'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['plugin'] ) ) : '';
+ $slug = isset( $_REQUEST['slug'] ) ? sanitize_key( wp_unslash( $_REQUEST['slug'] ) ) : '';
+ if ( empty( $plugin ) ) {
return;
}
- if( empty( $_REQUEST['slug'] ) ) {
+ if ( empty( $slug ) ) {
return;
}
if( ! current_user_can( 'update_plugins' ) ) {
wp_die( esc_html__( 'You do not have permission to install plugin updates', 'restropress' ), esc_html__( 'Error', 'restropress' ), array( 'response' => 403 ) );
}
$update_cache = get_site_transient( 'update_plugins' );
- $version_info = $update_cache->response[$_REQUEST['plugin']];
+ if ( empty( $update_cache->response ) || ! is_array( $update_cache->response ) || ! isset( $update_cache->response[ $plugin ] ) ) {
+ return;
+ }
+ $version_info = $update_cache->response[ $plugin ];
if ( isset( $version_info->sections ) ) {
$sections = $this->convert_object_to_array( $version_info->sections );
if ( ! empty( $sections['changelog'] ) ) {
--- a/restropress/includes/class-rpress-ajax.php
+++ b/restropress/includes/class-rpress-ajax.php
@@ -134,15 +134,63 @@
add_action( 'wp_ajax_rpress_' . $ajax_event, array( __CLASS__, $ajax_event ) );
}
}
+
+ /**
+ * Check whether the current request can access a frontend order action.
+ *
+ * Logged-in users can only access their own user-linked orders.
+ * Guest orders require a valid payment key that can view the receipt.
+ *
+ * @since 3.2.8
+ *
+ * @param int $order_id Payment post ID.
+ * @return bool
+ */
+ private static function can_access_frontend_order_action( $order_id ) {
+ $order_id = absint( $order_id );
+ if ( $order_id <= 0 || 'rpress_payment' !== get_post_type( $order_id ) ) {
+ return false;
+ }
+
+ $user = rpress_get_payment_meta_user_info( $order_id );
+ $order_user_id = isset( $user['id'] ) ? absint( $user['id'] ) : 0;
+
+ if ( is_user_logged_in() ) {
+ return ( $order_user_id > 0 && get_current_user_id() === $order_user_id );
+ }
+
+ if ( $order_user_id > 0 ) {
+ return false;
+ }
+
+ $payment_key = isset( $_REQUEST['payment_key'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['payment_key'] ) ) : '';
+ if ( empty( $payment_key ) ) {
+ return false;
+ }
+
+ $payment_id_from_key = absint( rpress_get_purchase_id_by_key( $payment_key ) );
+ if ( $payment_id_from_key !== $order_id ) {
+ return false;
+ }
+
+ return (bool) rpress_can_view_receipt( $payment_key );
+ }
/**
* for order reorder.
*/
public static function reorder() {
-
- $user = rpress_get_payment_meta_user_info( absint( $_POST['order_id'] ) );
-
- if( get_current_user_id() !== $user['id'] ) return;
- $order_id = isset( $_POST['order_id'] ) ? absint( $_POST['order_id'] ) : '';
+ check_ajax_referer( 'show-order-details', 'security' );
+
+ $order_id = isset( $_POST['order_id'] ) ? absint( wp_unslash( $_POST['order_id'] ) ) : 0;
+ if ( ! self::can_access_frontend_order_action( $order_id ) ) {
+ wp_send_json_error(
+ array(
+ 'message' => esc_html__( 'You do not have permission to reorder this order.', 'restropress' ),
+ ),
+ 403
+ );
+ }
+
$payment = get_post( $order_id );
if( empty( $payment ) ) return;
$cart = rpress_get_payment_meta_cart_details( $payment->ID, true );
@@ -485,15 +533,77 @@
*/
public static function show_products() {
check_ajax_referer( 'show-products', 'security' );
- $service_type = filter_input( INPUT_POST, 'service_type' );
- $selected_date = filter_input( INPUT_POST, 'selected_date' );
- if ( empty( $_POST['fooditem_id'] ) || empty( $service_type ) )
- return;
- if( ! rpress_is_store_open( $service_type, $selected_date ) ){
- $response = array('status' => 'error', 'error_msg' => rpress_store_closed_message($service_type));
+ $service_type = sanitize_key( (string) filter_input( INPUT_POST, 'service_type' ) );
+ $selected_date = sanitize_text_field( (string) filter_input( INPUT_POST, 'selected_date' ) );
+ $selected_time = sanitize_text_field( (string) filter_input( INPUT_POST, 'selected_time' ) );
+ if ( empty( $_POST['fooditem_id'] ) ) {
+ wp_send_json_error(
+ array(
+ 'status' => 'error',
+ 'error_msg' => __( 'Unable to load item details. Please try again.', 'restropress' ),
+ )
+ );
+ }
+ $enabled_service = rpress_get_option( 'enable_service', 'delivery_and_pickup' );
+ $allowed_services = ( 'delivery_and_pickup' === $enabled_service ) ? array( 'delivery', 'pickup' ) : array( $enabled_service );
+ $allowed_services = array_map( 'sanitize_key', $allowed_services );
+ if ( empty( $service_type ) || ! in_array( $service_type, $allowed_services, true ) ) {
+ wp_send_json_error(
+ array(
+ 'status' => 'error',
+ 'error_msg' => __( 'Please select a service type.', 'restropress' ),
+ )
+ );
+ }
+ if ( empty( $selected_date ) ) {
+ wp_send_json_error(
+ array(
+ 'status' => 'error',
+ 'error_msg' => __( 'Please select a service date.', 'restropress' ),
+ )
+ );
+ }
+ $selected_date_ts = strtotime( $selected_date );
+ if ( false === $selected_date_ts ) {
+ wp_send_json_error(
+ array(
+ 'status' => 'error',
+ 'error_msg' => __( 'Please select a valid service date.', 'restropress' ),
+ )
+ );
+ }
+ $selected_date = date_i18n( 'Y-m-d', $selected_date_ts );
+ $service_time_hidden = function_exists( 'rp_otil_is_service_time_hidden' ) && rp_otil_is_service_time_hidden( $service_type );
+ $service_time = ! empty( $selected_time )
+ ? $selected_time
+ : ( isset( $_COOKIE['service_time'] ) ? sanitize_text_field( wp_unslash( $_COOKIE['service_time'] ) ) : '' );
+ if ( ! $service_time_hidden && empty( $service_time ) ) {
+ wp_send_json_error(
+ array(
+ 'status' => 'error',
+ 'error_msg' => __( 'Please select a service time.', 'restropress' ),
+ )
+ );
+ }
+ if ( ! rpress_is_store_open( $service_type, $selected_date ) ) {
+ $response = array( 'status' => 'error', 'error_msg' => rpress_store_closed_message( $service_type ) );
wp_send_json_error( $response );
die();
}
+ if ( ! $service_time_hidden && ! empty( $service_time ) ) {
+ $allow_asap = rpress_get_option( 'enable_asap_option' );
+ $prep_time = (int) rpress_get_option( 'prep_time', 0 ) * 60;
+ $current_time = current_time( 'timestamp' ) + $prep_time;
+ $service_time_ts = strtotime( $selected_date . ' ' . $service_time );
+ if ( false !== $service_time_ts && $service_time_ts < $current_time && ! $allow_asap ) {
+ wp_send_json_error(
+ array(
+ 'status' => 'error',
+ 'error_msg' => __( 'Selected time slot is no longer available. Please choose another time.', 'restropress' ),
+ )
+ );
+ }
+ }
$fooditem_id = sanitize_text_field ( wp_unslash( $_POST['fooditem_id'] ) );
$price = '';
if ( ! empty( $fooditem_id ) ) {
@@ -581,6 +691,7 @@
* Check Service Options availibility
*/
public static function check_service_slot() {
+ check_ajax_referer( 'service-type', 'security' );
$data = rpress_sanitize_array( $_POST );
$response = apply_filters( 'rpress_check_service_slot', $data );
$response = apply_filters( 'rpress_validate_slot', $response );
@@ -869,6 +980,8 @@
* Proceed Checkout
*/
public static function proceed_checkout() {
+ check_ajax_referer( 'proceed-checkout', 'security' );
+
$response = rpress_pre_validate_order();
$response = apply_filters( 'rpress_proceed_checkout', $response );
wp_send_json( $response );
@@ -880,12 +993,22 @@
*/
public static function get_order_details() {
check_admin_referer( 'rpress-preview-order', 'security' );
- if ( isset( $_GET['payment_id'] ) ){
- if( ! current_user_can( 'edit_shop_payments', $_GET['payment_id'] ) ) {
- wp_die( esc_html__( 'You do not have permission to update this order', 'restropress' ), esc_html__( 'Error', 'restropress' ), array( 'response' => 403 ) );
- }
+ $order_id = isset( $_GET['order_id'] ) ? absint( wp_unslash( $_GET['order_id'] ) ) : 0;
+
+ if ( empty( $order_id ) ) {
+ wp_send_json_error(
+ array(
+ 'message' => esc_html__( 'Invalid order request.', 'restropress' ),
+ ),
+ 400
+ );
+ }
+
+ if ( ! current_user_can( 'edit_shop_payments', $order_id ) ) {
+ wp_die( esc_html__( 'You do not have permission to update this order', 'restropress' ), esc_html__( 'Error', 'restropress' ), array( 'response' => 403 ) );
}
- $order = rpress_get_payment( absint( $_GET['order_id'] ) );
+
+ $order = rpress_get_payment( $order_id );
if ( $order ) {
include_once 'admin/payments/class-payments-table.php';
wp_send_json_success( RPRESS_Payment_History_Table::order_preview_get_order_details( $order ) );
@@ -1151,7 +1274,7 @@
*/
public static function fooditem_search() {
global $wpdb;
- $search = sanitize_text_field( $_GET['s'] );
+ $search = isset( $_GET['s'] ) ? sanitize_text_field( wp_unslash( $_GET['s'] ) ) : '';
$excludes = ( isset( $_GET['current_id'] ) ? (array) $_GET['current_id'] : array() );
$excludes = array_unique( array_map( 'absint', $excludes ) );
$exclude = implode( ",", $excludes );
@@ -1186,7 +1309,7 @@
foreach( $items as $item ) {
$results[] = array(
'id' => $item->ID,
- 'name' => $item->post_title
+ 'name' => wp_strip_all_tags( $item->post_title )
);
if ( $variations && rpress_has_variable_prices( $item->ID ) ) {
$prices = rpress_get_variable_prices( $item->ID );
@@ -1220,7 +1343,7 @@
*/
public static function customer_search() {
global $wpdb;
- $search = esc_sql( sanitize_text_field( $_GET['s'] ) );
+ $search = isset( $_GET['s'] ) ? esc_sql( sanitize_text_field( wp_unslash( $_GET['s'] ) ) ) : '';
$results = array();
$customer_view_role = apply_filters( 'rpress_view_customers_role', 'view_shop_reports' );
if ( ! current_user_can( $customer_view_role ) ) {
@@ -1237,13 +1360,15 @@
}
if( $customers ) {
foreach( $customers as $customer ) {
+ $customer_name = isset( $customer->name ) ? wp_strip_all_tags( $customer->name ) : '';
+ $customer_email = isset( $customer->email ) ? sanitize_email( $customer->email ) : '';
$results[] = array(
'id' => $customer->id,
- 'name' => $customer->name . '(' . $customer->email . ')'
+ 'name' => $customer_name . '(' . $customer_email . ')'
);
}
} else {
- $customers[] = array(
+ $results[] = array(
'id' => 0,
'name' => __( 'No results found', 'restropress' )
);
@@ -1259,7 +1384,7 @@
*/
public static function user_search() {
global $wpdb;
- $search = esc_sql( sanitize_text_field( $_GET['s'] ) );
+ $search = isset( $_GET['s'] ) ? esc_sql( sanitize_text_field( wp_unslash( $_GET['s'] ) ) ) : '';
$results = array();
$user_view_role = apply_filters( 'rpress_view_users_role', 'view_shop_reports' );
if ( ! current_user_can( $user_view_role ) ) {
@@ -1275,7 +1400,7 @@
foreach( $users as $user ) {
$results[] = array(
'id' => $user->ID,
- 'name' => $user->display_name,
+ 'name' => wp_strip_all_tags( $user->display_name ),
);
}
} else {
@@ -1295,8 +1420,8 @@
*/
public static function search_users() {
if( current_user_can( 'manage_shop_settings' ) ) {
- $search_query = trim( sanitize_text_field( $_POST['user_name'] ) );
- $exclude = trim( sanitize_text_field( $_POST['exclude'] ) );
+ $search_query = isset( $_POST['user_name'] ) ? trim( sanitize_text_field( wp_unslash( $_POST['user_name'] ) ) ) : '';
+ $exclude = isset( $_POST['exclude'] ) ? trim( sanitize_text_field( wp_unslash( $_POST['exclude'] ) ) ) : '';
$get_users_args = array(
'number' => 9999,
'search' => $search_query . '*'
@@ -1328,6 +1453,18 @@
* @return json | user notification json object
*/
public static function check_new_orders() {
+ $orders_cap = apply_filters( 'rpress_check_new_orders_cap', 'edit_shop_payments' );
+ if ( ! current_user_can( $orders_cap ) ) {
+ wp_send_json_error(
+ array(
+ 'message' => esc_html__( 'You do not have permission to access this resource.', 'restropress' ),
+ ),
+ 403
+ );
+ }
+
+ check_ajax_referer( 'rpress-check-new-orders', 'security' );
+
$last_order = get_option( 'rp_last_order_id' );
$order = rpress_get_payments( array( 'number' => 1, 'status' => array( 'publish' => __( 'Paid', 'restropress' ), 'processing' => __( 'Processing', 'restropress' )) ) );
if( is_array( $order ) && $order[0]->ID != $last_order ) {
@@ -1392,7 +1529,8 @@
'url' => home_url()
);
// Call the custom API.
- $response = wp_remote_post( 'https://www.restropress.com', array( 'timeout' => 15, 'sslverify' => false, 'body' => $api_params ) );
+ $verify_ssl = (bool) apply_filters( 'rpress_remote_request_verify_ssl', true );
+ $response = wp_remote_post( 'https://www.restropress.com', array( 'timeout' => 15, 'sslverify' => $verify_ssl, 'body' => $api_params ) );
// make sure the response came back okay
if ( is_wp_error( $response )
|| 200 !== wp_remote_retrieve_response_code( $response ) ) {
@@ -1471,7 +1609,8 @@
'url' => home_url()
);
// Call the custom API.
- $response = wp_remote_post( 'https://www.restropress.com', array( 'timeout' => 15, 'sslverify' => false, 'body' => $api_params ) );
+ $verify_ssl = (bool) apply_filters( 'rpress_remote_request_verify_ssl', true );
+ $response = wp_remote_post( 'https://www.restropress.com', array( 'timeout' => 15, 'sslverify' => $verify_ssl, 'body' => $api_params ) );
// make sure the response came back okay
if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) {
if ( is_wp_error( $response ) ) {
@@ -1504,9 +1643,18 @@
public static function show_order_details() {
check_ajax_referer( 'show-order-details', 'security' );
- $user = rpress_get_payment_meta_user_info( absint( $_POST['order_id'] ) );
-
- if( get_current_user_id() !== $user['id'] ) return;
+ $order_id = isset( $_POST['order_id'] ) ? absint( wp_unslash( $_POST['order_id'] ) ) : 0;
+
+ if ( ! self::can_access_frontend_order_action( $order_id ) ) {
+ wp_send_json_error(
+ array(
+ 'message' => esc_html__( 'You do not have permission to view this order.', 'restropress' ),
+ ),
+ 403
+ );
+ }
+
+ $_POST['order_id'] = $order_id;
ob_start();
rpress_get_template_part( 'rpress', 'show-order-details' );
$html = ob_get_clean();
@@ -1524,6 +1672,16 @@
*/
public static function more_order_history() {
check_ajax_referer( 'show-order-details', 'security' );
+
+ if ( ! is_user_logged_in() ) {
+ wp_send_json_error(
+ array(
+ 'message' => esc_html__( 'You must be logged in to view order history.', 'restropress' ),
+ ),
+ 403
+ );
+ }
+
ob_start();
include RP_PLUGIN_DIR . '/templates/rpress-order-history-load-more.php';
$html = ob_get_clean();
@@ -1531,13 +1689,19 @@
rpress_die();
}
public static function delete_user_address(){
+ check_ajax_referer( 'rpress-user-address', 'security' );
+
+ if ( ! is_user_logged_in() ) {
+ wp_send_json_error( array( 'success' => false ), 403 );
+ }
+
if( isset( $_POST['index'] ) ) {
- $index = $_POST['index'];
+ $index = absint( wp_unslash( $_POST['index'] ) );
$user_id = get_current_user_id();
// Get user addresses
$user_addresses = get_user_meta($user_id, 'user_addresses', true);
- if(!empty($user_addresses)){
+ if(!empty($user_addresses) && isset( $user_addresses[ $index ] )){
// Remove the address array from the main array
unset($user_addresses[$index]);
@@ -1558,11 +1722,21 @@
}
}
public static function default_user_address(){
+ check_ajax_referer( 'rpress-user-address', 'security' );
+
+ if ( ! is_user_logged_in() ) {
+ wp_send_json_error( array( 'success' => false ), 403 );
+ }
+
if( isset( $_POST['index'] ) ) {
- $index = $_POST['index'];
+ $index = absint( wp_unslash( $_POST['index'] ) );
$user_id = get_current_user_id();
// Get user addresses
$user_addresses = get_user_meta( $user_id, 'user_addresses', true );
+ if ( empty( $user_addresses ) || ! isset( $user_addresses[ $index ] ) ) {
+ echo wp_json_encode( ['success' => false] );
+ return;
+ }
$default_address = $user_addresses[$index];
$new_address = array(
@@ -1596,6 +1770,7 @@
* @return json
*/
public static function checkout_update_service_option() {
+ check_ajax_referer( 'update-service', 'security' );
do_action( 'rpress_checkout_service_option_updated' );
ob_start();
rpress_order_details_fields();
@@ -1613,6 +1788,7 @@
rpress_die();
}
public static function remove_fees_after_empty_cart() {
+ check_ajax_referer( 'clear-cart', 'security' );
RPRESS()->session->set('rpress_cart', null);
// Remove all cart fees.
@@ -1629,7 +1805,9 @@
}
public static function update_modal_on_service_switch() {
- $service_type = $_GET['service_type'];
+ check_ajax_referer( 'service-type', 'security' );
+
+ $service_type = isset( $_GET['service_type'] ) ? sanitize_text_field( wp_unslash( $_GET['service_type'] ) ) : '';
ob_start();
rpress_get_template_part('rpress','datetime-popup');
--- a/restropress/includes/class-rpress-frontend-scripts.php
+++ b/restropress/includes/class-rpress-frontend-scripts.php
@@ -219,6 +219,7 @@
self::enqueue_script('swl-js');
$user_params = array(
'ajaxurl' => rpress_get_ajax_url(),
+ 'address_nonce' => wp_create_nonce( 'rpress-user-address' ),
);
wp_register_script('user-dashboard-scripts', plugin_dir_url(RP_PLUGIN_FILE) . 'assets/js/user-dashboard.js', array('jquery'), RP_VERSION, true);
wp_localize_script('user-dashboard-scripts', 'users', $user_params);
@@ -294,14 +295,14 @@
'success' => esc_html__('Success', 'restropress'),
'success_empty_cart' => esc_html__('Cart cleared', 'restropress'),
'decimal_separator' => rpress_get_option('decimal_separator', '.'),
- 'cart_quantity' => $cart_quantity,
- 'items' => esc_html__('Items', 'restropress'),
- 'no_image' => RP_PLUGIN_URL . 'assets/images/no-image.png',
- 'always_open' => !empty(rpress_get_option('enable_always_open')) ? '1' : '0',
- 'open_hours' => (rpress_get_option('enable_always_open')) ? '12:00am' : rpress_get_option('open_time'),
- 'close_hours' => (rpress_get_option('enable_always_open')) ? '11:59pm' : rpress_get_option('close_time'),
- 'closed_message' => $closed_message,
- );
+ 'cart_quantity' => $cart_quantity,
+ 'items' => esc_html__('Items', 'restropress'),
+ 'no_image' => RP_PLUGIN_URL . 'assets/images/no-image.png',
+ 'always_open' => !empty(rpress_get_option('enable_always_open')) ? '1' : '0',
+ 'open_hours' => (rpress_get_option('enable_always_open')) ? '12:00am' : rpress_get_option('open_time'),
+ 'close_hours' => (rpress_get_option('enable_always_open')) ? '11:59pm' : rpress_get_option('close_time'),
+ 'closed_message' => $closed_message,
+ );
$cookie_service = isset($_COOKIE['service_type']) ? sanitize_text_field(wp_unslash($_COOKIE['service_type'])) : $default_service;
$cookie_service = apply_filters('rpress_current_service_type', $cookie_service);
--- a/restropress/includes/class-rpress-print-receipts.php
+++ b/restropress/includes/class-rpress-print-receipts.php
@@ -133,13 +133,14 @@
*
*/
public function rp_print_payment_data() {
-
- if( ! current_user_can( 'edit_shop_payments', $_GET['payment_id'] ) ) {
- wp_die( esc_html__( 'You do not have permission to update this order', 'restropress' ), esc_html__( 'Error', 'restropress' ), array( 'response' => 403 ) );
+ check_ajax_referer( 'rpress-order', 'security' );
+
+ $payment_id = isset( $_GET['payment_id'] ) ? absint( wp_unslash( $_GET['payment_id'] ) ) : '';
+
+ if ( ! current_user_can( 'edit_shop_payments', $payment_id ) ) {
+ wp_die( esc_html__( 'You do not have permission to update this order', 'restropress' ), esc_html__( 'Error', 'restropress' ), array( 'response' => 403 ) );
}
- $payment_id = isset( $_GET['payment_id'] ) ? absint( $_GET['payment_id'] ) : '';
-
if( empty( $payment_id ) ) return;
$payment = new RPRESS_Payment( $payment_id );
@@ -285,4 +286,4 @@
return $payment_receipt;
}
}
-$print_receipts = new RPRESS_Print_Receipts();
No newline at end of file
+$print_receipts = new RPRESS_Print_Receipts();
--- a/restropress/includes/class-rpress.php
+++ b/restropress/includes/class-rpress.php
@@ -18,7 +18,7 @@
*
* @var string
*/
- public $version = '3.2.7';
+ public $version = '3.2.8';
/**
* The single instance of the class.
*
--- a/restropress/includes/process-purchase.php
+++ b/restropress/includes/process-purchase.php
@@ -30,19 +30,45 @@
// Validate the form $_POST data
$valid_data = rpress_purchase_form_validate_fields();
- // Check cookies for service type and service time
- $service_type = isset( $_COOKIE['service_type'] ) ? sanitize_text_field( $_COOKIE['service_type'] ) : '';
- $service_time = isset( $_COOKIE['service_time'] ) ? sanitize_text_field( $_COOKIE['service_time'] ) : '';
-
- if ( empty( $service_type ) ) {
- $valid_data = false;
- rpress_set_error( 'missing_service_type', __( 'Please select a service type.', 'restropress' ) );
- }
-
- if ( empty( $service_time ) ) {
- $valid_data = false;
- rpress_set_error( 'missing_service_time', __( 'Please select a service time.', 'restropress' ) );
- }
+ // Validate selected service context from cookies.
+ $service_type = isset( $_POST['rpress_service_type'] ) ? sanitize_key( wp_unslash( $_POST['rpress_service_type'] ) ) : '';
+ if ( empty( $service_type ) ) {
+ $service_type = isset( $_COOKIE['service_type'] ) ? sanitize_key( wp_unslash( $_COOKIE['service_type'] ) ) : '';
+ }
+ $service_time = isset( $_POST['rpress_service_time'] ) ? sanitize_text_field( wp_unslash( $_POST['rpress_service_time'] ) ) : '';
+ if ( empty( $service_time ) ) {
+ $service_time = isset( $_COOKIE['service_time'] ) ? sanitize_text_field( wp_unslash( $_COOKIE['service_time'] ) ) : '';
+ }
+ $service_date = isset( $_POST['rpress_service_date'] ) ? sanitize_text_field( wp_unslash( $_POST['rpress_service_date'] ) ) : '';
+ if ( empty( $service_date ) ) {
+ $service_date = isset( $_COOKIE['service_date'] ) ? sanitize_text_field( wp_unslash( $_COOKIE['service_date'] ) ) : '';
+ }
+ $enabled_service = rpress_get_option( 'enable_service', 'delivery_and_pickup' );
+ $allowed_services = ( 'delivery_and_pickup' === $enabled_service ) ? array( 'delivery', 'pickup' ) : array( $enabled_service );
+ $allowed_services = array_map( 'sanitize_key', $allowed_services );
+
+ if ( empty( $service_type ) || ! in_array( $service_type, $allowed_services, true ) ) {
+ $valid_data = false;
+ rpress_set_error( 'missing_service_type', __( 'Please select a service type.', 'restropress' ) );
+ }
+
+ if ( ! empty( $service_type ) ) {
+ if ( empty( $service_date ) ) {
+ $service_date = rp_row_date( '', $service_type );
+ }
+
+ if ( ! rpress_is_store_open( $service_type, $service_date ) ) {
+ $valid_data = false;
+ // Reuse checkout-wide order error key to avoid duplicate store-closed notices.
+ rpress_set_error( 'order_error', rpress_store_closed_message( $service_type ) );
+ }
+ }
+
+ $service_time_hidden = ! empty( $service_type ) && function_exists( 'rp_otil_is_service_time_hidden' ) && rp_otil_is_service_time_hidden( $service_type );
+ if ( empty( $service_time ) && ! $service_time_hidden ) {
+ $valid_data = false;
+ rpress_set_error( 'missing_service_time', __( 'Please select a service time.', 'restropress' ) );
+ }
// Allow themes and plugins to hook to errors
do_action( 'rpress_checkout_error_checks', $valid_data, $data );
@@ -198,21 +224,24 @@
$is_ajax = isset( $_POST['rpress_ajax'] ) ? sanitize_text_field( $_POST['rpress_ajax'] ) : null;
$user_data = rpress_purchase_form_validate_user_login();
if ( rpress_get_errors() || $user_data['user_id'] < 1 ) {
- if ( $is_ajax ) {
- do_action( 'rpress_ajax_checkout_errors' );
- rpress_die();
- } else {
- wp_redirect( $_SERVER['HTTP_REFERER'] ); exit;
- }
- }
+ if ( $is_ajax ) {
+ do_action( 'rpress_ajax_checkout_errors' );
+ rpress_die();
+ } else {
+ $redirect_url = wp_get_referer() ? wp_get_referer() : rpress_get_checkout_uri();
+ wp_safe_redirect( $redirect_url );
+ exit;
+ }
+ }
rpress_log_user_in( $user_data['user_id'], $user_data['user_login'], $user_data['user_pass'] );
- if ( $is_ajax ) {
- echo 'success';
- rpress_die();
- } else {
- wp_redirect( rpress_get_checkout_uri( $_SERVER['QUERY_STRING'] ) );
- }
-}
+ if ( $is_ajax ) {
+ echo 'success';
+ rpress_die();
+ } else {
+ $query_string = isset( $_SERVER['QUERY_STRING'] ) ? sanitize_text_field( wp_unslash( $_SERVER['QUERY_STRING'] ) ) : '';
+ wp_safe_redirect( rpress_get_checkout_uri( $query_string ) );
+ }
+}
add_action( 'wp_ajax_rpress_process_checkout_login', 'rpress_process_purchase_login' );
add_action( 'wp_ajax_nopriv_rpress_process_checkout_login', 'rpress_process_purchase_login' );
/**
@@ -309,13 +338,17 @@
* @since 2.7.2
* @return bool
*/
-function rpress_validate_service_type() {
- if( empty( $_COOKIE['service_type'] ) ) {
- rpress_set_error( 'empty_service_type', __( 'Please select a Service.', 'restropress' ) );
- } else {
- return true;
- }
-}
+function rpress_validate_service_type() {
+ $service_type = isset( $_POST['rpress_service_type'] ) ? sanitize_key( wp_unslash( $_POST['rpress_service_type'] ) ) : '';
+ if ( empty( $service_type ) ) {
+ $service_type = isset( $_COOKIE['service_type'] ) ? sanitize_key( wp_unslash( $_COOKIE['service_type'] ) ) : '';
+ }
+ if( empty( $service_type ) ) {
+ rpress_set_error( 'empty_service_type', __( 'Please select a Service.', 'restropress' ) );
+ } else {
+ return true;
+ }
+}
/**
* Purchase Form Validate Gateway
*
--- a/restropress/includes/rp-ajax-functions.php
+++ b/restropress/includes/rp-ajax-functions.php
@@ -114,33 +114,33 @@
* @since 1.0
* @return void
*/
-function get_fooditem_lists($fooditem_id, $cart_key = '')
-{
- $addons = get_post_meta($fooditem_id, '_addon_items', true);
- if (!is_array($addons)) {
- $addons = array();
- }
-
- $chosen_addons = array();
- $addon_quantity = [];
- $price_id = 0;
- $addon_ids = $child_ids = array();
- if (!empty($addons)) {
- foreach ($addons as $addon) {
- if (!empty($addon['category'])) {
- $addon_ids[] = absint($addon['category']);
- if (isset($addon['items']) && is_array($addon['items'])) {
- $child_ids = array_merge($child_ids, $addon['items']);
- }
- }
- }
- }
- $addon_ids = array_values(array_unique(array_filter(array_map('absint', $addon_ids))));
- $child_ids = array_values(array_unique(array_filter(array_map('absint', $child_ids))));
-
- if ($cart_key !== '') {
- $cart_contents = rpress_get_cart_contents();
- $cart_contents = $cart_contents[$cart_key];
+function get_fooditem_lists($fooditem_id, $cart_key = '')
+{
+ $addons = get_post_meta($fooditem_id, '_addon_items', true);
+ if (!is_array($addons)) {
+ $addons = array();
+ }
+
+ $chosen_addons = array();
+ $addon_quantity = [];
+ $price_id = 0;
+ $addon_ids = $child_ids = array();
+ if (!empty($addons)) {
+ foreach ($addons as $addon) {
+ if (!empty($addon['category'])) {
+ $addon_ids[] = absint($addon['category']);
+ if (isset($addon['items']) && is_array($addon['items'])) {
+ $child_ids = array_merge($child_ids, $addon['items']);
+ }
+ }
+ }
+ }
+ $addon_ids = array_values(array_unique(array_filter(array_map('absint', $addon_ids))));
+ $child_ids = array_values(array_unique(array_filter(array_map('absint', $child_ids))));
+
+ if ($cart_key !== '') {
+ $cart_contents = rpress_get_cart_contents();
+ $cart_contents = $cart_contents[$cart_key];
$price_id = isset($cart_contents['price_id']) ? $cart_contents['price_id'] : 0;
if (!empty($cart_contents['addon_items'])) {
@@ -214,25 +214,25 @@
if (empty($addon_items)) {
continue;
}
- $addon_name = $addon_items->name;
- $addon_slug = $addon_items->slug;
- $addon_id = $addon_items->term_id;
- $addon_config = isset($addons[$parent]) && is_array($addons[$parent]) ? $addons[$parent] : array();
-
- // Backward compatibility: some datasets store addon rows as numeric arrays.
- if (empty($addon_config)) {
- foreach ($addons as $addon_row) {
- if (!empty($addon_row['category']) && absint($addon_row['category']) === absint($parent)) {
- $addon_config = $addon_row;
- break;
- }
- }
- }
-
- $is_required = isset($addon_config['is_required']) ? $addon_config['is_required'] : 'no';
- $max_addons = isset($addon_config['max_addons']) ? $addon_config['max_addons'] : 0;
- $min_addons = isset($addon_config['min_addons']) ? $addon_config['min_addons'] : 0;
- $is_default = isset($addon_config['default']) ? $addon_config['default'] : array();
+ $addon_name = $addon_items->name;
+ $addon_slug = $addon_items->slug;
+ $addon_id = $addon_items->term_id;
+ $addon_config = isset($addons[$parent]) && is_array($addons[$parent]) ? $addons[$parent] : array();
+
+ // Backward compatibility: some datasets store addon rows as numeric arrays.
+ if (empty($addon_config)) {
+ foreach ($addons as $addon_row) {
+ if (!empty($addon_row['category']) && absint($addon_row['category']) === absint($parent)) {
+ $addon_config = $addon_row;
+ break;
+ }
+ }
+ }
+
+ $is_required = isset($addon_config['is_required']) ? $addon_config['is_required'] : 'no';
+ $max_addons = isset($addon_config['max_addons']) ? $addon_config['max_addons'] : 0;
+ $min_addons = isset($addon_config['min_addons']) ? $addon_config['min_addons'] : 0;
+ $is_default = isset($addon_config['default']) ? $addon_config['default'] : array();
if (!empty($is_default))
$chosen_addons = array_merge($chosen_addons, $is_default);
@@ -279,14 +279,14 @@
<input type="hidden" name="max_limit" class="addon_max_limit" value="<?php echo esc_attr($max_addons); ?>" />
<input type="hidden" name="min_limit" class="addon_min_limit" value="<?php echo esc_attr($min_addons); ?>" />
<?php
- $addon_category_args = array(
- 'taxonomy' => 'addon_category',
- 'parent' => $addon_items->term_id,
- );
- if (!empty($child_ids)) {
- $addon_category_args['include'] = $child_ids;
- }
- $child_addons = get_terms(apply_filters('rp_addon_category', $addon_category_args));
+ $addon_category_args = array(
+ 'taxonomy' => 'addon_category',
+ 'parent' => $addon_items->term_id,
+