plugin updates
This commit is contained in:
@@ -2,15 +2,24 @@
|
||||
|
||||
namespace Automattic\WooCommerce\Admin\Features;
|
||||
|
||||
use Automattic\WooCommerce\Admin\PageController;
|
||||
use Automattic\WooCommerce\Blocks\Utils\BlockTemplateUtils;
|
||||
use Automattic\WooCommerce\Admin\WCAdminHelper;
|
||||
|
||||
/**
|
||||
* Takes care of Launch Your Store related actions.
|
||||
*/
|
||||
class LaunchYourStore {
|
||||
const BANNER_DISMISS_USER_META_KEY = 'woocommerce_coming_soon_banner_dismissed';
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
add_action( 'woocommerce_update_options_general', array( $this, 'save_site_visibility_options' ) );
|
||||
add_action( 'woocommerce_update_options_site-visibility', array( $this, 'save_site_visibility_options' ) );
|
||||
add_filter( 'woocommerce_admin_shared_settings', array( $this, 'preload_settings' ) );
|
||||
add_action( 'wp_footer', array( $this, 'maybe_add_coming_soon_banner_on_frontend' ) );
|
||||
add_action( 'init', array( $this, 'register_launch_your_store_user_meta_fields' ) );
|
||||
add_action( 'wp_login', array( $this, 'reset_woocommerce_coming_soon_banner_dismissed' ), 10, 2 );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -30,12 +39,163 @@ class LaunchYourStore {
|
||||
'woocommerce_private_link' => array( 'yes', 'no' ),
|
||||
);
|
||||
|
||||
$at_least_one_saved = false;
|
||||
foreach ( $options as $name => $option ) {
|
||||
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
||||
if ( isset( $_POST[ $name ] ) && in_array( $_POST[ $name ], $option, true ) ) {
|
||||
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
||||
update_option( $name, wp_unslash( $_POST[ $name ] ) );
|
||||
$at_least_one_saved = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $at_least_one_saved ) {
|
||||
wc_admin_record_tracks_event( 'site_visibility_saved' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Preload settings for Site Visibility.
|
||||
*
|
||||
* @param array $settings settings array.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function preload_settings( $settings ) {
|
||||
if ( ! is_admin() ) {
|
||||
return $settings;
|
||||
}
|
||||
|
||||
$current_screen = get_current_screen();
|
||||
$is_setting_page = $current_screen && 'woocommerce_page_wc-settings' === $current_screen->id;
|
||||
|
||||
if ( $is_setting_page ) {
|
||||
// Regnerate the share key if it's not set.
|
||||
add_option( 'woocommerce_share_key', wp_generate_password( 32, false ) );
|
||||
|
||||
$settings['siteVisibilitySettings'] = array(
|
||||
'shop_permalink' => get_permalink( wc_get_page_id( 'shop' ) ),
|
||||
'woocommerce_coming_soon' => get_option( 'woocommerce_coming_soon' ),
|
||||
'woocommerce_store_pages_only' => get_option( 'woocommerce_store_pages_only' ),
|
||||
'woocommerce_private_link' => get_option( 'woocommerce_private_link' ),
|
||||
'woocommerce_share_key' => get_option( 'woocommerce_share_key' ),
|
||||
);
|
||||
}
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* User must be an admin or editor.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function is_manager_or_admin() {
|
||||
// phpcs:ignore
|
||||
if ( ! current_user_can( 'shop_manager' ) && ! current_user_can( 'administrator' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add 'coming soon' banner on the frontend when the following conditions met.
|
||||
*
|
||||
* - User must be either an admin or store editor (must be logged in).
|
||||
* - 'woocommerce_coming_soon' option value must be 'yes'
|
||||
* - The page must not be the Coming soon page itself.
|
||||
*/
|
||||
public function maybe_add_coming_soon_banner_on_frontend() {
|
||||
// Do not show the banner if the site is being previewed.
|
||||
if ( isset( $_GET['site-preview'] ) ) { // @phpcs:ignore
|
||||
return false;
|
||||
}
|
||||
|
||||
$current_user_id = get_current_user_id();
|
||||
if ( ! $current_user_id ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( get_user_meta( $current_user_id, self::BANNER_DISMISS_USER_META_KEY, true ) === 'yes' ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! $this->is_manager_or_admin() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 'woocommerce_coming_soon' must be 'yes'
|
||||
if ( get_option( 'woocommerce_coming_soon', 'no' ) !== 'yes' ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$store_pages_only = get_option( 'woocommerce_store_pages_only' ) === 'yes';
|
||||
if ( $store_pages_only && ! WCAdminHelper::is_store_page() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$link = admin_url( 'admin.php?page=wc-settings&tab=site-visibility' );
|
||||
$rest_url = rest_url( 'wp/v2/users/' . $current_user_id );
|
||||
$rest_nonce = wp_create_nonce( 'wp_rest' );
|
||||
|
||||
$text = sprintf(
|
||||
// translators: no need to translate it. It's a link.
|
||||
__(
|
||||
"
|
||||
This page is in \"Coming soon\" mode and is only visible to you and those who have permission. To make it public to everyone, <a href='%s'>change visibility settings</a>
|
||||
",
|
||||
'woocommerce'
|
||||
),
|
||||
$link
|
||||
);
|
||||
// phpcs:ignore
|
||||
echo "<div id='coming-soon-footer-banner'>$text<a class='coming-soon-footer-banner-dismiss' data-rest-url='$rest_url' data-rest-nonce='$rest_nonce'></a></div>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Register user meta fields for Launch Your Store.
|
||||
*/
|
||||
public function register_launch_your_store_user_meta_fields() {
|
||||
if ( ! $this->is_manager_or_admin() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
register_meta(
|
||||
'user',
|
||||
'woocommerce_launch_your_store_tour_hidden',
|
||||
array(
|
||||
'type' => 'string',
|
||||
'description' => 'Indicate whether the user has dismissed the site visibility tour on the home screen.',
|
||||
'single' => true,
|
||||
'show_in_rest' => true,
|
||||
)
|
||||
);
|
||||
|
||||
register_meta(
|
||||
'user',
|
||||
self::BANNER_DISMISS_USER_META_KEY,
|
||||
array(
|
||||
'type' => 'string',
|
||||
'description' => 'Indicate whether the user has dismissed the coming soon notice or not.',
|
||||
'single' => true,
|
||||
'show_in_rest' => true,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset 'woocommerce_coming_soon_banner_dismissed' user meta to 'no'.
|
||||
*
|
||||
* Runs when a user logs-in successfully.
|
||||
*
|
||||
* @param string $user_login user login.
|
||||
* @param object $user user object.
|
||||
*/
|
||||
public function reset_woocommerce_coming_soon_banner_dismissed( $user_login, $user ) {
|
||||
$existing_meta = get_user_meta( $user->ID, self::BANNER_DISMISS_USER_META_KEY, true );
|
||||
if ( 'yes' === $existing_meta ) {
|
||||
update_user_meta( $user->ID, self::BANNER_DISMISS_USER_META_KEY, 'no' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,6 +165,7 @@ class TaskLists {
|
||||
),
|
||||
),
|
||||
'tasks' => array(
|
||||
'StoreConnect',
|
||||
'AdditionalPayments',
|
||||
'GetMobileApp',
|
||||
),
|
||||
|
||||
@@ -9,13 +9,24 @@ use Automattic\WooCommerce\Admin\Features\OnboardingTasks\Task;
|
||||
* Launch Your Store Task
|
||||
*/
|
||||
class LaunchYourStore extends Task {
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param TaskList $task_list Parent task list.
|
||||
*/
|
||||
public function __construct( $task_list ) {
|
||||
parent::__construct( $task_list );
|
||||
|
||||
add_action( 'show_admin_bar', array( $this, 'possibly_hide_wp_admin_bar' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* ID.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_id() {
|
||||
return 'launch_your_store';
|
||||
return 'launch-your-store';
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -48,21 +59,22 @@ class LaunchYourStore extends Task {
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Action URL.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_action_url() {
|
||||
return admin_url( 'wp-admin/admin.php?page=wc-admin&path=%2Flaunch-your-store' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Task completion.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_complete() {
|
||||
$launch_status = get_option( 'launch-status' );
|
||||
|
||||
// The site is launched when the launch status is 'launched' or missing.
|
||||
$launched_values = array(
|
||||
'launched',
|
||||
'',
|
||||
false,
|
||||
);
|
||||
return in_array( $launch_status, $launched_values, true );
|
||||
return 'yes' !== get_option( 'woocommerce_coming_soon' );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -73,4 +85,40 @@ class LaunchYourStore extends Task {
|
||||
public function can_view() {
|
||||
return Features::is_enabled( 'launch-your-store' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide the WP admin bar when the user is previewing the site.
|
||||
*
|
||||
* @param bool $show Whether to show the admin bar.
|
||||
*/
|
||||
public function possibly_hide_wp_admin_bar( $show ) {
|
||||
if ( isset( $_GET['site-preview'] ) ) { // @phpcs:ignore
|
||||
return false;
|
||||
}
|
||||
|
||||
global $wp;
|
||||
$http_referer = wp_get_referer() ?? '';
|
||||
$parsed_url = wp_parse_url( $http_referer, PHP_URL_QUERY );
|
||||
$query_string = is_string( $parsed_url ) ? $parsed_url : '';
|
||||
|
||||
// Check if the user is coming from the site preview link.
|
||||
if ( strpos( $query_string, 'site-preview' ) !== false ) {
|
||||
if ( ! isset( $_SERVER['REQUEST_URI'] ) ) {
|
||||
return $show;
|
||||
}
|
||||
|
||||
// Redirect to the current URL with the site-preview query string.
|
||||
$current_url =
|
||||
add_query_arg(
|
||||
array(
|
||||
'site-preview' => 1,
|
||||
),
|
||||
esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) )
|
||||
);
|
||||
wp_safe_redirect( $current_url );
|
||||
exit;
|
||||
}
|
||||
|
||||
return $show;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ class Shipping extends Task {
|
||||
* @return string
|
||||
*/
|
||||
public function get_title() {
|
||||
return __( 'Get your products shipped', 'woocommerce' );
|
||||
return __( 'Select your shipping options', 'woocommerce' );
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
namespace Automattic\WooCommerce\Admin\Features\OnboardingTasks\Tasks;
|
||||
|
||||
use Automattic\WooCommerce\Admin\Features\OnboardingTasks\Task;
|
||||
|
||||
/**
|
||||
* Connect store to WooCommerce.com Task
|
||||
*/
|
||||
class StoreConnect extends Task {
|
||||
/**
|
||||
* ID.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_id() {
|
||||
return 'connect-store';
|
||||
}
|
||||
|
||||
/**
|
||||
* Title.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_title() {
|
||||
return __( 'Manage your WooCommerce.com Marketplace subscriptions', 'woocommerce' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Content.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_content() {
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Time.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_time() {
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Task completion.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_complete() {
|
||||
return \WC_Helper::is_site_connected();
|
||||
}
|
||||
|
||||
/**
|
||||
* Always dismissable.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_dismissable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Action URL.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_action_url() {
|
||||
return admin_url( 'admin.php?page=wc-admin&tab=my-subscriptions&path=/extensions' );
|
||||
}
|
||||
}
|
||||
@@ -78,6 +78,8 @@ class Init {
|
||||
add_action( 'rest_api_init', array( $this, 'register_layout_templates' ) );
|
||||
add_action( 'rest_api_init', array( $this, 'register_user_metas' ) );
|
||||
|
||||
add_filter( 'register_block_type_args', array( $this, 'register_metadata_attribute' ) );
|
||||
|
||||
// Make sure the block registry is initialized so that core blocks are registered.
|
||||
BlockRegistry::get_instance();
|
||||
|
||||
@@ -113,6 +115,9 @@ class Init {
|
||||
);
|
||||
wp_tinymce_inline_scripts();
|
||||
wp_enqueue_media();
|
||||
wp_register_style( 'wc-global-presets', false ); // phpcs:ignore
|
||||
wp_add_inline_style( 'wc-global-presets', wp_get_global_stylesheet( array( 'presets' ) ) );
|
||||
wp_enqueue_style( 'wc-global-presets' );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -417,4 +422,31 @@ class Init {
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the metadata block attribute for all block types.
|
||||
* This is a fallback/temporary solution until
|
||||
* the Gutenberg core version registers the metadata attribute.
|
||||
*
|
||||
* @see https://github.com/WordPress/gutenberg/blob/6aaa3686ae67adc1a6a6b08096d3312859733e1b/lib/compat/wordpress-6.5/blocks.php#L27-L47
|
||||
* To do: Remove this method once the Gutenberg core version registers the metadata attribute.
|
||||
*
|
||||
* @param array $args Array of arguments for registering a block type.
|
||||
* @return array $args
|
||||
*/
|
||||
public function register_metadata_attribute( $args ) {
|
||||
// Setup attributes if needed.
|
||||
if ( ! isset( $args['attributes'] ) || ! is_array( $args['attributes'] ) ) {
|
||||
$args['attributes'] = array();
|
||||
}
|
||||
|
||||
// Add metadata attribute if it doesn't exist.
|
||||
if ( ! array_key_exists( 'metadata', $args['attributes'] ) ) {
|
||||
$args['attributes']['metadata'] = array(
|
||||
'type' => 'object',
|
||||
);
|
||||
}
|
||||
|
||||
return $args;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,6 +61,13 @@ class ProductTemplate {
|
||||
*/
|
||||
private $icon = null;
|
||||
|
||||
/**
|
||||
* If the template is directly selectable through the UI.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
private $is_selectable_by_user = true;
|
||||
|
||||
/**
|
||||
* ProductTemplate constructor
|
||||
*
|
||||
@@ -86,6 +93,10 @@ class ProductTemplate {
|
||||
if ( isset( $data['icon'] ) ) {
|
||||
$this->icon = $data['icon'];
|
||||
}
|
||||
|
||||
if ( isset( $data['is_selectable_by_user'] ) ) {
|
||||
$this->is_selectable_by_user = $data['is_selectable_by_user'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -180,6 +191,15 @@ class ProductTemplate {
|
||||
return $this->order;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the selectable attribute.
|
||||
*
|
||||
* @return boolean Selectable.
|
||||
*/
|
||||
public function get_is_selectable_by_user() {
|
||||
return $this->is_selectable_by_user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the template order.
|
||||
*
|
||||
@@ -196,13 +216,14 @@ class ProductTemplate {
|
||||
*/
|
||||
public function to_json() {
|
||||
return array(
|
||||
'id' => $this->get_id(),
|
||||
'title' => $this->get_title(),
|
||||
'description' => $this->get_description(),
|
||||
'icon' => $this->get_icon(),
|
||||
'order' => $this->get_order(),
|
||||
'layoutTemplateId' => $this->get_layout_template_id(),
|
||||
'productData' => $this->get_product_data(),
|
||||
'id' => $this->get_id(),
|
||||
'title' => $this->get_title(),
|
||||
'description' => $this->get_description(),
|
||||
'icon' => $this->get_icon(),
|
||||
'order' => $this->get_order(),
|
||||
'layoutTemplateId' => $this->get_layout_template_id(),
|
||||
'productData' => $this->get_product_data(),
|
||||
'isSelectableByUser' => $this->get_is_selectable_by_user(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user