| 1 |
<?php |
| 2 |
/** |
| 3 |
* Plugin Name: Shop as Client for WooCommerce |
| 4 |
* Plugin URI: https://nakedcatplugins.com/product/shop-as-client-for-woocommerce-pro-add-on/ |
| 5 |
* Description: Allows a WooCommerce Store Administrator or Shop Manager to use the frontend and assign a new order to a registered or new customer. Useful for phone or email orders. |
| 6 |
* Version: 7.3 |
| 7 |
* Author: Naked Cat Plugins (by Webdados) |
| 8 |
* Author URI: https://nakedcatplugins.com/ |
| 9 |
* Text Domain: shop-as-client |
| 10 |
* Domain Path: /languages |
| 11 |
* Requires at least: 5.8 |
| 12 |
* Tested up to: 7.0 |
| 13 |
* Requires PHP: 7.4 |
| 14 |
* WC requires at least: 7.1 |
| 15 |
* WC tested up to: 10.5 |
| 16 |
* Requires Plugins: woocommerce |
| 17 |
* License: GPLv3 |
| 18 |
**/ |
| 19 |
|
| 20 |
/* WooCommerce CRUD ready */ |
| 21 |
|
| 22 |
if ( ! defined( 'ABSPATH' ) ) { |
| 23 |
exit; // Exit if accessed directly |
| 24 |
} |
| 25 |
|
| 26 |
if ( ! defined( 'SHOPASCLIENT_REQUIRED_WC' ) ) { |
| 27 |
define( 'SHOPASCLIENT_REQUIRED_WC', '7.1' ); |
| 28 |
} |
| 29 |
define( 'SHOPASCLIENT_PLUGIN_DIR', plugin_dir_path( __FILE__ ) ); |
| 30 |
define( 'SHOPASCLIENT_PLUGIN_URL', plugin_dir_url( __FILE__ ) ); |
| 31 |
define( 'SHOPASCLIENT_PRO_OUT_LINK', 'https://nakedcatplugins.com/product/shop-as-client-for-woocommerce-pro-add-on/?utm_source=' . rawurlencode( esc_url( home_url( '/' ) ) ) . '&utm_medium=link&utm_campaign=shop_as_client_plugin' ); |
| 32 |
|
| 33 |
/** |
| 34 |
* Check if WooCommerce is active |
| 35 |
* plugins_loaded is too soon for code in functions.php to run - This needs to be addressed, but it probably won't work because on the initialization of blocks |
| 36 |
*/ |
| 37 |
add_action( |
| 38 |
'plugins_loaded', |
| 39 |
function () { |
| 40 |
if ( class_exists( 'WooCommerce' ) && defined( 'WC_VERSION' ) && version_compare( WC_VERSION, SHOPASCLIENT_REQUIRED_WC, '>=' ) ) { |
| 41 |
|
| 42 |
/** |
| 43 |
* Version |
| 44 |
*/ |
| 45 |
if ( ! function_exists( 'get_plugin_data' ) ) { |
| 46 |
include ABSPATH . '/wp-admin/includes/plugin.php'; |
| 47 |
} |
| 48 |
$temp_plugin_data = get_plugin_data( __FILE__, false, false ); |
| 49 |
define( 'SHOPASCLIENT_VERSION', $temp_plugin_data['Version'] ); |
| 50 |
|
| 51 |
/** |
| 52 |
* Languages and scripts |
| 53 |
*/ |
| 54 |
function shop_as_client_init() { |
| 55 |
// Load scripts |
| 56 |
add_action( 'wp_enqueue_scripts', 'shop_as_client_enqueue_scripts' ); |
| 57 |
} |
| 58 |
add_action( 'plugins_loaded', 'shop_as_client_init', 7 ); |
| 59 |
|
| 60 |
/** |
| 61 |
* Fake settings link |
| 62 |
* |
| 63 |
* @param array $links The current links. |
| 64 |
*/ |
| 65 |
function shop_as_client_add_settings_link( $links ) { |
| 66 |
$action_links = array( |
| 67 |
sprintf( |
| 68 |
'<a href="admin.php?page=wc-settings&tab=account#shop_as_client_pro_license_key">%s</a>', |
| 69 |
__( 'Settings', 'shop-as-client' ) |
| 70 |
), |
| 71 |
); |
| 72 |
return array_merge( $links, $action_links ); |
| 73 |
} |
| 74 |
add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), 'shop_as_client_add_settings_link' ); |
| 75 |
|
| 76 |
/** |
| 77 |
* Fake settings |
| 78 |
* |
| 79 |
* @param array $settings The current settings. |
| 80 |
*/ |
| 81 |
function shop_as_client_woocommerce_account_settings( $settings ) { |
| 82 |
$our_settings = array(); |
| 83 |
if ( ! defined( 'SHOPASCLIENT_PRO_PLUGIN_FILE' ) ) { |
| 84 |
$description = sprintf( |
| 85 |
/* translators: %1$s: link open, %2$s: link close */ |
| 86 |
__( 'Available on the %1$sPRO Add-on%2$s', 'shop-as-client' ), |
| 87 |
'<a href="' . esc_url( SHOPASCLIENT_PRO_OUT_LINK ) . '">', |
| 88 |
'</a>' |
| 89 |
); |
| 90 |
$our_settings = array( |
| 91 |
array( |
| 92 |
'title' => __( 'Shop as Client', 'shop-as-client' ) . sprintf( |
| 93 |
' (Free %s)', |
| 94 |
SHOPASCLIENT_VERSION |
| 95 |
), |
| 96 |
'type' => 'title', |
| 97 |
'id' => 'shop_as_client_options', |
| 98 |
), |
| 99 |
// Disabled fields here (shop as client default, create user field default, search on orders, update customer, clear checkout fields, Handler) |
| 100 |
array( |
| 101 |
'title' => __( 'Shop as client field default', 'shop-as-client' ), |
| 102 |
'id' => 'shop_as_client_pro_shop_as_client_default', |
| 103 |
'type' => 'select', |
| 104 |
'options' => array( |
| 105 |
'yes' => __( 'Yes', 'shop-as-client' ), |
| 106 |
'no' => __( 'No', 'shop-as-client' ), |
| 107 |
), |
| 108 |
'default' => 'yes', |
| 109 |
'desc' => $description, |
| 110 |
'custom_attributes' => array( |
| 111 |
'disabled' => 'disabled', |
| 112 |
), |
| 113 |
), |
| 114 |
array( |
| 115 |
'title' => __( 'Create user field default', 'shop-as-client' ), |
| 116 |
'id' => 'shop_as_client_pro_create_user_default', |
| 117 |
'type' => 'select', |
| 118 |
'options' => array( |
| 119 |
'yes' => __( 'Yes', 'shop-as-client' ), |
| 120 |
'no' => __( 'No', 'shop-as-client' ), |
| 121 |
), |
| 122 |
'default' => 'yes', |
| 123 |
'desc' => $description, |
| 124 |
'custom_attributes' => array( |
| 125 |
'disabled' => 'disabled', |
| 126 |
), |
| 127 |
), |
| 128 |
array( |
| 129 |
'title' => __( 'Search on orders', 'shop-as-client' ), |
| 130 |
'desc' => __( 'By default, the search is only performed on registered users by their registration and billing email, but if you enable this option it will also be done on orders (if not found as user), so you can get data from guest customers.', 'shop-as-client' ) . '<br/>' . $description, |
| 131 |
'id' => 'shop_as_client_pro_search_orders', |
| 132 |
'type' => 'select', |
| 133 |
'options' => array( |
| 134 |
'yes' => __( 'Yes', 'shop-as-client' ), |
| 135 |
'no' => __( 'No', 'shop-as-client' ), |
| 136 |
), |
| 137 |
'default' => 'yes', |
| 138 |
'custom_attributes' => array( |
| 139 |
'disabled' => 'disabled', |
| 140 |
), |
| 141 |
), |
| 142 |
array( |
| 143 |
'title' => __( 'Update customer', 'shop-as-client' ), |
| 144 |
'desc' => __( 'Update the customer details on his profile', 'shop-as-client' ) . '<br/>' . $description, |
| 145 |
'id' => 'shop_as_client_pro_update_customer', |
| 146 |
'type' => 'select', |
| 147 |
'options' => array( |
| 148 |
'yes' => __( 'Yes', 'shop-as-client' ), |
| 149 |
'no' => __( 'No', 'shop-as-client' ), |
| 150 |
), |
| 151 |
'default' => 'yes', |
| 152 |
'custom_attributes' => array( |
| 153 |
'disabled' => 'disabled', |
| 154 |
), |
| 155 |
), |
| 156 |
array( |
| 157 |
'title' => __( 'Clear checkout fields', 'shop-as-client' ), |
| 158 |
'desc' => ( |
| 159 |
__( 'Default all checkout fields to blank for Administrators and Shop Managers', 'shop-as-client' ) |
| 160 |
. |
| 161 |
'<br/>' |
| 162 |
. |
| 163 |
__( 'Only on the classic checkout', 'shop-as-client' ) . '<br/>' . $description |
| 164 |
), |
| 165 |
'id' => 'shop_as_client_pro_empty_checkout', |
| 166 |
'type' => 'select', |
| 167 |
'options' => array( |
| 168 |
'yes' => __( 'Yes', 'shop-as-client' ), |
| 169 |
'no' => __( 'No', 'shop-as-client' ), |
| 170 |
), |
| 171 |
'default' => 'yes', |
| 172 |
'custom_attributes' => array( |
| 173 |
'disabled' => 'disabled', |
| 174 |
), |
| 175 |
), |
| 176 |
array( |
| 177 |
'title' => __( 'Handler on orders list', 'shop-as-client' ), |
| 178 |
'desc' => __( 'Add a column with the order handler and allow filtering by handler on the admin orders list', 'shop-as-client' ) . '<br/>' . $description, |
| 179 |
'id' => 'shop_as_client_pro_handler_order_list', |
| 180 |
'type' => 'select', |
| 181 |
'options' => array( |
| 182 |
'yes' => __( 'Yes', 'shop-as-client' ), |
| 183 |
'no' => __( 'No', 'shop-as-client' ), |
| 184 |
), |
| 185 |
'default' => 'yes', |
| 186 |
'custom_attributes' => array( |
| 187 |
'disabled' => 'disabled', |
| 188 |
), |
| 189 |
), |
| 190 |
array( |
| 191 |
'type' => 'sectionend', |
| 192 |
'id' => 'shop_as_client_options', |
| 193 |
), |
| 194 |
); |
| 195 |
} |
| 196 |
return array_merge( $settings, $our_settings ); |
| 197 |
} |
| 198 |
add_filter( 'woocommerce_account_settings', 'shop_as_client_woocommerce_account_settings' ); |
| 199 |
|
| 200 |
/** |
| 201 |
* Can checkout with shop as client? - Should be used for both classic and blocks checkout |
| 202 |
* |
| 203 |
* @param integer $user_id The user ID to check or null to check the current logged-in user. |
| 204 |
*/ |
| 205 |
function shop_as_client_can_checkout( $user_id = null ) { |
| 206 |
if ( is_null( $user_id ) ) { |
| 207 |
// The shop_as_client_allow_checkout filter can be used to allow other user roles to use this functionality - Use carefully and wisely |
| 208 |
return current_user_can( 'manage_options' ) || current_user_can( 'manage_woocommerce' ) || apply_filters( 'shop_as_client_allow_checkout', false, null ); |
| 209 |
} elseif ( intval( $user_id ) > 0 ) { |
| 210 |
return user_can( intval( $user_id ), 'manage_options' ) || user_can( intval( $user_id ), 'manage_woocommerce' ) || apply_filters( 'shop_as_client_allow_checkout', false, $user_id ); |
| 211 |
} |
| 212 |
return false; |
| 213 |
} |
| 214 |
|
| 215 |
/** |
| 216 |
* Our field - Classic checkout only - Blocks checkout in includes/class-shop-as-client-checkout-blocks.php |
| 217 |
* |
| 218 |
* @param array $fields The fields. |
| 219 |
*/ |
| 220 |
function shop_as_client_init_woocommerce_checkout_fields( $fields ) { |
| 221 |
if ( shop_as_client_can_checkout() ) { |
| 222 |
$priority = apply_filters( 'shop_as_client_field_priority', 990 ); |
| 223 |
// Shop as client? |
| 224 |
$fields['billing']['billing_shop_as_client'] = array( |
| 225 |
'label' => __( 'Shop as client', 'shop-as-client' ), |
| 226 |
'required' => true, |
| 227 |
'class' => apply_filters( 'shop_as_client_field_class', array( 'form-row-wide' ) ), |
| 228 |
'input_class' => apply_filters( 'shop_as_client_field_input_class', array() ), |
| 229 |
'label_class' => apply_filters( 'shop_as_client_field_label_class', array() ), |
| 230 |
'clear' => true, |
| 231 |
'priority' => $priority, |
| 232 |
'type' => 'select', |
| 233 |
'options' => array( |
| 234 |
'yes' => __( 'Yes', 'shop-as-client' ), |
| 235 |
'no' => __( 'No', 'shop-as-client' ), |
| 236 |
), |
| 237 |
'default' => apply_filters( 'shop_as_client_default_shop_as_client', 'yes' ), |
| 238 |
); |
| 239 |
$priority++; |
| 240 |
// Create user if it doesn't exist? |
| 241 |
$fields['billing']['billing_shop_as_client_create_user'] = array( |
| 242 |
'label' => __( 'Create user (if not found by email)?', 'shop-as-client' ), |
| 243 |
'required' => true, |
| 244 |
'class' => apply_filters( 'shop_as_client_create_user_field_class', array( 'form-row-wide' ) ), |
| 245 |
'input_class' => apply_filters( 'shop_as_client_create_user_field_input_class', array() ), |
| 246 |
'label_class' => apply_filters( 'shop_as_client_create_user_field_label_class', array() ), |
| 247 |
'clear' => true, |
| 248 |
'priority' => $priority, |
| 249 |
'type' => 'select', |
| 250 |
'options' => array( |
| 251 |
'yes' => __( 'Yes', 'shop-as-client' ), |
| 252 |
'no' => __( 'No (leave as guest)', 'shop-as-client' ), |
| 253 |
), |
| 254 |
'default' => apply_filters( 'shop_as_client_default_create_user', 'no' ), |
| 255 |
); |
| 256 |
} |
| 257 |
return $fields; |
| 258 |
} |
| 259 |
add_filter( 'woocommerce_checkout_fields', 'shop_as_client_init_woocommerce_checkout_fields', PHP_INT_MAX ); |
| 260 |
|
| 261 |
/** |
| 262 |
* Enqueue scripts - Classic checkout only - Blocks checkout in includes/class-shop-as-client-checkout-blocks.php |
| 263 |
*/ |
| 264 |
function shop_as_client_enqueue_scripts() { |
| 265 |
if ( |
| 266 |
function_exists( 'is_checkout' ) |
| 267 |
&& |
| 268 |
is_checkout() |
| 269 |
&& |
| 270 |
( ! has_block( 'woocommerce/checkout' ) ) // Not on the Blocks checkout |
| 271 |
) { |
| 272 |
wp_enqueue_script( 'shop-as-client', plugins_url( 'js/functions.js', __FILE__ ), array( 'jquery' ), '1.3.0', true ); |
| 273 |
wp_localize_script( |
| 274 |
'shop-as-client', |
| 275 |
'shop_as_client', |
| 276 |
array( |
| 277 |
'txt_pro' => sprintf( |
| 278 |
'<p><a href="%s" target="_blank">%s</a></p>', |
| 279 |
esc_url( SHOPASCLIENT_PRO_OUT_LINK ), |
| 280 |
__( 'Do you want to load the customer details automatically?<br/>Get the PRO add-on!', 'shop-as-client' ) |
| 281 |
), |
| 282 |
) |
| 283 |
); |
| 284 |
} |
| 285 |
} |
| 286 |
|
| 287 |
/** |
| 288 |
* Force our field defaults - Shop as Client |
| 289 |
*/ |
| 290 |
function shop_as_client_default_checkout_billing_shop_as_client() { |
| 291 |
return apply_filters( 'shop_as_client_default_shop_as_client', 'yes' ); |
| 292 |
} |
| 293 |
add_filter( 'default_checkout_billing_shop_as_client', 'shop_as_client_default_checkout_billing_shop_as_client', 10, 0 ); |
| 294 |
|
| 295 |
/** |
| 296 |
* Force our field defaults - Create user |
| 297 |
*/ |
| 298 |
function shop_as_client_default_checkout_billing_shop_as_client_create_user() { |
| 299 |
return apply_filters( 'shop_as_client_default_create_user', 'no' ); |
| 300 |
} |
| 301 |
add_filter( 'default_checkout_billing_shop_as_client_create_user', 'shop_as_client_default_checkout_billing_shop_as_client_create_user', 10, 0 ); |
| 302 |
|
| 303 |
/** |
| 304 |
* Get order "shop as client" |
| 305 |
* |
| 306 |
* @param WC_Order $order The order. |
| 307 |
*/ |
| 308 |
function shop_as_client_get_order_status( $order ) { |
| 309 |
return 'yes' === $order->get_meta( '_billing_shop_as_client' ); |
| 310 |
} |
| 311 |
|
| 312 |
/** |
| 313 |
* Return yes to woocommerce_registration_generate_password |
| 314 |
* |
| 315 |
* @param string $value If the password should be generated. |
| 316 |
*/ |
| 317 |
function shop_as_client_woocommerce_registration_generate_password( $value ) { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.Found |
| 318 |
return 'yes'; |
| 319 |
} |
| 320 |
|
| 321 |
/** |
| 322 |
* Set order user - Inspiration: https://gist.github.com/twoelevenjay/80294a635969a54e4693 |
| 323 |
* Classic checkout only - Blocks alternative missing - https://github.com/woocommerce/woocommerce/issues/44530 |
| 324 |
* |
| 325 |
* @param integer $user_id The original order user ID. |
| 326 |
* @throws Exception Error message. |
| 327 |
*/ |
| 328 |
function shop_as_client_woocommerce_checkout_customer_id( $user_id ) { |
| 329 |
// WooCommerce took care of nonces |
| 330 |
// phpcs:disable WordPress.Security.NonceVerification.Missing |
| 331 |
if ( shop_as_client_can_checkout() ) { |
| 332 |
$billing_shop_as_client = isset( $_POST['billing_shop_as_client'] ) ? trim( sanitize_text_field( wp_unslash( $_POST['billing_shop_as_client'] ) ) ) : ''; |
| 333 |
if ( 'yes' === $billing_shop_as_client ) { |
| 334 |
$user_id = 0; |
| 335 |
// Check if an exisiting user already uses this email address. |
| 336 |
$user_email = isset( $_POST['billing_email'] ) ? sanitize_email( wp_unslash( $_POST['billing_email'] ) ) : ''; |
| 337 |
if ( empty( $user_email ) ) { |
| 338 |
$user_email = apply_filters( 'shop_as_client_user_email_if_empty', $user_email, $_POST ); |
| 339 |
} |
| 340 |
// Get user by profile email |
| 341 |
$user = get_user_by( 'email', $user_email ); |
| 342 |
if ( $user ) { |
| 343 |
// User found |
| 344 |
$user_id = $user->ID; |
| 345 |
// Should we update the user details? - This is by WooCommerce on WC_Checkout process_customer - Working on Blocks too |
| 346 |
} elseif ( |
| 347 |
( ! empty( $user_email ) ) |
| 348 |
&& |
| 349 |
( $users = get_users( // phpcs:ignore Generic.CodeAnalysis.AssignmentInCondition.Found, Squiz.PHP.DisallowMultipleAssignments.FoundInControlStructure |
| 350 |
// Get user by WooCommerce billing email |
| 351 |
array( |
| 352 |
'meta_key' => 'billing_email', // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key |
| 353 |
'meta_value' => $user_email, // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value |
| 354 |
'meta_compare' => '=', |
| 355 |
) |
| 356 |
) ) |
| 357 |
) { |
| 358 |
// User found - We should check for more than one... (There's no real solution for this) |
| 359 |
$user_id = $users[0]->ID; |
| 360 |
} else { |
| 361 |
// Create user or guest? |
| 362 |
$billing_shop_as_client_create_user = isset( $_POST['billing_shop_as_client_create_user'] ) ? trim( sanitize_text_field( wp_unslash( $_POST['billing_shop_as_client_create_user'] ) ) ) : ''; |
| 363 |
if ( 'yes' === $billing_shop_as_client_create_user ) { |
| 364 |
$billing_first_name = isset( $_POST['billing_first_name'] ) ? trim( sanitize_text_field( wp_unslash( $_POST['billing_first_name'] ) ) ) : ''; |
| 365 |
$billing_last_name = isset( $_POST['billing_last_name'] ) ? trim( sanitize_text_field( wp_unslash( $_POST['billing_last_name'] ) ) ) : ''; |
| 366 |
$temp_user_id = shop_as_client_create_customer( $user_email, $billing_first_name, $billing_last_name ); |
| 367 |
if ( ! is_wp_error( $temp_user_id ) ) { |
| 368 |
$user_id = $temp_user_id; |
| 369 |
} else { |
| 370 |
$message = sprintf( |
| 371 |
/* translators: %s: error message */ |
| 372 |
__( 'Shop as Client failed to create user: %s', 'shop-as-client' ), |
| 373 |
$temp_user_id->get_error_message() |
| 374 |
); |
| 375 |
throw new Exception( esc_html( $message ) ); |
| 376 |
} |
| 377 |
} |
| 378 |
} |
| 379 |
} |
| 380 |
} |
| 381 |
return $user_id; |
| 382 |
// phpcs:enable WordPress.Security.NonceVerification.Missing |
| 383 |
} |
| 384 |
add_filter( 'woocommerce_checkout_customer_id', 'shop_as_client_woocommerce_checkout_customer_id' ); |
| 385 |
|
| 386 |
/** |
| 387 |
* Create the user/customer - Should be used for both classic and blocks checkout |
| 388 |
* |
| 389 |
* @param string $user_email The user email. |
| 390 |
* @param string $user_first_name The user first name. |
| 391 |
* @param string $user_last_name The user last name. |
| 392 |
*/ |
| 393 |
function shop_as_client_create_customer( $user_email, $user_first_name, $user_last_name ) { |
| 394 |
// Username |
| 395 |
if ( 'yes' === get_option( 'woocommerce_registration_generate_username' ) ) { |
| 396 |
$username = ''; |
| 397 |
} else { |
| 398 |
$username = $user_email; |
| 399 |
} |
| 400 |
// Force password generation by WooCommerce (and sending via email), even if the option is not set |
| 401 |
if ( apply_filters( 'shop_as_client_email_password', true ) ) { |
| 402 |
add_filter( 'option_woocommerce_registration_generate_password', 'shop_as_client_woocommerce_registration_generate_password' ); |
| 403 |
$password = ''; |
| 404 |
} else { |
| 405 |
$password = wp_generate_password(); |
| 406 |
} |
| 407 |
$user_id = wc_create_new_customer( $user_email, $username, $password ); |
| 408 |
if ( apply_filters( 'shop_as_client_email_password', true ) ) { |
| 409 |
remove_filter( 'option_woocommerce_registration_generate_password', 'shop_as_client_woocommerce_registration_generate_password' ); |
| 410 |
} |
| 411 |
if ( ! is_wp_error( $user_id ) ) { |
| 412 |
wp_update_user( |
| 413 |
array( |
| 414 |
'ID' => $user_id, |
| 415 |
'first_name' => $user_first_name, |
| 416 |
'last_name' => $user_last_name, |
| 417 |
'display_name' => trim( $user_first_name . ' ' . $user_last_name ), |
| 418 |
// phpcs:ignore Squiz.PHP.CommentedOutCode.Found |
| 419 |
// 'role' => 'customer', |
| 420 |
) |
| 421 |
); |
| 422 |
} else { |
| 423 |
$message = 'Shop as Client failed to create user: ' . $user_id->get_error_message(); |
| 424 |
// We should notify the admin user somehow - WooCommerce already does that |
| 425 |
} |
| 426 |
return $user_id; |
| 427 |
} |
| 428 |
|
| 429 |
/** |
| 430 |
* Prevent logged in user to be updated |
| 431 |
* Not running on the blocks checkout but it seems not to be necessary as only the target user is being updated and not the logged-in one |
| 432 |
*/ |
| 433 |
function shop_as_client_woocommerce_checkout_process() { |
| 434 |
if ( shop_as_client_can_checkout() ) { |
| 435 |
// WooCommerce took care of nonces |
| 436 |
// phpcs:ignore WordPress.Security.NonceVerification.Missing |
| 437 |
$billing_shop_as_client = isset( $_POST['billing_shop_as_client'] ) ? trim( sanitize_text_field( wp_unslash( $_POST['billing_shop_as_client'] ) ) ) : ''; |
| 438 |
if ( 'yes' === $billing_shop_as_client ) { |
| 439 |
if ( ! apply_filters( 'shop_as_client_update_customer_data', false ) ) { |
| 440 |
add_filter( 'woocommerce_checkout_update_customer_data', '__return_false' ); |
| 441 |
} |
| 442 |
} |
| 443 |
} |
| 444 |
} |
| 445 |
add_action( 'woocommerce_checkout_process', 'shop_as_client_woocommerce_checkout_process' ); |
| 446 |
|
| 447 |
/** |
| 448 |
* Save logged in user id as order handler - Classic checkout only - Blocks alternative missing |
| 449 |
* |
| 450 |
* @param integer $order_id The order ID. |
| 451 |
* @param array $data The checkout data. |
| 452 |
*/ |
| 453 |
function shop_as_client_woocommerce_checkout_update_order_meta( $order_id, $data ) { |
| 454 |
// The "correct" way to check for our fields |
| 455 |
$billing_shop_as_client = isset( $data['billing_shop_as_client'] ) ? trim( $data['billing_shop_as_client'] ) : ''; |
| 456 |
if ( empty( $billing_shop_as_client ) ) { |
| 457 |
// Because when using Funnelkit our fields are not present on the $data array |
| 458 |
// WooCommerce took care of nonces |
| 459 |
// phpcs:ignore WordPress.Security.NonceVerification.Missing |
| 460 |
$billing_shop_as_client = isset( $_POST['billing_shop_as_client'] ) ? trim( sanitize_text_field( wp_unslash( $_POST['billing_shop_as_client'] ) ) ) : ''; |
| 461 |
} |
| 462 |
if ( shop_as_client_can_checkout() && 'yes' === $billing_shop_as_client ) { |
| 463 |
$order = wc_get_order( $order_id ); |
| 464 |
$order->update_meta_data( '_billing_shop_as_client_handler_user_id', get_current_user_id() ); |
| 465 |
$order->update_meta_data( '_billing_shop_as_client_checkout', 'classic' ); |
| 466 |
$order->save(); |
| 467 |
} |
| 468 |
} |
| 469 |
add_action( 'woocommerce_checkout_update_order_meta', 'shop_as_client_woocommerce_checkout_update_order_meta', 10, 2 ); |
| 470 |
|
| 471 |
/** |
| 472 |
* Information on the order edit screen |
| 473 |
* |
| 474 |
* @param WC_Order $order The order. |
| 475 |
*/ |
| 476 |
function shop_as_client_woocommerce_admin_order_data_after_order_details( $order ) { |
| 477 |
if ( shop_as_client_get_order_status( $order ) ) { |
| 478 |
?> |
| 479 |
<p class="form-field form-field-wide"> |
| 480 |
<label><?php esc_html_e( 'Shop as client', 'shop-as-client' ); ?>:</label> |
| 481 |
<?php esc_html_e( 'Yes', 'shop-as-client' ); ?> |
| 482 |
</p> |
| 483 |
<?php |
| 484 |
$user_id = $order->get_meta( '_billing_shop_as_client_handler_user_id' ); |
| 485 |
if ( $user_id ) { |
| 486 |
?> |
| 487 |
<p class="form-field form-field-wide"> |
| 488 |
<label><?php esc_html_e( 'Order handled by', 'shop-as-client' ); ?>:</label> |
| 489 |
<?php |
| 490 |
$user = get_user_by( 'ID', $user_id ); |
| 491 |
if ( $user ) { |
| 492 |
echo wp_kses_post( |
| 493 |
sprintf( |
| 494 |
'<a href="%s" target="_blank">%s</a>', |
| 495 |
esc_url( add_query_arg( 'user_id', $user_id, admin_url( 'user-edit.php' ) ) ), |
| 496 |
sprintf( |
| 497 |
'%s (%s)', |
| 498 |
$user->display_name, |
| 499 |
$user->nickname |
| 500 |
) |
| 501 |
) |
| 502 |
); |
| 503 |
} else { |
| 504 |
echo esc_html( |
| 505 |
sprintf( |
| 506 |
/* translators: $d: user id */ |
| 507 |
__( 'User %d', 'shop-as-client' ), |
| 508 |
$user_id |
| 509 |
) |
| 510 |
); |
| 511 |
} |
| 512 |
do_action( 'shop_as_client_after_order_handler', $order, $user_id ); |
| 513 |
?> |
| 514 |
</p> |
| 515 |
<?php |
| 516 |
} |
| 517 |
$checkout = $order->get_meta( '_billing_shop_as_client_checkout' ); |
| 518 |
if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { |
| 519 |
?> |
| 520 |
<p class="form-field form-field-wide"> |
| 521 |
<label><?php esc_html_e( 'Checkout', 'shop-as-client' ); ?>:</label> |
| 522 |
<?php echo esc_html( $checkout ); ?> |
| 523 |
</p> |
| 524 |
<?php |
| 525 |
} |
| 526 |
do_action( 'shop_as_client_after_order_details', $order ); |
| 527 |
} |
| 528 |
} |
| 529 |
add_action( 'woocommerce_admin_order_data_after_order_details', 'shop_as_client_woocommerce_admin_order_data_after_order_details' ); |
| 530 |
|
| 531 |
/** |
| 532 |
* Thank you page warning - https://github.com/woocommerce/woocommerce/pull/38983/ |
| 533 |
* Still not working on the blocks checkout |
| 534 |
* |
| 535 |
* @param string $tag The shortcode tag. |
| 536 |
*/ |
| 537 |
function shop_as_client_is_our_checkout_order_received( $tag ) { |
| 538 |
if ( $tag === apply_filters( 'woocommerce_checkout_shortcode_tag', 'woocommerce_checkout' ) && is_order_received_page() && shop_as_client_can_checkout() ) { |
| 539 |
global $wp; |
| 540 |
if ( isset( $wp->query_vars['order-received'] ) && intval( $wp->query_vars['order-received'] ) > 0 ) { |
| 541 |
$order = wc_get_order( $wp->query_vars['order-received'] ); |
| 542 |
if ( $order ) { |
| 543 |
$key = isset( $_GET['key'] ) ? sanitize_text_field( wp_unslash( $_GET['key'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 544 |
if ( hash_equals( $order->get_order_key(), $key ) ) { |
| 545 |
$order_customer_id = $order->get_customer_id(); |
| 546 |
if ( $order_customer_id && get_current_user_id() !== $order_customer_id ) { |
| 547 |
// We're pretty sure there's no access right now, so we need also to make sure it's a shop as client order and the handler is logged in |
| 548 |
if ( $order->get_meta( '_billing_shop_as_client' ) === 'yes' && intval( $order->get_meta( '_billing_shop_as_client_handler_user_id' ) ) === intval( get_current_user_id() ) ) { |
| 549 |
// We dealt with the order |
| 550 |
return $order; |
| 551 |
} |
| 552 |
} |
| 553 |
} |
| 554 |
} |
| 555 |
} |
| 556 |
} |
| 557 |
return false; |
| 558 |
} |
| 559 |
if ( version_compare( WC_VERSION, '7.8.1', '>=' ) ) { |
| 560 |
add_filter( 'do_shortcode_tag', 'shop_as_client_checkout_order_received', 10, 2 ); |
| 561 |
} |
| 562 |
|
| 563 |
/** |
| 564 |
* Undocumented function |
| 565 |
* |
| 566 |
* @param string $output Orginal HTML. |
| 567 |
* @param string $tag Shortcode tag. |
| 568 |
*/ |
| 569 |
function shop_as_client_checkout_order_received( $output, $tag ) { |
| 570 |
$order = shop_as_client_is_our_checkout_order_received( $tag ); |
| 571 |
if ( $order ) { |
| 572 |
ob_start(); |
| 573 |
?> |
| 574 |
<div class="woocommerce-error"> |
| 575 |
<a href="<?php echo esc_url( SHOPASCLIENT_PRO_OUT_LINK ); ?>" class="button wc-forward" target="_blank"> |
| 576 |
<?php esc_html_e( 'Get the PRO add-on to fix this', 'shop-as-client' ); ?> |
| 577 |
</a> |
| 578 |
<?php echo wp_kses_post( __( '<strong>Shop as client</strong><br/>Since WooCommerce 7.8.1 only the order owner/customer is able to see the "Order received" details.', 'shop-as-client' ) ); ?> |
| 579 |
</div> |
| 580 |
<?php |
| 581 |
$output = ob_get_clean() . $output; |
| 582 |
} |
| 583 |
return $output; |
| 584 |
} |
| 585 |
|
| 586 |
/** |
| 587 |
* Fix PRO updates to 2.3 - https://nakedcatplugins.com/shop-as-client-pro-add-on-not-working-after-updating-the-free-version-to-1-9-or-above-the-solution-is-here/ |
| 588 |
*/ |
| 589 |
add_action( |
| 590 |
'plugins_loaded', |
| 591 |
function () { |
| 592 |
if ( is_admin() && class_exists( 'Shop_As_Client_Pro' ) ) { |
| 593 |
if ( isset( $GLOBALS['Shop_As_Client_Pro'] ) ) { |
| 594 |
if ( version_compare( $GLOBALS['Shop_As_Client_Pro']->version, '2.3', '<' ) ) { |
| 595 |
$GLOBALS['Shop_As_Client_Pro']->update_checker(); |
| 596 |
} |
| 597 |
} |
| 598 |
} |
| 599 |
}, |
| 600 |
15 |
| 601 |
); |
| 602 |
|
| 603 |
if ( function_exists( 'woocommerce_store_api_register_update_callback' ) ) { |
| 604 |
|
| 605 |
/* Blocks */ |
| 606 |
add_action( |
| 607 |
'woocommerce_blocks_loaded', |
| 608 |
function () { |
| 609 |
require_once __DIR__ . '/includes/class-shop-as-client-checkout-blocks.php'; |
| 610 |
|
| 611 |
add_action( |
| 612 |
'woocommerce_blocks_checkout_block_registration', |
| 613 |
function ( $integration_registry ) { |
| 614 |
$integration_registry->register( new \ShopAsClient_Checkout_Blocks() ); |
| 615 |
} |
| 616 |
); |
| 617 |
} |
| 618 |
); |
| 619 |
|
| 620 |
/* Blocks - Extend Store endpoint */ |
| 621 |
add_action( |
| 622 |
'woocommerce_blocks_loaded', |
| 623 |
function () { |
| 624 |
require_once __DIR__ . '/includes/class-shop-as-client-extend-store-endpoint.php'; |
| 625 |
|
| 626 |
( new ShopAsClient_Extend_Store_Endpoint() )->initialize(); |
| 627 |
} |
| 628 |
); |
| 629 |
|
| 630 |
} |
| 631 |
|
| 632 |
/* Simple Order Approval nag */ |
| 633 |
add_action( |
| 634 |
'admin_init', |
| 635 |
function () { |
| 636 |
if ( |
| 637 |
( ! class_exists( 'Shop_As_Client_Pro' ) ) // Not for PRO add-on users |
| 638 |
&& |
| 639 |
( ! defined( 'PTWOO_SIMPLE_ORDER_APPROVAL_NAG' ) ) |
| 640 |
&& |
| 641 |
( ! class_exists( '\PTWooPlugins\SWOA\SWOA' ) ) |
| 642 |
&& |
| 643 |
empty( get_transient( 'ptwoo_simple_order_approval_nag' ) ) |
| 644 |
&& |
| 645 |
apply_filters( 'shop_as_client_ptwoo_simple_order_approval_nag', true ) |
| 646 |
) { |
| 647 |
define( 'PTWOO_SIMPLE_ORDER_APPROVAL_NAG', true ); |
| 648 |
require_once 'simple_order_approval_nag/simple_order_approval_nag.php'; |
| 649 |
} |
| 650 |
} |
| 651 |
); |
| 652 |
} |
| 653 |
}, |
| 654 |
6 |
| 655 |
); |
| 656 |
|
| 657 |
/* HPOS & Blocks Checkout Compatible */ |
| 658 |
add_action( |
| 659 |
'before_woocommerce_init', |
| 660 |
function () { |
| 661 |
\Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'custom_order_tables', __FILE__, true ); |
| 662 |
\Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'cart_checkout_blocks', __FILE__, true ); |
| 663 |
} |
| 664 |
); |
| 665 |
|
| 666 |
/* If you're reading this you must know what you're doing ;-) Greetings from sunny Portugal! */ |
| 667 |
|