plugin updates

This commit is contained in:
Tony Volpe
2024-02-21 16:19:46 +00:00
parent c72f206574
commit 21d4c85c00
1214 changed files with 102269 additions and 179257 deletions

View File

@@ -556,6 +556,25 @@ if ( ! class_exists( 'WC_Admin_Assets', false ) ) :
}
}
/**
* Enqueue a script in the block editor.
* Similar to `WCAdminAssets::register_script()` but without enqueuing unnecessary dependencies.
*
* @return void
*/
private function enqueue_block_editor_script( $script_path_name, $script_name ) {
$script_assets_filename = WCAdminAssets::get_script_asset_filename( $script_path_name, $script_name );
$script_assets = require WC_ADMIN_ABSPATH . WC_ADMIN_DIST_JS_FOLDER . $script_path_name . '/' . $script_assets_filename;
wp_enqueue_script(
'wc-admin-' . $script_name,
WCAdminAssets::get_url( $script_path_name . '/' . $script_name, 'js' ),
$script_assets['dependencies'],
WCAdminAssets::get_file_version( 'js' ),
true
);
}
/**
* Enqueue block editor assets.
*
@@ -578,7 +597,7 @@ if ( ! class_exists( 'WC_Admin_Assets', false ) ) :
}
}
WCAdminAssets::register_script( 'wp-admin-scripts', 'command-palette' );
self::enqueue_block_editor_script( 'wp-admin-scripts', 'command-palette' );
wp_localize_script(
'wc-admin-command-palette',
'wcCommandPaletteSettings',
@@ -611,7 +630,7 @@ if ( ! class_exists( 'WC_Admin_Assets', false ) ) :
}, $analytics_reports );
$formatted_analytics_reports = array_filter( $formatted_analytics_reports, 'is_array' );
WCAdminAssets::register_script( 'wp-admin-scripts', 'command-palette-analytics' );
self::enqueue_block_editor_script( 'wp-admin-scripts', 'command-palette-analytics' );
wp_localize_script(
'wc-admin-command-palette-analytics',
'wcCommandPaletteAnalytics',

View File

@@ -43,40 +43,19 @@ class WC_Admin_Log_Table_List extends WP_List_Table {
* @global wpdb $wpdb
*/
public function level_dropdown() {
$labels = WC_Log_Levels::get_all_level_labels();
$levels = array(
array(
'value' => WC_Log_Levels::EMERGENCY,
'label' => __( 'Emergency', 'woocommerce' ),
),
array(
'value' => WC_Log_Levels::ALERT,
'label' => __( 'Alert', 'woocommerce' ),
),
array(
'value' => WC_Log_Levels::CRITICAL,
'label' => __( 'Critical', 'woocommerce' ),
),
array(
'value' => WC_Log_Levels::ERROR,
'label' => __( 'Error', 'woocommerce' ),
),
array(
'value' => WC_Log_Levels::WARNING,
'label' => __( 'Warning', 'woocommerce' ),
),
array(
'value' => WC_Log_Levels::NOTICE,
'label' => __( 'Notice', 'woocommerce' ),
),
array(
'value' => WC_Log_Levels::INFO,
'label' => __( 'Info', 'woocommerce' ),
),
array(
'value' => WC_Log_Levels::DEBUG,
'label' => __( 'Debug', 'woocommerce' ),
),
$levels = array_reduce(
array_keys( $labels ),
function( $carry, $item ) use ( $labels ) {
$carry[] = array(
'value' => $item,
'label' => $labels[ $item ],
);
return $carry;
},
array()
);
$selected_level = isset( $_REQUEST['level'] ) ? $_REQUEST['level'] : '';
@@ -181,16 +160,7 @@ class WC_Admin_Log_Table_List extends WP_List_Table {
*/
public function column_level( $log ) {
$level_key = WC_Log_Levels::get_severity_level( $log['level'] );
$levels = array(
'emergency' => __( 'Emergency', 'woocommerce' ),
'alert' => __( 'Alert', 'woocommerce' ),
'critical' => __( 'Critical', 'woocommerce' ),
'error' => __( 'Error', 'woocommerce' ),
'warning' => __( 'Warning', 'woocommerce' ),
'notice' => __( 'Notice', 'woocommerce' ),
'info' => __( 'Info', 'woocommerce' ),
'debug' => __( 'Debug', 'woocommerce' ),
);
$levels = WC_Log_Levels::get_all_level_labels();
if ( ! isset( $levels[ $level_key ] ) ) {
return '';

View File

@@ -147,8 +147,9 @@ class WC_Admin_Notices {
),
sprintf(
// translators: Placeholders are URLs.
wpautop( wp_kses_data( __( 'The WooCommerce Legacy REST API, <a href="%1$s">currently enabled in this site</a>, will be removed in WooCommerce 9.0. A separate WooCommerce extension will be available to keep it enabled. <b><a target="_blank" href="%2$s">Learn more about this change.</a></b>', 'woocommerce' ) ) ),
wpautop( __( 'The WooCommerce Legacy REST API, <a href="%1$s">currently enabled in this site</a>, will be removed in WooCommerce 9.0. <a target="_blank" href="%2$s">A separate WooCommerce extension is available</a> to keep it enabled. <b><a target="_blank" href="%3$s">Learn more about this change.</a></b>', 'woocommerce' ) ),
admin_url( 'admin.php?page=wc-settings&tab=advanced&section=legacy_api' ),
'https://wordpress.org/plugins/woocommerce-legacy-rest-api/',
'https://developer.woo.com/2023/10/03/the-legacy-rest-api-will-move-to-a-dedicated-extension-in-woocommerce-9-0/'
)
)
@@ -166,8 +167,9 @@ class WC_Admin_Notices {
),
sprintf(
// translators: Placeholders are URLs.
wpautop( wp_kses_data( __( 'The WooCommerce Legacy REST API will be removed in WooCommerce 9.0, and this will cause <a href="%1$s">webhooks on this site that are configured to use the Legacy REST API</a> to stop working. A separate WooCommerce extension will be available to allow these webhooks to keep using the Legacy REST API without interruption. You can also edit these webhooks to use the current REST API version to generate the payload instead. <b><a target="_blank" href="%2$s">Learn more about this change.</a></b>', 'woocommerce' ) ) ),
wpautop( __( 'The WooCommerce Legacy REST API will be removed in WooCommerce 9.0, and this will cause <a href="%1$s">webhooks on this site that are configured to use the Legacy REST API</a> to stop working. <a target="_blank" href="%2$s">A separate WooCommerce extension is available</a> to allow these webhooks to keep using the Legacy REST API without interruption. You can also edit these webhooks to use the current REST API version to generate the payload instead. <b><a target="_blank" href="%3$s">Learn more about this change.</a></b>', 'woocommerce' ) ),
admin_url( 'admin.php?page=wc-settings&tab=advanced&section=webhooks&legacy=true' ),
'https://wordpress.org/plugins/woocommerce-legacy-rest-api/',
'https://developer.woo.com/2023/10/03/the-legacy-rest-api-will-move-to-a-dedicated-extension-in-woocommerce-9-0/'
)
)

View File

@@ -287,8 +287,9 @@ if ( ! class_exists( 'WC_Admin_Settings', false ) ) :
break;
case 'info':
?><tr valign="top"<?php echo $value['row_class'] ? ' class="' . esc_attr( $value['row_class'] ) . '"' : '' ?>">
<th scope="row" class="titledesc"/><td style="<?php echo esc_attr( $value['css'] ); ?>">
?><tr class="<?php echo esc_attr( $value['row_class'] ); ?>">
<th scope="row" class="titledesc"><?php echo esc_html( $value['title'] ); ?></th>
<td style="<?php echo esc_attr( $value['css'] ); ?>">
<?php
echo wp_kses_post( wpautop( wptexturize( $value['text'] ) ) );
echo '</td></tr>';
@@ -320,7 +321,8 @@ if ( ! class_exists( 'WC_Admin_Settings', false ) ) :
case 'tel':
$option_value = $value['value'];
?><tr valign="top"<?php echo $value['row_class'] ? ' class="' . esc_attr( $value['row_class'] ) . '"' : '' ?>">
?>
<tr class="<?php echo esc_attr( $value['row_class'] ); ?>">
<th scope="row" class="titledesc">
<label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo esc_html( $value['title'] ); ?> <?php echo $tooltip_html; // WPCS: XSS ok. ?></label>
</th>
@@ -345,7 +347,7 @@ if ( ! class_exists( 'WC_Admin_Settings', false ) ) :
$option_value = $value['value'];
?>
<tr valign="top"<?php echo $value['row_class'] ? ' class="' . esc_attr( $value['row_class'] ) . '"' : '' ?>">
<tr class="<?php echo esc_attr( $value['row_class'] ); ?>">
<th scope="row" class="titledesc">
<label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo esc_html( $value['title'] ); ?> <?php echo $tooltip_html; // WPCS: XSS ok. ?></label>
</th>
@@ -373,7 +375,7 @@ if ( ! class_exists( 'WC_Admin_Settings', false ) ) :
$option_value = $value['value'];
?>
<tr valign="top"<?php echo $value['row_class'] ? ' class="' . esc_attr( $value['row_class'] ) . '"' : '' ?>">
<tr class="<?php echo esc_attr( $value['row_class'] ); ?>">
<th scope="row" class="titledesc">
<label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo esc_html( $value['title'] ); ?> <?php echo $tooltip_html; // WPCS: XSS ok. ?></label>
</th>
@@ -399,7 +401,7 @@ if ( ! class_exists( 'WC_Admin_Settings', false ) ) :
$option_value = $value['value'];
?>
<tr valign="top"<?php echo $value['row_class'] ? ' class="' . esc_attr( $value['row_class'] ) . '"' : '' ?>">
<tr class="<?php echo esc_attr( $value['row_class'] ); ?>">
<th scope="row" class="titledesc">
<label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo esc_html( $value['title'] ); ?> <?php echo $tooltip_html; // WPCS: XSS ok. ?></label>
</th>
@@ -442,7 +444,7 @@ if ( ! class_exists( 'WC_Admin_Settings', false ) ) :
$show_desc_at_end = $value['desc_at_end'] ?? false;
?>
<tr valign="top"<?php echo $value['row_class'] ? ' class="' . esc_attr( $value['row_class'] ) . '"' : '' ?>">
<tr class="<?php echo esc_attr( $value['row_class'] ); ?>">
<th scope="row" class="titledesc">
<label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo esc_html( $value['title'] ); ?> <?php echo $tooltip_html; // WPCS: XSS ok. ?></label>
</th>
@@ -509,13 +511,14 @@ if ( ! class_exists( 'WC_Admin_Settings', false ) ) :
$visibility_class[] = $value['row_class'];
}
$must_disable = $value['disabled'] ?? false;
$container_class = implode( ' ', $visibility_class );
$must_disable = $value['disabled'] ?? false;
if ( ! isset( $value['checkboxgroup'] ) || 'start' === $value['checkboxgroup'] ) {
$has_tooltip = isset( $value['tooltip'] ) && '' !== $value['tooltip'];
$tooltip_container_class = $has_tooltip ? 'with-tooltip' : '';
?>
<tr valign="top" class="<?php echo esc_attr( implode( ' ', $visibility_class ) ); ?>">
<tr class="<?php echo esc_attr( $container_class ); ?>">
<th scope="row" class="titledesc"><?php echo esc_html( $value['title'] ); ?></th>
<td class="forminp forminp-checkbox <?php echo esc_html( $tooltip_container_class ); ?>">
<?php if ( $has_tooltip ) : ?>
@@ -525,7 +528,7 @@ if ( ! class_exists( 'WC_Admin_Settings', false ) ) :
<?php
} else {
?>
<fieldset class="<?php echo esc_attr( implode( ' ', $visibility_class ) ); ?>">
<fieldset class="<?php echo esc_attr( $container_class ); ?>">
<?php
}
@@ -580,7 +583,7 @@ if ( ! class_exists( 'WC_Admin_Settings', false ) ) :
}
?>
<tr valign="top"<?php echo $value['row_class'] ? ' class="' . esc_attr( $value['row_class'] ) . '"' : '' ?>">
<tr class="<?php echo esc_attr( $value['row_class'] ); ?>">
<th scope="row" class="titledesc">
<label><?php echo esc_html( $value['title'] ); ?> <?php echo $tooltip_html . $disabled_message; // WPCS: XSS ok. ?></label>
</th>
@@ -614,7 +617,7 @@ if ( ! class_exists( 'WC_Admin_Settings', false ) ) :
}
?>
<tr valign="top" class="single_select_page"<?php echo $value['row_class'] ? ' class="' . esc_attr( $value['row_class'] ) . '"' : '' ?>">
<tr class="single_select_page <?php echo esc_attr( $value['row_class'] ); ?>">
<th scope="row" class="titledesc">
<label><?php echo esc_html( $value['title'] ); ?> <?php echo $tooltip_html; // WPCS: XSS ok. ?></label>
</th>
@@ -639,7 +642,7 @@ if ( ! class_exists( 'WC_Admin_Settings', false ) ) :
);
}
?>
<tr valign="top" class="single_select_page"<?php echo $value['row_class'] ? ' class="' . esc_attr( $value['row_class'] ) . '"' : '' ?>">
<tr class="single_select_page <?php echo esc_attr( $value['row_class'] ); ?>">
<th scope="row" class="titledesc">
<label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo esc_html( $value['title'] ); ?> <?php echo $tooltip_html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></label>
</th>
@@ -679,7 +682,7 @@ if ( ! class_exists( 'WC_Admin_Settings', false ) ) :
$state = '*';
}
?>
<tr valign="top"<?php echo $value['row_class'] ? ' class="' . esc_attr( $value['row_class'] ) . '"' : '' ?>">
<tr class="<?php echo esc_attr( $value['row_class'] ); ?>">
<th scope="row" class="titledesc">
<label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo esc_html( $value['title'] ); ?> <?php echo $tooltip_html; // WPCS: XSS ok. ?></label>
</th>
@@ -703,7 +706,7 @@ if ( ! class_exists( 'WC_Admin_Settings', false ) ) :
asort( $countries );
?>
<tr valign="top"<?php echo $value['row_class'] ? ' class="' . esc_attr( $value['row_class'] ) . '"' : '' ?>">
<tr class="<?php echo esc_attr( $value['row_class'] ); ?>">
<th scope="row" class="titledesc">
<label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo esc_html( $value['title'] ); ?> <?php echo $tooltip_html; // WPCS: XSS ok. ?></label>
</th>
@@ -732,7 +735,7 @@ if ( ! class_exists( 'WC_Admin_Settings', false ) ) :
);
$option_value = wc_parse_relative_date_option( $value['value'] );
?>
<tr valign="top"<?php echo $value['row_class'] ? ' class="' . esc_attr( $value['row_class'] ) . '"' : '' ?>">
<tr class="<?php echo esc_attr( $value['row_class'] ); ?>">
<th scope="row" class="titledesc">
<label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo esc_html( $value['title'] ); ?> <?php echo $tooltip_html; // WPCS: XSS ok. ?></label>
</th>

View File

@@ -39,13 +39,23 @@ class WC_Helper_Admin {
$auth_user_data = WC_Helper_Options::get( 'auth_user_data', array() );
$auth_user_email = isset( $auth_user_data['email'] ) ? $auth_user_data['email'] : '';
// Get the all installed themes and plugins. Knowing this will help us decide to show Add to Store button on product cards.
$installed_products = array_merge( WC_Helper::get_local_plugins(), WC_Helper::get_local_themes() );
$installed_products = array_map(
function ( $product ) {
return $product['slug'];
},
$installed_products
);
$settings['wccomHelper'] = array(
'isConnected' => WC_Helper::is_site_connected(),
'connectURL' => self::get_connection_url(),
'userEmail' => $auth_user_email,
'userAvatar' => get_avatar_url( $auth_user_email, array( 'size' => '48' ) ),
'storeCountry' => wc_get_base_location()['country'],
'isConnected' => WC_Helper::is_site_connected(),
'connectURL' => self::get_connection_url(),
'userEmail' => $auth_user_email,
'userAvatar' => get_avatar_url( $auth_user_email, array( 'size' => '48' ) ),
'storeCountry' => wc_get_base_location()['country'],
'inAppPurchaseURLParams' => WC_Admin_Addons::get_in_app_purchase_url_params(),
'installedProducts' => $installed_products,
);
return $settings;
@@ -74,10 +84,6 @@ class WC_Helper_Admin {
$connect_url_args['wc-helper-nonce'] = wp_create_nonce( 'connect' );
}
if ( isset( $current_screen->id ) && 'woocommerce_page_wc-admin' === $current_screen->id ) {
$connect_url_args['redirect-to-wc-admin'] = 1;
}
return add_query_arg(
$connect_url_args,
admin_url( 'admin.php' )

View File

@@ -0,0 +1,107 @@
<?php
/**
* WooCommerce Admin Helper - React admin interface
*
* @package WooCommerce\Admin\Helper
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* WC_Helper_Orders_API
*
* Pings Woo.com to create an order and pull in the necessary data to start the installation process.
*/
class WC_Helper_Orders_API {
/**
* Loads the class, runs on init
*
* @return void
*/
public static function load() {
add_filter( 'rest_api_init', array( __CLASS__, 'register_rest_routes' ) );
}
/**
* Registers the REST routes for the Marketplace Orders API.
* These endpoints are used by the Marketplace Subscriptions React UI.
*/
public static function register_rest_routes() {
register_rest_route(
'wc/v3',
'/marketplace/create-order',
array(
'methods' => 'POST',
'callback' => array( __CLASS__, 'create_order' ),
'permission_callback' => array( __CLASS__, 'get_permission' ),
'args' => array(
'product_id' => array(
'required' => true,
'validate_callback' => function( $argument ) {
return is_int( $argument );
},
),
),
)
);
}
/**
* The Extensions page can only be accessed by users with the manage_woocommerce
* capability. So the API mimics that behavior.
*
* @return bool
*/
public static function get_permission() {
return WC_Helper_Subscriptions_API::get_permission();
}
/**
* Core function to create an order on Woo.com. Pings the API and catches the exceptions if any.
*
* @param WP_REST_Request $request Request object.
*
* @return WP_REST_Response
*/
public static function create_order( $request ) {
if ( ! current_user_can( 'install_plugins' ) ) {
return new \WP_REST_Response(
array(
'message' => __( 'You do not have permission to install plugins.', 'woocommerce' ),
),
403
);
}
try {
$response = WC_Helper_API::post(
'create-order',
array(
'authenticated' => true,
'body' => http_build_query(
array(
'product_id' => $request['product_id'],
),
),
)
);
return new \WP_REST_Response(
json_decode( wp_remote_retrieve_body( $response ), true ),
wp_remote_retrieve_response_code( $response )
);
} catch ( Exception $e ) {
return new \WP_REST_Response(
array(
'message' => __( 'Could not start the installation process. Reason: ', 'woocommerce' ) . $e->getMessage(),
'code' => 'could-not-install',
),
500
);
}
}
}
WC_Helper_Orders_API::load();

View File

@@ -61,6 +61,7 @@ class WC_Helper {
include_once dirname( __FILE__ ) . '/class-wc-helper-compat.php';
include_once dirname( __FILE__ ) . '/class-wc-helper-admin.php';
include_once dirname( __FILE__ ) . '/class-wc-helper-subscriptions-api.php';
include_once dirname( __FILE__ ) . '/class-wc-helper-orders-api.php';
}
/**
@@ -699,40 +700,53 @@ class WC_Helper {
array(
'page' => 'wc-addons',
'section' => 'helper',
),
isset( $_GET['redirect-to-wc-admin'] ),
sanitize_text_field( wp_unslash( $_GET['install'] ) )
)
)
);
// phpcs:enable WordPress.Security.NonceVerification.Recommended
}
/**
* Get helper redirect URL.
*
* @param array $args Query args.
* @param bool $redirect_to_wc_admin Whether to redirect to WC Admin.
* @param string $install_product_key Optional Product key to install.
* @param array $args Query args.
* @return string
*/
private static function get_helper_redirect_url( $args = array(), $redirect_to_wc_admin = false, $install_product_key = '' ) {
private static function get_helper_redirect_url( $args = array() ) {
global $current_screen;
// phpcs:disable WordPress.Security.NonceVerification.Recommended
$redirect_admin_url = isset( $_GET['redirect_admin_url'] )
? esc_url_raw(
urldecode(
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
wp_unslash( $_GET['redirect_admin_url'] )
)
)
: '';
$install_product_key = isset( $_GET['install'] ) ? sanitize_text_field( wp_unslash( $_GET['install'] ) ) : '';
// phpcs:enable WordPress.Security.NonceVerification.Recommended
if (
'woocommerce_page_wc-addons' === $current_screen->id &&
FeaturesUtil::feature_is_enabled( 'marketplace' ) &&
(
true === $redirect_to_wc_admin ||
false === empty( $redirect_admin_url ) ||
false === empty( $install_product_key )
)
) {
$new_url = add_query_arg(
array(
'page' => 'wc-admin',
'tab' => 'my-subscriptions',
'path' => rawurlencode( '/extensions' ),
),
admin_url( 'admin.php' )
);
if ( strpos( $redirect_admin_url, admin_url( 'admin.php' ) ) === 0 ) {
$new_url = $redirect_admin_url;
} else {
$new_url = add_query_arg(
array(
'page' => 'wc-admin',
'tab' => 'my-subscriptions',
'path' => rawurlencode( '/extensions' ),
),
admin_url( 'admin.php' )
);
}
if ( ! empty( $install_product_key ) ) {
$new_url = add_query_arg(
array(
@@ -766,10 +780,6 @@ class WC_Helper {
'wc-helper-nonce' => wp_create_nonce( 'connect' ),
);
if ( isset( $_GET['redirect-to-wc-admin'] ) ) {
$redirect_url_args['redirect-to-wc-admin'] = 1;
}
if ( isset( $_GET['install'] ) ) {
$redirect_url_args['install'] = sanitize_text_field( wp_unslash( $_GET['install'] ) );
}
@@ -809,9 +819,19 @@ class WC_Helper {
$connect_url = add_query_arg(
array(
'home_url' => rawurlencode( home_url() ),
'redirect_uri' => rawurlencode( $redirect_uri ),
'secret' => rawurlencode( $secret ),
'home_url' => rawurlencode( home_url() ),
'redirect_uri' => rawurlencode( $redirect_uri ),
'secret' => rawurlencode( $secret ),
'redirect_admin_url' => isset( $_GET['redirect_admin_url'] )
? rawurlencode(
esc_url_raw(
urldecode(
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
wp_unslash( $_GET['redirect_admin_url'] )
)
)
)
: '',
),
WC_Helper_API::url( 'oauth/authorize' )
);
@@ -841,9 +861,7 @@ class WC_Helper {
array(
'page' => 'wc-addons',
'section' => 'helper',
),
isset( $_GET['redirect-to-wc-admin'] ),
isset( $_GET['install'] ) ? sanitize_text_field( wp_unslash( $_GET['install'] ) ) : ''
)
)
);
die();
@@ -905,9 +923,7 @@ class WC_Helper {
'page' => 'wc-addons',
'section' => 'helper',
'wc-helper-status' => 'helper-connected',
),
isset( $_GET['redirect-to-wc-admin'] ),
isset( $_GET['install'] ) ? sanitize_text_field( wp_unslash( $_GET['install'] ) ) : ''
)
)
);
die();
@@ -932,9 +948,7 @@ class WC_Helper {
'page' => 'wc-addons',
'section' => 'helper',
'wc-helper-status' => 'helper-disconnected',
),
isset( $_GET['redirect-to-wc-admin'] ),
isset( $_GET['install'] ) ? sanitize_text_field( wp_unslash( $_GET['install'] ) ) : ''
)
);
self::disconnect();
@@ -960,9 +974,7 @@ class WC_Helper {
'section' => 'helper',
'filter' => self::get_current_filter(),
'wc-helper-status' => 'helper-refreshed',
),
isset( $_GET['redirect-to-wc-admin'] ),
isset( $_GET['install'] ) ? sanitize_text_field( wp_unslash( $_GET['install'] ) ) : ''
)
);
wp_safe_redirect( $redirect_uri );

View File

@@ -34,18 +34,23 @@ class WC_Meta_Box_Order_Data {
protected static $shipping_fields = array();
/**
* Init billing and shipping fields we display + save.
* Get billing fields for the meta box.
*
* @param \WC_Order $order Order object.
* @param string $context Context of fields (view or edit).
* @return array
*/
public static function init_address_fields() {
protected static function get_billing_fields( $order = false, $context = 'edit' ) {
/**
* Provides an opportunity to modify the list of order billing fields displayed on the admin.
*
* @since 1.4.0
*
* @param array Billing fields.
* @param WC_Order|false $order Order object.
* @param string $context Context of fields (view or edit).
*/
self::$billing_fields = apply_filters(
return apply_filters(
'woocommerce_admin_billing_fields',
array(
'first_name' => array(
@@ -94,17 +99,30 @@ class WC_Meta_Box_Order_Data {
'phone' => array(
'label' => __( 'Phone', 'woocommerce' ),
),
)
),
$order,
$context
);
}
/**
* Get shipping fields for the meta box.
*
* @param \WC_Order $order Order object.
* @param string $context Context of fields (view or edit).
* @return array
*/
protected static function get_shipping_fields( $order = false, $context = 'edit' ) {
/**
* Provides an opportunity to modify the list of order shipping fields displayed on the admin.
*
* @since 1.4.0
*
* @param array Shipping fields.
* @param WC_Order|false $order Order object.
* @param string $context Context of fields (view or edit).
*/
self::$shipping_fields = apply_filters(
return apply_filters(
'woocommerce_admin_shipping_fields',
array(
'first_name' => array(
@@ -150,10 +168,20 @@ class WC_Meta_Box_Order_Data {
'phone' => array(
'label' => __( 'Phone', 'woocommerce' ),
),
)
),
$order,
$context
);
}
/**
* Init billing and shipping fields we display + save. Maintained for backwards compat.
*/
public static function init_address_fields() {
self::$billing_fields = self::get_billing_fields();
self::$shipping_fields = self::get_shipping_fields();
}
/**
* Output the metabox.
*
@@ -166,8 +194,6 @@ class WC_Meta_Box_Order_Data {
$order = $theorder;
self::init_address_fields();
if ( WC()->payment_gateways() ) {
$payment_gateways = WC()->payment_gateways->payment_gateways();
} else {
@@ -373,7 +399,6 @@ class WC_Meta_Box_Order_Data {
</h3>
<div class="address">
<?php
// Display values.
if ( $order->get_formatted_billing_address() ) {
echo '<p>' . wp_kses( $order->get_formatted_billing_address(), array( 'br' => array() ) ) . '</p>';
@@ -381,7 +406,9 @@ class WC_Meta_Box_Order_Data {
echo '<p class="none_set"><strong>' . esc_html__( 'Address:', 'woocommerce' ) . '</strong> ' . esc_html__( 'No billing address set.', 'woocommerce' ) . '</p>';
}
foreach ( self::$billing_fields as $key => $field ) {
$billing_fields = self::get_billing_fields( $order, 'view' );
foreach ( $billing_fields as $key => $field ) {
if ( isset( $field['show'] ) && false === $field['show'] ) {
continue;
}
@@ -413,9 +440,10 @@ class WC_Meta_Box_Order_Data {
<div class="edit_address">
<?php
// Display form.
foreach ( self::$billing_fields as $key => $field ) {
$billing_fields = self::get_billing_fields( $order, 'edit' );
foreach ( $billing_fields as $key => $field ) {
if ( ! isset( $field['type'] ) ) {
$field['type'] = 'text';
}
@@ -437,6 +465,9 @@ class WC_Meta_Box_Order_Data {
case 'select':
woocommerce_wp_select( $field, $order );
break;
case 'checkbox':
woocommerce_wp_checkbox( $field, $order );
break;
default:
woocommerce_wp_text_input( $field, $order );
break;
@@ -493,7 +524,6 @@ class WC_Meta_Box_Order_Data {
</h3>
<div class="address">
<?php
// Display values.
if ( $order->get_formatted_shipping_address() ) {
echo '<p>' . wp_kses( $order->get_formatted_shipping_address(), array( 'br' => array() ) ) . '</p>';
@@ -501,15 +531,19 @@ class WC_Meta_Box_Order_Data {
echo '<p class="none_set"><strong>' . esc_html__( 'Address:', 'woocommerce' ) . '</strong> ' . esc_html__( 'No shipping address set.', 'woocommerce' ) . '</p>';
}
if ( ! empty( self::$shipping_fields ) ) {
foreach ( self::$shipping_fields as $key => $field ) {
$shipping_fields = self::get_shipping_fields( $order, 'view' );
if ( ! empty( $shipping_fields ) ) {
foreach ( $shipping_fields as $key => $field ) {
if ( isset( $field['show'] ) && false === $field['show'] ) {
continue;
}
$field_name = 'shipping_' . $key;
if ( is_callable( array( $order, 'get_' . $field_name ) ) ) {
if ( isset( $field['value'] ) ) {
$field_value = $field['value'];
} elseif ( is_callable( array( $order, 'get_' . $field_name ) ) ) {
$field_value = $order->{"get_$field_name"}( 'edit' );
} else {
$field_value = $order->get_meta( '_' . $field_name );
@@ -519,9 +553,11 @@ class WC_Meta_Box_Order_Data {
$field_value = wc_make_phone_clickable( $field_value );
}
if ( $field_value ) {
echo '<p><strong>' . esc_html( $field['label'] ) . ':</strong> ' . wp_kses_post( $field_value ) . '</p>';
if ( ! $field_value ) {
continue;
}
echo '<p><strong>' . esc_html( $field['label'] ) . ':</strong> ' . wp_kses_post( $field_value ) . '</p>';
}
}
@@ -532,10 +568,11 @@ class WC_Meta_Box_Order_Data {
</div>
<div class="edit_address">
<?php
// Display form.
if ( ! empty( self::$shipping_fields ) ) {
foreach ( self::$shipping_fields as $key => $field ) {
$shipping_fields = self::get_shipping_fields( $order, 'edit' );
if ( ! empty( $shipping_fields ) ) {
foreach ( $shipping_fields as $key => $field ) {
if ( ! isset( $field['type'] ) ) {
$field['type'] = 'text';
}
@@ -545,16 +582,21 @@ class WC_Meta_Box_Order_Data {
$field_name = 'shipping_' . $key;
if ( is_callable( array( $order, 'get_' . $field_name ) ) ) {
$field['value'] = $order->{"get_$field_name"}( 'edit' );
} else {
$field['value'] = $order->get_meta( '_' . $field_name );
if ( ! isset( $field['value'] ) ) {
if ( is_callable( array( $order, 'get_' . $field_name ) ) ) {
$field['value'] = $order->{"get_$field_name"}( 'edit' );
} else {
$field['value'] = $order->get_meta( '_' . $field_name );
}
}
switch ( $field['type'] ) {
case 'select':
woocommerce_wp_select( $field, $order );
break;
case 'checkbox':
woocommerce_wp_checkbox( $field, $order );
break;
default:
woocommerce_wp_text_input( $field, $order );
break;
@@ -604,8 +646,6 @@ class WC_Meta_Box_Order_Data {
throw new Exception( __( 'Payment method is missing.', 'woocommerce' ), 400 );
}
self::init_address_fields();
// Ensure gateways are loaded in case they need to insert data into the emails.
WC()->payment_gateways();
WC()->shipping();
@@ -626,8 +666,10 @@ class WC_Meta_Box_Order_Data {
}
// Update billing fields.
if ( ! empty( self::$billing_fields ) ) {
foreach ( self::$billing_fields as $key => $field ) {
$billing_fields = self::get_billing_fields( $order, 'edit' );
if ( ! empty( $billing_fields ) ) {
foreach ( $billing_fields as $key => $field ) {
if ( ! isset( $field['id'] ) ) {
$field['id'] = '_billing_' . $key;
}
@@ -636,17 +678,24 @@ class WC_Meta_Box_Order_Data {
continue;
}
if ( is_callable( array( $order, 'set_billing_' . $key ) ) ) {
$props[ 'billing_' . $key ] = wc_clean( wp_unslash( $_POST[ $field['id'] ] ) );
$value = wc_clean( wp_unslash( $_POST[ $field['id'] ] ) );
// Update a field if it includes an update callback.
if ( isset( $field['update_callback'] ) ) {
call_user_func( $field['update_callback'], $field['id'], $value, $order );
} elseif ( is_callable( array( $order, 'set_billing_' . $key ) ) ) {
$props[ 'billing_' . $key ] = $value;
} else {
$order->update_meta_data( $field['id'], wc_clean( wp_unslash( $_POST[ $field['id'] ] ) ) );
$order->update_meta_data( $field['id'], $value );
}
}
}
// Update shipping fields.
if ( ! empty( self::$shipping_fields ) ) {
foreach ( self::$shipping_fields as $key => $field ) {
$shipping_fields = self::get_shipping_fields( $order, 'edit' );
if ( ! empty( $shipping_fields ) ) {
foreach ( $shipping_fields as $key => $field ) {
if ( ! isset( $field['id'] ) ) {
$field['id'] = '_shipping_' . $key;
}
@@ -655,10 +704,15 @@ class WC_Meta_Box_Order_Data {
continue;
}
if ( is_callable( array( $order, 'set_shipping_' . $key ) ) ) {
$props[ 'shipping_' . $key ] = wc_clean( wp_unslash( $_POST[ $field['id'] ] ) );
$value = isset( $_POST[ $field['id'] ] ) ? wc_clean( wp_unslash( $_POST[ $field['id'] ] ) ) : '';
// Update a field if it includes an update callback.
if ( isset( $field['update_callback'] ) ) {
call_user_func( $field['update_callback'], $field['id'], $value, $order );
} elseif ( is_callable( array( $order, 'set_shipping_' . $key ) ) ) {
$props[ 'shipping_' . $key ] = $value;
} else {
$order->update_meta_data( $field['id'], wc_clean( wp_unslash( $_POST[ $field['id'] ] ) ) );
$order->update_meta_data( $field['id'], $value );
}
}
}

View File

@@ -361,7 +361,7 @@ class WC_Settings_Advanced extends WC_Settings_Page {
array(
'title' => __( 'Show Suggestions', 'woocommerce' ),
'desc' => __( 'Display suggestions within WooCommerce', 'woocommerce' ),
'desc_tip' => esc_html__( 'Leave this box unchecked if you do not want to see suggested extensions.', 'woocommerce' ),
'desc_tip' => esc_html__( 'Leave this box unchecked if you do not want to pull suggested extensions from Woo.com. You will see a static list of extensions instead.', 'woocommerce' ),
'id' => 'woocommerce_show_marketplace_suggestions',
'type' => 'checkbox',
'checkboxgroup' => 'start',
@@ -395,9 +395,10 @@ class WC_Settings_Advanced extends WC_Settings_Page {
$enable_legacy_api_setting['desc_tip'] = sprintf(
// translators: Placeholders are URLs.
__(
'⚠️ <b>The Legacy REST API will be removed in WooCommerce 9.0.</b> A separate WooCommerce extension will soon be available to keep it enabled. You can check Legacy REST API usages in <b><a target="_blank" href="%1$s">the WooCommerce log files</a></b> (file names start with <code>legacy_rest_api_usages</code>). <b><a target="_blank" href="%2$s">Learn more about this change.</a></b>',
'⚠️ <b>The Legacy REST API will be removed in WooCommerce 9.0.</b> <a target="_blank" href="%1$s">A separate WooCommerce extension is available</a> to keep it enabled. You can check Legacy REST API usages in <b><a target="_blank" href="%2$s">the WooCommerce log files</a></b> (file names start with <code>legacy_rest_api_usages</code>). <b><a target="_blank" href="%3$s">Learn more about this change.</a></b>',
'woocommerce'
),
'https://wordpress.org/plugins/woocommerce-legacy-rest-api/',
admin_url( 'admin.php?page=wc-status&tab=logs' ),
'https://developer.woo.com/2023/10/03/the-legacy-rest-api-will-move-to-a-dedicated-extension-in-woocommerce-9-0/'
);

View File

@@ -158,7 +158,14 @@ function woocommerce_wp_checkbox( $field, WC_Data $data = null ) {
$field['name'] = isset( $field['name'] ) ? $field['name'] : $field['id'];
$field['desc_tip'] = isset( $field['desc_tip'] ) ? $field['desc_tip'] : false;
// Custom attribute handling
/**
* These values are what get passed vis $_POST depending on if the field is checked or not. If no unchecked_value is
* provided, the $_POST will not be set. This maintains backwards compatibility where consumers would use `isset`.
*/
$field['checked_value'] = isset( $field['checked_value'] ) ? $field['checked_value'] : $field['cbvalue'];
$field['unchecked_value'] = isset( $field['unchecked_value'] ) ? $field['unchecked_value'] : null;
// Custom attribute handling.
$custom_attributes = array();
if ( ! empty( $field['custom_attributes'] ) && is_array( $field['custom_attributes'] ) ) {
@@ -168,6 +175,14 @@ function woocommerce_wp_checkbox( $field, WC_Data $data = null ) {
}
}
if ( ! empty( $field['style'] ) ) {
$custom_attributes[] = 'style="' . esc_attr( $field['style'] ) . '"';
}
if ( ! empty( $field['class'] ) ) {
$custom_attributes[] = 'class="' . esc_attr( $field['class'] ) . '"';
}
echo '<p class="form-field ' . esc_attr( $field['id'] ) . '_field ' . esc_attr( $field['wrapper_class'] ) . '">
<label for="' . esc_attr( $field['id'] ) . '">' . wp_kses_post( $field['label'] ) . '</label>';
@@ -175,7 +190,19 @@ function woocommerce_wp_checkbox( $field, WC_Data $data = null ) {
echo wc_help_tip( $field['description'] );
}
echo '<input type="checkbox" class="' . esc_attr( $field['class'] ) . '" style="' . esc_attr( $field['style'] ) . '" name="' . esc_attr( $field['name'] ) . '" id="' . esc_attr( $field['id'] ) . '" value="' . esc_attr( $field['cbvalue'] ) . '" ' . checked( $field['value'], $field['cbvalue'], false ) . ' ' . implode( ' ', $custom_attributes ) . '/> ';
// Output a hidden field so a value is POSTed if the box is not checked.
if ( ! is_null( $field['unchecked_value'] ) ) {
printf( '<input type="hidden" name="%1$s" value="%2$s" />', esc_attr( $field['name'] ), esc_attr( $field['unchecked_value'] ) );
}
printf(
'<input type="checkbox" name="%1$s" id="%2$s" value="%3$s" %4$s %5$s />',
esc_attr( $field['name'] ),
esc_attr( $field['id'] ),
esc_attr( $field['checked_value'] ),
checked( $field['value'], $field['checked_value'], false ),
implode( ' ', $custom_attributes ) // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
);
if ( ! empty( $field['description'] ) && false === $field['desc_tip'] ) {
echo '<span class="description">' . wp_kses_post( $field['description'] ) . '</span>';
@@ -194,7 +221,8 @@ function woocommerce_wp_select( $field, WC_Data $data = null ) {
global $post;
$field = wp_parse_args(
$field, array(
$field,
array(
'class' => 'select short',
'style' => '',
'wrapper_class' => '',