Файловый менеджер - Редактировать - /home/tuudkjt/globeasy/wp-includes/ID3/yith-woocommerce-wishlist.tar
Назад
includes/legacy/functions-yith-wcwl-legacy.php 0000777 00000000306 15251156646 0015547 0 ustar 00 <?php /** * Legacy Functions * * @package YITH\Wishlist\Classes\Legacy * @author YITH <plugins@yithemes.com> * @version 3.0.0 */ defined( 'YITH_WCWL' ) || exit; // Exit if accessed directly includes/legacy/class-yith-wcwl-frontend-legacy.php 0000777 00000026040 15251156646 0016464 0 ustar 00 <?php /** * Frontend legacy class * * @package YITH\Wishlist\Legacy * @author YITH <plugins@yithemes.com> */ defined( 'YITH_WCWL' ) || exit; // Exit if accessed directly. if ( ! class_exists( 'YITH_WCWL_Frontend_Legacy' ) ) { /** * Frontend legacy class */ class YITH_WCWL_Frontend_Legacy { use YITH_WCWL_Extensible_Singleton_Trait; use YITH_WCWL_Rendering_Method_Access_Trait; /* === SCRIPTS AND ASSETS === */ /** * Register styles required by the plugin * * @return void */ public function register_styles() { $woocommerce_base = WC()->template_path(); $assets_path = str_replace( array( 'http:', 'https:' ), '', WC()->plugin_url() ) . '/assets/'; // register dependencies. wp_register_style( 'jquery-selectBox', YITH_WCWL_URL . 'assets/css/jquery.selectBox.css', array(), '1.2.0' ); wp_register_style( 'woocommerce_prettyPhoto_css', $assets_path . 'css/prettyPhoto.css', array(), '3.1.6' ); /** * APPLY_FILTERS: yith_wcwl_main_style_deps * * Filter the style dependencies to be used in the plugin. * * @param array $deps Array of style dependencies * * @return array */ $deps = apply_filters( 'yith_wcwl_main_style_deps', array( 'jquery-selectBox', 'yith-wcwl-font-awesome', 'woocommerce_prettyPhoto_css' ) ); // register main style. $located = locate_template( array( $woocommerce_base . 'wishlist.css', 'wishlist.css', ) ); if ( ! $located ) { wp_register_style( 'yith-wcwl-main', YITH_WCWL_URL . 'assets/css/style.css', $deps, YITH_WCWL_VERSION ); } else { $stylesheet_directory = get_stylesheet_directory(); $stylesheet_directory_uri = get_stylesheet_directory_uri(); $template_directory = get_template_directory(); $template_directory_uri = get_template_directory_uri(); $style_url = ( strpos( $located, $stylesheet_directory ) !== false ) ? str_replace( $stylesheet_directory, $stylesheet_directory_uri, $located ) : str_replace( $template_directory, $template_directory_uri, $located ); wp_register_style( 'yith-wcwl-user-main', $style_url, $deps, YITH_WCWL_VERSION ); } // theme specific assets. $current_theme = wp_get_theme(); if ( $current_theme->exists() ) { $theme_slug = $current_theme->Template; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase if ( file_exists( YITH_WCWL_DIR . 'assets/css/themes/' . $theme_slug . '.css' ) ) { wp_register_style( 'yith-wcwl-theme', YITH_WCWL_URL . 'assets/css/themes/' . $theme_slug . '.css', array( $located ? 'yith-wcwl-user-main' : 'yith-wcwl-main' ), YITH_WCWL_VERSION ); } } } /** * Register scripts required by the plugin * * @return void */ public function register_scripts() { $woocommerce_base = WC()->template_path(); $assets_path = str_replace( array( 'http:', 'https:' ), '', WC()->plugin_url() ) . '/assets/'; $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min'; $prefix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? 'unminified/' : ''; // register dependencies. wp_register_script( 'wc-prettyPhoto', $assets_path . 'js/prettyPhoto/jquery.prettyPhoto' . $suffix . '.js', array( 'jquery' ), '3.1.6', true ); wp_register_script( 'jquery-selectBox', YITH_WCWL_ASSETS_JS_URL . 'jquery.selectBox.min.js', array( 'jquery' ), '1.2.0', true ); /** * APPLY_FILTERS: yith_wcwl_main_script_deps * * Filter the script dependencies to be used in the plugin. * * @param array $deps Array of script dependencies * * @return array */ $deps = apply_filters( 'yith_wcwl_main_script_deps', array( 'jquery', 'jquery-selectBox', \YIT_Assets::wc_script_handle( 'wc-prettyPhoto' ) ) ); // get localized variables. $yith_wcwl_l10n = $this->get_localize(); // register main script. $located = locate_template( array( $woocommerce_base . 'wishlist.js', 'wishlist.js', ) ); if ( ! $located ) { wp_register_script( 'jquery-yith-wcwl', YITH_WCWL_URL . 'assets/js/' . $prefix . 'jquery.yith-wcwl' . $suffix . '.js', $deps, YITH_WCWL_VERSION, true ); wp_localize_script( 'jquery-yith-wcwl', 'yith_wcwl_l10n', $yith_wcwl_l10n ); } else { wp_register_script( 'jquery-yith-wcwl-user', str_replace( get_stylesheet_directory(), get_stylesheet_directory_uri(), $located ), $deps, YITH_WCWL_VERSION, true ); wp_localize_script( 'jquery-yith-wcwl-user', 'yith_wcwl_l10n', $yith_wcwl_l10n ); } } /** * Enqueue styles, scripts and other stuffs needed in the <head>. * * @return void * @since 1.0.0 */ public function enqueue_styles_and_stuffs() { // main plugin style. if ( ! wp_style_is( 'yith-wcwl-user-main', 'registered' ) ) { wp_enqueue_style( 'yith-wcwl-main' ); } else { wp_enqueue_style( 'yith-wcwl-user-main' ); } // theme specific style. if ( wp_style_is( 'yith-wcwl-theme', 'registered' ) ) { wp_enqueue_style( 'yith-wcwl-theme' ); } // custom style. $this->enqueue_custom_style(); } /** * Enqueue plugin scripts. * * @return void * @since 1.0.0 */ public function enqueue_scripts() { if ( ! wp_script_is( 'jquery-yith-wcwl-user', 'registered' ) ) { wp_enqueue_script( 'jquery-yith-wcwl' ); } else { wp_enqueue_script( 'jquery-yith-wcwl-user' ); } } /** * Return localize array * * @return array Array with variables to be localized inside js * @since 2.2.3 */ public function get_localize() { /** * APPLY_FILTERS: yith_wcwl_localize_script * * Filter the array with the parameters sent to the plugin scripts trought the localize. * * @param array $localize Array of parameters * * @return array */ return apply_filters( 'yith_wcwl_localize_script', array( 'ajax_url' => admin_url( 'admin-ajax.php', 'relative' ), 'redirect_to_cart' => get_option( 'yith_wcwl_redirect_cart' ), 'yith_wcwl_button_position' => get_option( 'yith_wcwl_button_position' ), 'multi_wishlist' => false, /** * APPLY_FILTERS: yith_wcwl_hide_add_button * * Filter whether to hide the 'Add to wishlist' button. * * @param bool $hide_button Whether to hide the ATW button or not * * @return bool */ 'hide_add_button' => apply_filters( 'yith_wcwl_hide_add_button', true ), 'enable_ajax_loading' => 'yes' === get_option( 'yith_wcwl_ajax_enable', 'no' ), 'ajax_loader_url' => YITH_WCWL_URL . 'assets/images/ajax-loader-alt.svg', 'remove_from_wishlist_after_add_to_cart' => 'yes' === get_option( 'yith_wcwl_remove_after_add_to_cart' ), /** * APPLY_FILTERS: yith_wcwl_is_wishlist_responsive * * Filter whether to use the responsive layout for the wishlist. * * @param bool $is_responsive Whether to use responsive layout or not * * @return bool */ 'is_wishlist_responsive' => apply_filters( 'yith_wcwl_is_wishlist_responsive', true ), /** * APPLY_FILTERS: yith_wcwl_time_to_close_prettyphoto * * Filter the time (in miliseconds) to close the popup after the 'Ask for an estimate' request has been sent. * * @param int $time Time to close the popup * * @return int */ 'time_to_close_prettyphoto' => apply_filters( 'yith_wcwl_time_to_close_prettyphoto', 3000 ), /** * APPLY_FILTERS: yith_wcwl_fragments_index_glue * * Filter the character used for the fragments index. * * @param string $char Character * * @return string */ 'fragments_index_glue' => apply_filters( 'yith_wcwl_fragments_index_glue', '.' ), /** * APPLY_FILTERS: yith_wcwl_reload_on_found_variation * * Filter whether to reload fragments on new variations found. * * @param bool $reload_variations Whether to reload fragments * * @return bool */ 'reload_on_found_variation' => apply_filters( 'yith_wcwl_reload_on_found_variation', true ), /** * APPLY_FILTERS: yith_wcwl_mobile_media_query * * Filter the breakpoint size for the mobile media queries. * * @param int $breakpoint Breakpoint size * * @return int */ 'mobile_media_query' => apply_filters( 'yith_wcwl_mobile_media_query', 768 ), 'labels' => array( 'cookie_disabled' => __( 'We are sorry, but this feature is available only if cookies on your browser are enabled.', 'yith-woocommerce-wishlist' ), /** * APPLY_FILTERS: yith_wcwl_added_to_cart_message * * Filter the message when a product has been added succesfully to the cart from the wishlist. * * @param string $message Message * * @return string */ 'added_to_cart_message' => sprintf( '<div class="woocommerce-notices-wrapper"><div class="woocommerce-message" role="alert">%s</div></div>', apply_filters( 'yith_wcwl_added_to_cart_message', __( 'Product added to cart successfully', 'yith-woocommerce-wishlist' ) ) ), ), 'actions' => array( 'add_to_wishlist_action' => 'add_to_wishlist', 'remove_from_wishlist_action' => 'remove_from_wishlist', 'reload_wishlist_and_adding_elem_action' => 'reload_wishlist_and_adding_elem', 'load_mobile_action' => 'load_mobile', 'delete_item_action' => 'delete_item', 'save_title_action' => 'save_title', 'save_privacy_action' => 'save_privacy', 'load_fragments' => 'load_fragments', ), 'nonce' => array( 'add_to_wishlist_nonce' => wp_create_nonce( 'add_to_wishlist' ), 'remove_from_wishlist_nonce' => wp_create_nonce( 'remove_from_wishlist' ), 'reload_wishlist_and_adding_elem_nonce' => wp_create_nonce( 'reload_wishlist_and_adding_elem' ), 'load_mobile_nonce' => wp_create_nonce( 'load_mobile' ), 'delete_item_nonce' => wp_create_nonce( 'delete_item' ), 'save_title_nonce' => wp_create_nonce( 'save_title' ), 'save_privacy_nonce' => wp_create_nonce( 'save_privacy' ), 'load_fragments_nonce' => wp_create_nonce( 'load_fragments' ), ), /** * APPLY_FILTERS: yith_wcwl_redirect_after_ask_an_estimate * * Filter whether to redirect after the 'Ask for an estimate' form has been submitted. * * @param bool $redirect Whether to redirect or not * * @return bool */ 'redirect_after_ask_estimate' => apply_filters( 'yith_wcwl_redirect_after_ask_an_estimate', false ), /** * APPLY_FILTERS: yith_wcwl_redirect_url_after_ask_an_estimate * * Filter the URL to redirect after the 'Ask for an estimate' form has been submitted. * * @param string $redirect_url Redirect URL * * @return string */ 'ask_estimate_redirect_url' => apply_filters( 'yith_wcwl_redirect_url_after_ask_an_estimate', get_home_url() ), ) ); } } } includes/legacy/class-yith-wcwl-premium-legacy.php 0000777 00000006464 15251156646 0016333 0 ustar 00 <?php /** * Init premium features of the plugin * * @package YITH\Wishlist\Classes * @author YITH <plugins@yithemes.com> * @version 3.0.0 */ defined( 'YITH_WCWL_PREMIUM' ) || exit; // Exit if accessed directly. if ( ! class_exists( 'YITH_WCWL_Premium' ) ) { /** * WooCommerce Wishlist Premium * * @since 1.0.0 */ class YITH_WCWL_Premium_Legacy extends YITH_WCWL_Extended { public function __construct() { parent::__construct(); add_filter( 'yith_wcwl_adding_wishlist_args', array( $this, 'apply_deprecated_filters_when_adding_wishlist' ) ); } /** * Adding support for deprecated filters while creating a new wishlist. * * @param array $args The arguments to filter. * @return array */ public function apply_deprecated_filters_when_adding_wishlist( $args ) { /** * APPLY_FILTERS: yith_wcwl_adding_to_wishlist_wishlist_name * * Filter the name of the wishlist to be created. * * @param string $wishlist_name Wishlist name * @return string * * @deprecated since 4.0.0 */ $args[ 'wishlist_name' ] = apply_filters( 'yith_wcwl_adding_to_wishlist_wishlist_name', $args[ 'wishlist_name' ] ); /** * APPLY_FILTERS: yith_wcwl_adding_to_wishlist_wishlist_visibility * * Filter the visibility of the wishlist to be created. * * @param int $wishlist_visibility Wishlist visibility * @return int * * @deprecated since 4.0.0 */ $args[ 'wishlist_visibility' ] = apply_filters( 'yith_wcwl_adding_to_wishlist_wishlist_visibility', in_array( (int) $args[ 'wishlist_visibility' ], array( 0, 1, 2 ), true ) ? $args[ 'wishlist_visibility' ] : 0 ); /** * APPLY_FILTERS: yith_wcwl_adding_to_wishlist_user_id * * Filter the user ID saved in the wishlist. * * @param int $user_id User ID * @return int * * @deprecated since 4.0.0 */ $args[ 'user_id' ] = apply_filters( 'yith_wcwl_adding_to_wishlist_user_id', intval( $args[ 'user_id' ] ) ); /** * APPLY_FILTERS: yith_wcwl_adding_to_wishlist_session_id * * Filter the session ID saved in the wishlist. * * @param int $user_id User ID * @return int * * @deprecated since 4.0.0 */ $args[ 'session_id' ] = apply_filters( 'yith_wcwl_adding_to_wishlist_session_id', $args[ 'session_id' ] ); return $args; } /* === WISHLIST METHODS === */ /** * Update wishlist with arguments passed as second parameter * * @param int $wishlist_id Wishlist id. * @param array $args Array of parameters to use for update query. * @throws YITH_WCWL_Exception When something goes wrong with update. * @return void * @since 2.0.0 */ public function update_wishlist( $wishlist_id, $args = array() ) { wc_deprecated_function( 'YITH_WCWL_Premium_Legacy::update_wishlist', '4.0.0', 'YITH_WCWL_Wishlists_Premium::update' ); yith_wcwl_wishlists()->update( $wishlist_id, $args ); } /** * Delete indicated wishlist * * @param int $wishlist_id Wishlist id. * @throws YITH_WCWL_Exception When something goes wrong with deletion. * @return void * @since 3.0.0 */ public function remove_wishlist( $wishlist_id ) { wc_deprecated_function( 'YITH_WCWL_Premium_Legacy::remove_wishlist', '4.0.0', 'YITH_WCWL_Wishlists_Premium::remove' ); yith_wcwl_wishlists()->remove( $wishlist_id ); } } } includes/legacy/class-yith-wcwl-admin-legacy.php 0000777 00000001344 15251156646 0015735 0 ustar 00 <?php /** * Legacy admin init class * * @package YITH\Wishlist\Legacy\Classes * @author YITH <plugins@yithemes.com> */ defined( 'YITH_WCWL' ) || exit; // Exit if accessed directly. if ( ! class_exists( 'YITH_WCWL_Admin_Legacy' ) ) { /** * Initiator class. Create and populate admin views. * * @since 4.0.0 */ abstract class YITH_WCWL_Admin_Legacy { /** * Register wishlist panel * * @return void * @depreacted since 4.0.0 * @see YITH_WCWL_Admin_Panel::register_panel */ public function register_panel() { wc_deprecated_function( 'YITH_WCWL_Admin::register_panel()', '4.0.0', 'YITH_WCWL_Admin_Panel::register_panel()' ); YITH_WCWL_Admin_Panel::get_instance()->register_panel(); } } } includes/legacy/class-yith-wcwl-deprecated-hooks.php 0000777 00000015017 15251156646 0016626 0 ustar 00 <?php /** * Deprecated hooks and filters * * @package YITH\Wishlist\Classes\Legacy * @author YITH <plugins@yithemes.com> * @version 3.0.24 */ if ( ! defined( 'YITH_WCWL' ) ) { exit; } // Exit if accessed directly if ( ! class_exists( 'YITH_WCWL_Deprecated_Hooks' ) ) { /** * Class that manages deprecated hooks and filters * * @since 1.0.0 */ class YITH_WCWL_Deprecated_Hooks { /** * List of deprecated hooks * * @var array */ private $deprecated_hooks = array( 'yith_wcwl_add_to_wishlist_button_html' => 'yith_wcwl_add_to_wishlisth_button_html', 'yith_wcwl_adding_to_wishlist_product_id' => 'yith_wcwl_adding_to_wishlist_prod_id', 'yith_wcwl_add_to_wishlist_button_move_label_option' => 'yith_wcwl_move_from_wishlist_label', 'yith_wcwl_add_to_wishlist_button_modal_label_option' => 'yith_wcwl_button_popup_label', 'yith_wcwl_add_to_wishlist_button_icon_option' => 'yith_wcwl_button_icon', 'yith_wcwl_add_to_wishlist_button_label_option' => 'yith_wcwl_button_label', 'yith_wcwl_add_to_wishlist_button_remove_label_option' => 'yith_wcwl_remove_from_wishlist_label', 'yith_wcwl_add_to_wishlist_button_added_icon_option' => 'yith_wcwl_button_added_icon', 'yith_wcwl_add_to_wishlist_button_custom_icon_alt_option' => 'yith_wcwl_custom_icon_alt', 'yith_wcwl_add_to_wishlist_button_custom_icon_width_option' => 'yith_wcwl_custom_width', 'yith_wcwl_add_to_wishlist_button_browse_label_option' => 'yith_wcwl_browse_wishlist_label', 'yith_wcwl_add_to_wishlist_button_already_in_label_option' => 'yith_wcwl_product_already_in_wishlist_text_button', 'yith_wcwl_add_to_wishlist_button_added_label_option' => 'yith_wcwl_product_added_to_wishlist_message_button', ); /** * List of deprecated hooks * * @var array */ private $deprecated_version = array( 'yith_wcwl_add_to_wishlist_button_html' => '4.0.0', 'yith_wcwl_adding_to_wishlist_product_id' => '4.0.0', 'yith_wcwl_add_to_wishlist_button_move_label_option' => '4.0.0', 'yith_wcwl_add_to_wishlist_button_modal_label_option' => '4.0.0', 'yith_wcwl_add_to_wishlist_button_icon_option' => '4.0.0', 'yith_wcwl_add_to_wishlist_button_label_option' => '4.0.0', 'yith_wcwl_add_to_wishlist_button_remove_label_option' => '4.0.0', 'yith_wcwl_add_to_wishlist_button_added_icon_option' => '4.0.0', 'yith_wcwl_add_to_wishlist_button_custom_icon_alt_option' => '4.0.0', 'yith_wcwl_add_to_wishlist_button_custom_icon_width_option' => '4.0.0', 'yith_wcwl_add_to_wishlist_button_browse_label_option' => '4.0.0', 'yith_wcwl_add_to_wishlist_button_already_in_label_option' => '4.0.0', 'yith_wcwl_add_to_wishlist_button_added_label_option' => '4.0.0', ); /** * Constructor. */ public function __construct() { $new_hooks = array_keys( $this->deprecated_hooks ); array_walk( $new_hooks, array( $this, 'hook_in' ) ); add_filter( 'yith_wcwl_adding_to_wishlist_args', array( $this, 'apply_deprecated_filters_when_adding_to_wishlist' ) ); } /** * Hook into the new hook so we can handle deprecated hooks once fired. * * @param string $hook_name Hook name. */ public function hook_in( $hook_name ) { add_filter( $hook_name, array( $this, 'maybe_handle_deprecated_hook' ), -1000, 8 ); } /** * If the hook is Deprecated, call the old hooks here. */ public function maybe_handle_deprecated_hook() { $new_hook = current_filter(); $old_hook = isset( $this->deprecated_hooks[ $new_hook ] ) ? $this->deprecated_hooks[ $new_hook ] : false; $new_callback_args = func_get_args(); $return_value = $new_callback_args[ 0 ]; if ( $old_hook && has_action( $old_hook ) ) { $this->display_notice( $old_hook, $new_hook ); $return_value = apply_filters_ref_array( $old_hook, $new_callback_args ); } return $return_value; } /** * Display a deprecated notice for old hooks. * * @param string $old_hook Old hook. * @param string $new_hook New hook. */ protected function display_notice( $old_hook, $new_hook ) { $deprecated_version = isset( $this->deprecated_version[ $old_hook ] ) ? $this->deprecated_version[ $old_hook ] : YITH_WCWL_VERSION; wc_deprecated_hook( esc_html( $old_hook ), esc_html( $deprecated_version ), esc_html( $new_hook ) ); } /* === DEPRECATED FILTERS COMPATIBILITY === */ /** * Adding support for deprecated filters when adding a product in wishlist. * * TODO: mark the used filters as deprecated without any replacement * * @param array $args List of arguments when adding to wishlist * * @return array */ public function apply_deprecated_filters_when_adding_to_wishlist( $args ) { /** * APPLY_FILTERS: yith_wcwl_adding_to_wishlist_prod_id * * Filter the ID of the product added to the wishlist. * * @param int $product_id Product ID * * @return int */ $args[ 'product_id' ] = apply_filters( 'yith_wcwl_adding_to_wishlist_product_id', $args[ 'product_id' ] ); /** * APPLY_FILTERS: yith_wcwl_adding_to_wishlist_wishlist_id * * Filter the wishlist ID where the products are added to. * * @param int $wishlist_id Wishlist ID * * @return int */ $args[ 'wishlist_id' ] = apply_filters( 'yith_wcwl_adding_to_wishlist_wishlist_id', $args[ 'wishlist_id' ] ); /** * APPLY_FILTERS: yith_wcwl_adding_to_wishlist_quantity * * Filter the quantity of the product added to the wishlist. * * @param int $quantity Product quantity * @param int $product_id Product ID * * @return int */ $args[ 'quantity' ] = apply_filters( 'yith_wcwl_adding_to_wishlist_quantity', intval( $args[ 'quantity' ] ), $args[ 'product_id' ] ); /** * APPLY_FILTERS: yith_wcwl_adding_to_wishlist_user_id * * Filter the user ID saved in the wishlist. * * @param int $user_id User ID * * @return int */ $args[ 'user_id' ] = apply_filters( 'yith_wcwl_adding_to_wishlist_user_id', intval( $args[ 'user_id' ] ) ); /** * APPLY_FILTERS: yith_wcwl_adding_to_wishlist_dateadded * * Filter the date when the wishlist was created. * * @param int $date_added Date when the wishlist was created (timestamp) * * @return int */ $args[ 'dateadded' ] = apply_filters( 'yith_wcwl_adding_to_wishlist_dateadded', $args[ 'dateadded' ] ); return $args; } } } return new YITH_WCWL_Deprecated_Hooks(); includes/legacy/class-yith-wcwl-legacy.php 0000777 00000036072 15251156646 0014655 0 ustar 00 <?php /** * Main class * * @package YITH\Wishlist\Classes * @author YITH <plugins@yithemes.com> * @since 4.0.0 */ defined( 'YITH_WCWL' ) || exit; // Exit if accessed directly if ( ! class_exists( 'YITH_WCWL_Legacy' ) ) { /** * WooCommerce Wishlist * * @since 1.0.0 */ abstract class YITH_WCWL_Legacy { public function __construct() { } /* === ITEMS METHODS === */ /** * Add a product in the wishlist. * * @param array $atts Array of parameters; when not passed, params will be searched in $_REQUEST. * @throws YITH_WCWL_Exception When an error occurs with Add to Wishlist operation. * * @return void * @depreacted since 4.0 * @see YITH_WCWL_Wishlists::add_item */ public function add( $atts = array() ) { wc_deprecated_function( 'YITH_WCWL::add', '4.0.0', 'YITH_WCWL_Wishlists::add_item' ); $atts = $this->get_details( $atts ); yith_wcwl_wishlists()->add_item( $atts ); } /** * Remove an entry from the wishlist. * * @param array $atts Array of parameters; when not passed, parameters will be retrieved from $_REQUEST. * * @throws YITH_WCWL_Exception When something was wrong with removal. * * @return void * @depreacted since 4.0 * @see YITH_WCWL_Wishlists::remove_item */ public function remove( $atts = array() ) { wc_deprecated_function( 'YITH_WCWL::remove', '4.0.0', 'YITH_WCWL_Wishlists::remove_item' ); $atts = $this->get_details($atts); yith_wcwl_wishlists()->remove_item( $atts ); } /** * Retrieve first list of current user where a specific product occurs; if no wishlist is found, returns false * * @param int $product_id Product id. * @return \YITH_WCWL_Wishlist|bool First wishlist found where the product occurs (system will privilege default lists) * @depreacted since 4.0 * @see YITH_WCWL_Wishlists::get_wishlist_for_product */ public function get_wishlist_for_product( $product_id ) { wc_deprecated_function( 'YITH_WCWL::get_wishlist_for_product', '4.0.0', 'YITH_WCWL_Wishlists::get_wishlist_for_product' ); return yith_wcwl_wishlists()->get_wishlist_for_product( $product_id ); } /** * Retrieve elements of the wishlist for a specific user * * @param array $args Arguments array; it may contains any of the following:<br/> * [<br/> * 'user_id' // Owner of the wishlist; default to current user logged in (if any), or false for cookie wishlist<br/> * 'product_id' // Product to search in the wishlist<br/> * 'wishlist_id' // wishlist_id for a specific wishlist, false for default, or all for any wishlist<br/> * 'wishlist_token' // wishlist token, or false as default<br/> * 'wishlist_visibility' // all, visible, public, shared, private<br/> * 'is_default' => // whether searched wishlist should be default one <br/> * 'id' => false, // only for table select<br/> * 'limit' => false, // pagination param; number of items per page. 0 to get all items<br/> * 'offset' => 0 // pagination param; offset for the current set. 0 to start from the first item<br/> * ]. * * @return YITH_WCWL_Wishlist_Item[]|bool * @depreacted since 4.0 * @see YITH_WCWL_Wishlists::get_items */ public function get_products( $args = array() ) { wc_deprecated_function( 'YITH_WCWL::get_products', '4.0.0', 'YITH_WCWL_Wishlists::get_items' ); return yith_wcwl_wishlists()->get_items( $args ); } /** * Retrieve details of a product in the wishlist. * * @param int $product_id Product id. * @param int|bool $wishlist_id Wishlist id, or false when default should be applied. * @return YITH_WCWL_Wishlist_Item|bool * @depreacted since 4.0 * @see YITH_WCWL_Wishlists::get_product_item */ public function get_product_details( $product_id, $wishlist_id = false ) { wc_deprecated_function( 'YITH_WCWL::get_product_details', '4.0.0', 'YITH_WCWL_Wishlists::get_product_item' ); return yith_wcwl_wishlists()->get_product_item( $product_id, $wishlist_id ); } /** * Retrieve the number of products in the wishlist. * * @param string|bool $wishlist_token Wishlist token if any; false for default wishlist. * * @return int * @depreacted since 4.0 * @see YITH_WCWL_Wishlists::count_items_in_wishlist */ public function count_products( $wishlist_token = false ) { wc_deprecated_function( 'YITH_WCWL::count_products', '4.0.0', 'YITH_WCWL_Wishlists::count_items_in_wishlist' ); return yith_wcwl_wishlists()->count_items_in_wishlist( $wishlist_token ); } /** * Count all user items in wishlists * * @return int Count of items added all over wishlist from current user * @depreacted since 4.0 * @see YITH_WCWL_Wishlists::count_all_items */ public function count_all_products() { wc_deprecated_function( 'YITH_WCWL::count_all_products', '4.0.0', 'YITH_WCWL_Wishlists::count_all_items' ); return yith_wcwl_wishlists()->count_all_items(); } /** * Count number of times a product was added to users wishlists * * @param int|bool $product_id Product id; false will force method to use global product. * * @return int Number of times the product was added to wishlist * * @depreacted since 4.0 * @see YITH_WCWL_Wishlists::count_add_to_wishlist */ public function count_add_to_wishlist( $product_id = false ) { wc_deprecated_function( 'YITH_WCWL::count_add_to_wishlist', '4.0.0', 'YITH_WCWL_Wishlists::count_add_to_wishlist' ); return yith_wcwl_wishlists()->count_add_to_wishlist( $product_id ); } /** * Count product occurrences in users wishlists * * @param int|bool $product_id Product id; false will force method to use global product. * * @return int * * @depreacted since 4.0 * @see YITH_WCWL_Wishlists::count_product_occurrences */ public function count_product_occurrences( $product_id = false ) { wc_deprecated_function( 'YITH_WCWL::count_product_occurrences', '4.0.0', 'YITH_WCWL_Wishlists::count_product_occurrences' ); return yith_wcwl_wishlists()->count_product_occurrences( $product_id ); } /** * Check if the product exists in the wishlist. * * @param int $product_id Product id to check. * @param int|bool $wishlist_id Wishlist where to search (use false to search in default wishlist). * @return bool * * @depreacted since 4.0 * @see YITH_WCWL_Wishlists::is_product_in_wishlist */ public function is_product_in_wishlist( $product_id, $wishlist_id = false ) { wc_deprecated_function( 'YITH_WCWL::is_product_in_wishlist', '4.0.0', 'YITH_WCWL_Wishlists::is_product_in_wishlist' ); return yith_wcwl_wishlists()->is_product_in_wishlist( $product_id, $wishlist_id ); } /* === WISHLISTS METHODS === */ /** * Add a new wishlist for the user. * * @param array $atts Array of params for wishlist creation. * @return int|false The ID of the wishlist created or false if something go wrong * * @depreacted since 4.0.0 * @see YITH_WCWL_Wishlists::remove_item */ public function add_wishlist( $atts = array() ) { wc_deprecated_function( 'YITH_WCWL::add_wishlist', '4.0.0', 'YITH_WCWL_Wishlists::create' ); $atts = $this->get_details($atts); return yith_wcwl_wishlists()->create( $atts ); } /** * Get details stored in the class or from request * * @return array */ public function get_details( $atts = array() ){ $atts = empty( $atts ) && ! empty( $this->details ) ? $this->details : $atts; $atts = ! empty( $atts ) ? $atts : $_REQUEST; // phpcs:ignore WordPress.Security.NonceVerification.Recommended if ( isset( $atts[ 'add_to_wishlist' ] ) ) { $atts[ 'product_id' ] = $atts[ 'add_to_wishlist' ]; unset( $atts[ 'add_to_wishlist' ] ); } if ( isset( $atts[ 'remove_from_wishlist' ] ) ) { $atts[ 'product_id' ] = $atts[ 'remove_from_wishlist' ]; unset( $atts[ 'remove_from_wishlist' ] ); } return $atts; } /** * Update wishlist with arguments passed as second parameter * * @param int $wishlist_id Wishlist id. * @param array $args Array of parameters to use in update process. * * @return void * * @depreacted since 4.0.0 * @see YITH_WCWL_Wishlists::update */ public function update_wishlist( $wishlist_id, $args = array() ) { wc_deprecated_function( 'YITH_WCWL::update_wishlist', '4.0.0', 'YITH_WCWL_Wishlists::update' ); yith_wcwl_wishlists()->update( $wishlist_id, $args ); } /** * Delete indicated wishlist * * @param int $wishlist_id Wishlist id. * * @return void * * @depreacted since 4.0.0 * @see YITH_WCWL_Wishlists::remove */ public function remove_wishlist( $wishlist_id ) { wc_deprecated_function( 'YITH_WCWL::remove_wishlist', '4.0.0', 'YITH_WCWL_Wishlists::remove' ); yith_wcwl_wishlists()->remove( $wishlist_id ); } /** * Retrieve all the wishlist matching specified arguments * * @param array $args Array of valid arguments<br/> * [<br/> * 'id' // Wishlist id to search, if any<br/> * 'user_id' // User owner<br/> * 'wishlist_slug' // Slug of the wishlist to search<br/> * 'wishlist_name' // Name of the wishlist to search<br/> * 'wishlist_token' // Token of the wishlist to search<br/> * 'wishlist_visibility' // Wishlist visibility: all, visible, public, shared, private<br/> * 'user_search' // String to match against first name / last name or email of the wishlist owner<br/> * 'is_default' // Whether wishlist should be default or not<br/> * 'orderby' // Column used to sort final result (could be any wishlist lists column)<br/> * 'order' // Sorting order<br/> * 'limit' // Pagination param: maximum number of elements in the set. 0 to retrieve all elements<br/> * 'offset' // Pagination param: offset for the current set. 0 to start from the first item<br/> * 'show_empty' // Whether to show empty lists os not<br/> * ]. * * @return YITH_WCWL_Wishlist[] * * @depreacted since 4.0 * @see YITH_WCWL_Wishlist_Factory::get_wishlists */ public function get_wishlists( $args = array() ) { wc_deprecated_function( 'YITH_WCWL::get_wishlists', '4.0.0', 'YITH_WCWL_Wishlist_Factory::get_wishlists' ); return YITH_WCWL_Wishlist_Factory::get_wishlists( $args ); } /** * Wrapper for \YITH_WCWL::get_wishlists, will return wishlists for current user * * @return YITH_WCWL_Wishlist[] * * @depreacted since 4.0 * @see YITH_WCWL_Wishlists::get_current_user_wishlists */ public function get_current_user_wishlists() { wc_deprecated_function( 'YITH_WCWL::get_current_user_wishlists', '4.0.0', 'YITH_WCWL_Wishlists::get_current_user_wishlists' ); return yith_wcwl_wishlists()->get_current_user_wishlists(); } /** * Returns details of a wishlist, searching it by wishlist id * * @param int $wishlist_id Wishlist id. * @return YITH_WCWL_Wishlist * * @depreacted since 4.0 * @see YITH_WCWL_Wishlist_Factory::get_wishlist */ public function get_wishlist_detail( $wishlist_id ) { wc_deprecated_function( 'YITH_WCWL::get_wishlist_detail', '4.0.0', 'YITH_WCWL_Wishlist_Factory::get_wishlist' ); return YITH_WCWL_Wishlist_Factory::get_wishlist( $wishlist_id ); } /** * Returns details of a wishlist, searching it by wishlist token * * @param string $wishlist_token Wishlist token. * @return YITH_WCWL_Wishlist * * @depreacted since 4.0 * @see YITH_WCWL_Wishlists::get_wishlist_for_product */ public function get_wishlist_detail_by_token( $wishlist_token ) { wc_deprecated_function( 'YITH_WCWL::get_wishlist_detail_by_token', '4.0.0', 'YITH_WCWL_Wishlist_Factory::get_wishlist' ); return YITH_WCWL_Wishlist_Factory::get_wishlist( $wishlist_token ); } /** * Generate default wishlist for current user or session * * @param int|bool $id User or session id; false if you want to use current user/session. * * @return int Default wishlist id * * @depreacted since 4.0 * @see YITH_WCWL_Wishlists::generate_default_wishlist */ public function generate_default_wishlist( $id = false ) { wc_deprecated_function( 'YITH_WCWL::generate_default_wishlist', '4.0.0', 'YITH_WCWL_Wishlists::generate_default_wishlist' ); return yith_wcwl_wishlists()->generate_default_wishlist( $id ); } /** * Generate a token to visit wishlist * * @return string token * * @depreacted since 4.0 * @see YITH_WCWL_Wishlist_Factory::generate_wishlist_token */ public function generate_wishlist_token() { wc_deprecated_function( 'YITH_WCWL::generate_wishlist_token', '4.0.0', 'YITH_WCWL_Wishlist_Factory::generate_wishlist_token' ); return YITH_WCWL_Wishlist_Factory::generate_wishlist_token(); } /** * Returns an array of users that created and populated a public wishlist * * @param array $args Array of valid arguments<br/> * [<br/> * 'search' // String to match against first name / last name / user login or user email of wishlist owner<br/> * 'limit' // Pagination param: number of items to show in one page. 0 to show all items<br/> * 'offset' // Pagination param: offset for the current set. 0 to start from the first item<br/> * ]. * * @return array * * @depreacted since 4.0 * @see YITH_WCWL_Wishlist_Factory::get_wishlist_users */ public function get_users_with_wishlist( $args = array() ) { wc_deprecated_function( 'YITH_WCWL::get_users_with_wishlist', '4.0.0', 'YITH_WCWL_Wishlist_Factory::get_wishlist_users' ); return YITH_WCWL_Wishlist_Factory::get_wishlist_users( $args ); } /** * Count users that have public wishlists * * @param string $search Search string. * * @return int * * @depreacted since 4.0 * @see YITH_WCWL_Wishlists::count_users_with_wishlists */ public function count_users_with_wishlists( $search ) { wc_deprecated_function( 'YITH_WCWL::count_users_with_wishlists', '4.0.0', 'YITH_WCWL_Wishlists::count_users_with_wishlists' ); return yith_wcwl_wishlists()->count_users_with_wishlists( $search ); } /* === GENERAL METHODS === */ /** * Checks whether multi-wishlist feature is enabled for current user * * @return bool Whether feature is enabled or not */ public function is_multi_wishlist_enabled() { wc_deprecated_function( 'YITH_WCWL::is_multi_wishlist_enabled', '4.0.0', 'YITH_WCWL_Wishlists::is_multi_wishlist_enabled' ); return yith_wcwl_wishlists()->is_multi_wishlist_enabled(); } } } includes/class-yith-wcwl-exception.php 0000777 00000001437 15251156646 0014140 0 ustar 00 <?php /** * Wishlist Exception class * * @package YITH\Wishlist\Classes * @author YITH <plugins@yithemes.com> * @version 3.0.0 */ defined( 'YITH_WCWL' ) || exit; // Exit if accessed directly. if ( ! class_exists( 'YITH_WCWL_Exception' ) ) { /** * WooCommerce Wishlist Exception * * @since 1.0.0 */ class YITH_WCWL_Exception extends Exception { /** * Available error codes * * @var array */ private $error_codes = array( 0 => 'error', 1 => 'exists', ); /** * Returns textual code for the error * * @return string Textual code of the error. */ public function getTextualCode() { $code = $this->getCode(); if ( array_key_exists( $code, $this->error_codes ) ) { return $this->error_codes[ $code ]; } return 'error'; } } } includes/class-yith-wcwl-form-handler.php 0000777 00000015227 15251156646 0014522 0 ustar 00 <?php /** * Static class that will handle all form submission from customer * * @author YITH <plugins@yithemes.com> * @package YITH\Wishlist\Classes * @version 3.0.0 */ if ( ! defined( 'YITH_WCWL' ) ) { exit; } // Exit if accessed directly if ( ! class_exists( 'YITH_WCWL_Form_Handler' ) ) { /** * WooCommerce Wishlist Form Handler * * @since 3.0.0 */ class YITH_WCWL_Form_Handler { /** * Performs all required add_actions to handle forms * * @return void */ public static function init() { /** * This check was added to prevent bots from accidentaly executing wishlist code * * @since 3.0.10 */ if ( ! self::process_form_handling() ) { return; } // add to wishlist when js is disabled. add_action( 'init', array( 'YITH_WCWL_Form_Handler', 'add_to_wishlist' ) ); // remove from wishlist when js is disabled. add_action( 'init', array( 'YITH_WCWL_Form_Handler', 'remove_from_wishlist' ) ); // remove from wishlist after add to cart. add_action( 'woocommerce_add_to_cart', array( 'YITH_WCWL_Form_Handler', 'remove_from_wishlist_after_add_to_cart' ) ); // change wishlist title. add_action( 'init', array( 'YITH_WCWL_Form_Handler', 'change_wishlist_title' ) ); } /** * Return true if system can process request; false otherwise * * @return bool */ public static function process_form_handling() { $user_agent = isset( $_SERVER['HTTP_USER_AGENT'] ) ? sanitize_text_field( wp_unslash( $_SERVER['HTTP_USER_AGENT'] ) ) : false; /** * APPLY_FILTERS: yith_wcwl_block_user_agent * * Filter the conditions to block some user agents. * * @param bool $condition Conditions * @param string $user_agent User agent * * @return bool */ if ( $user_agent && apply_filters( 'yith_wcwl_block_user_agent', preg_match( '/bot|crawl|slurp|spider|wordpress/i', $user_agent ), $user_agent ) ) { return false; } return true; } /** * Adds a product to wishlist when js is disabled * * @return void */ public static function add_to_wishlist() { // add item to wishlist when javascript is not enabled. if ( isset( $_GET['add_to_wishlist'] ) && isset( $_GET['_wpnonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['_wpnonce'] ) ), 'add_to_wishlist' ) ) { try { yith_wcwl_wishlists()->add_item(yith_wcwl()->get_details()); /** * APPLY_FILTERS: yith_wcwl_product_added_to_wishlist_message * * Filter the message shown when an item has been added to the wishlist. * * @param string $message Message * * @return string */ yith_wcwl_add_notice( apply_filters( 'yith_wcwl_product_added_to_wishlist_message', get_option( 'yith_wcwl_product_added_text' ) ), 'success' ); } catch ( Exception $e ) { /** * APPLY_FILTERS: yith_wcwl_error_adding_to_wishlist_message * * Filter the error message shown when adding an item to the wishlist. * * @param string $message Message * * @return string */ yith_wcwl_add_notice( apply_filters( 'yith_wcwl_error_adding_to_wishlist_message', $e->getMessage() ), 'error' ); } } } /** * Removes from wishlist when js is disabled * * @return void */ public static function remove_from_wishlist() { // remove item from wishlist when javascript is not enabled. if ( isset( $_GET['remove_from_wishlist'] ) && isset( $_GET['_wpnonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['_wpnonce'] ) ), 'remove_from_wishlist' ) ) { try { yith_wcwl_wishlists()->remove_item( yith_wcwl()->get_details() ); } catch ( Exception $e ) { yith_wcwl_add_notice( $e->getMessage(), 'error' ); } } } /** * Remove from wishlist after adding to cart * * @return void */ public static function remove_from_wishlist_after_add_to_cart() { if ( 'yes' !== get_option( 'yith_wcwl_remove_after_add_to_cart' ) ) { return; } $args = array(); // phpcs:disable WordPress.Security.NonceVerification.Recommended if ( isset( $_REQUEST['remove_from_wishlist_after_add_to_cart'] ) ) { $args['remove_from_wishlist'] = intval( $_REQUEST['remove_from_wishlist_after_add_to_cart'] ); if ( isset( $_REQUEST['wishlist_id'] ) ) { $args['wishlist_id'] = sanitize_text_field( wp_unslash( $_REQUEST['wishlist_id'] ) ); } } elseif ( yith_wcwl_is_wishlist() && isset( $_REQUEST['add-to-cart'] ) ) { $args['remove_from_wishlist'] = intval( $_REQUEST['add-to-cart'] ); if ( isset( $_REQUEST['wishlist_id'] ) ) { $args['wishlist_id'] = sanitize_text_field( wp_unslash( $_REQUEST['wishlist_id'] ) ); } } // phpcs:enable WordPress.Security.NonceVerification.Recommended if ( ! empty( $args['wishlist_id'] ) ) { $wishlist = yith_wcwl_get_wishlist( $args['wishlist_id'] ); /** * APPLY_FILTERS: yith_wcwl_remove_after_add_to_cart * * Filter the conditions to allow removing the product from the wishlist after it has been adding to the cart. * * @param bool $condition Conditions * * @return bool */ if ( apply_filters( 'yith_wcwl_remove_after_add_to_cart', $wishlist && $wishlist->is_current_user_owner(), $wishlist ) ) { try { yith_wcwl_wishlists()->remove_item( yith_wcwl()->get_details( $args ) ); } catch ( Exception $e ) { // phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedCatch // we were unable to remove item from the wishlist; no follow up is provided. } } } } /** * Change wishlist title * * @return void * @since 2.0.0 */ public static function change_wishlist_title() { if ( ! isset( $_POST['yith_wcwl_edit_wishlist'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['yith_wcwl_edit_wishlist'] ) ), 'yith_wcwl_edit_wishlist_action' ) || ! isset( $_POST['save_title'] ) || empty( $_POST['wishlist_name'] ) ) { return; } $wishlist_name = isset( $_POST['wishlist_name'] ) ? sanitize_text_field( wp_unslash( $_POST['wishlist_name'] ) ) : false; $wishlist_id = isset( $_POST['wishlist_id'] ) ? sanitize_text_field( wp_unslash( $_POST['wishlist_id'] ) ) : false; $wishlist = yith_wcwl_get_wishlist( $wishlist_id ); if ( ! $wishlist_name || strlen( $wishlist_name ) >= 65535 ) { yith_wcwl_add_notice( __( 'Please, make sure to enter a valid title', 'yith-woocommerce-wishlist' ), 'error' ); } else { $wishlist->set_name( $wishlist_name ); $wishlist->save(); } $redirect_url = isset( $_REQUEST['redirect_to'] ) ? esc_url_raw( wp_unslash( $_REQUEST['redirect_to'] ) ) : $wishlist->get_url(); wp_safe_redirect( $redirect_url ); die; } } } YITH_WCWL_Form_Handler::init(); includes/class-yith-wcwl-wishlist-factory.php 0000777 00000040516 15251156646 0015456 0 ustar 00 <?php /** * Wishlist Factory class * * @author YITH <plugins@yithemes.com> * @package YITH\Wishlist\Classes\Wishlists * @version 3.0.0 */ if ( ! defined( 'YITH_WCWL' ) ) { exit; } // Exit if accessed directly if ( ! class_exists( 'YITH_WCWL_Wishlist_Factory' ) ) { /** * This class is used to create all Wishlist object required by the plugin * * @since 3.0.0 */ class YITH_WCWL_Wishlist_Factory { /** * Retrieve a specific wishlist from ID or token * * @param string|int|bool $wishlist_id Wishlist id or token or false, when you want to retrieve default. * @param string $context Context; when on edit context, and no wishlist matches selection, default wishlist will be created and returned. * @return \YITH_WCWL_Wishlist|bool Wishlist object or false on failure */ public static function get_wishlist( $wishlist_id = false, $context = 'view' ) { if ( ! $wishlist_id ) { return self::get_default_wishlist( false, $context ); } try { if ( is_array( $wishlist_id ) ) { $wishlist_id = $wishlist_id[0]; } return new YITH_WCWL_Wishlist( $wishlist_id ); } catch ( Exception $e ) { wc_caught_exception( $e, __FUNCTION__, func_get_args() ); return false; } } /** * Query database to search for wishlists that matches specific parameters * * @param array $args Array of valid arguments<br/> * [<br/> * 'id' // Wishlist id to search, if any<br/> * 'user_id' // User owner<br/> * 'wishlist_slug' // Slug of the wishlist to search<br/> * 'wishlist_name' // Name of the wishlist to search<br/> * 'wishlist_token' // Token of the wishlist to search<br/> * 'wishlist_visibility' // Wishlist visibility: all, visible, public, shared, private<br/> * 'user_search' // String to match against first name / last name or email of the wishlist owner<br/> * 'is_default' // Whether wishlist should be default or not<br/> * 'orderby' // Column used to sort final result (could be any wishlist lists column)<br/> * 'order' // Sorting order<br/> * 'limit' // Pagination param: maximum number of elements in the set. 0 to retrieve all elements<br/> * 'offset' // Pagination param: offset for the current set. 0 to start from the first item<br/> * 'show_empty' // Whether to show empty lists os not<br/> * ]. * * @return \YITH_WCWL_Wishlist[]|bool A list of matching wishlists or false on failure */ public static function get_wishlists( $args = array() ) { /** * APPLY_FILTERS: yith_wcwl_wishlist_query_args * * Filter the array of parameters to get wishlists. * * @param array $args Array of parameters * * @return array */ $args = apply_filters( 'yith_wcwl_wishlist_query_args', $args ); try { $results = WC_Data_Store::load( 'wishlist' )->query( $args ); /** * APPLY_FILTERS: yith_wcwl_wishlist_query * * Filter the result of the query to get wishlists. * * @param array $results Query results * @param array $args Array of parameters * * @return array */ return apply_filters( 'yith_wcwl_wishlist_query', $results, $args ); } catch ( Exception $e ) { wc_caught_exception( $e, __FUNCTION__, func_get_args() ); return false; } } /** * Query database to count wishlists that matches specific parameters * * @param array $args Same parameters allowed for {@see get_wishlists}. * @return int Count */ public static function get_wishlists_count( $args = array() ) { /** * APPLY_FILTERS: yith_wcwl_wishlists_count_query_args * * Filter the array of parameters to get wishlists count. * * @param array $args Array of parameters * * @return array */ $args = apply_filters( 'yith_wcwl_wishlists_count_query_args', $args ); try { $result = WC_Data_Store::load( 'wishlist' )->count( $args ); /** * APPLY_FILTERS: yith_wcwl_wishlist_count_query * * Filter the result of the query to get wishlists count. * * @param int $result Query results * @param array $args Array of parameters * * @return int */ return apply_filters( 'yith_wcwl_wishlist_count_query', $result, $args ); } catch ( Exception $e ) { wc_caught_exception( $e, __FUNCTION__, func_get_args() ); return 0; } } /** * Search user ids whose wishlists match passed parameters * NOTE: this will only retrieve wishlists for a logged in user, while guests wishlist will be ignored * * @param array $args Array of valid arguments<br/> * [<br/> * 'search' // String to match against first name / last name / user login or user email of wishlist owner<br/> * 'limit' // Pagination param: number of items to show in one page. 0 to show all items<br/> * 'offset' // Pagination param: offset for the current set. 0 to start from the first item<br/> * ]. * @return int[]|bool Array of user ids, or false on failure */ public static function get_wishlist_users( $args = array() ) { /** * APPLY_FILTERS: yith_wcwl_wishlist_users_query_args * * Filter the array of parameters to get wishlists users. * * @param array $args Array of parameters * * @return array */ $args = apply_filters( 'yith_wcwl_wishlist_users_query_args', $args ); try { $results = WC_Data_Store::load( 'wishlist' )->search_users( $args ); /** * APPLY_FILTERS: yith_wcwl_wishlist_user_query * * Filter the result of the query to get wishlists users. * * @param array $results Query results * @param array $args Array of parameters * * @return array */ return apply_filters( 'yith_wcwl_wishlist_user_query', $results, $args ); } catch ( Exception $e ) { wc_caught_exception( $e, __FUNCTION__, func_get_args() ); return false; } } /** * Retrieve current wishlist, basing on query string parameters, user or session * * @param array $args Array of arguments<br/> * [<br/> * 'action_params' // query string parameters * 'user_id' // user we need to retrieve wishlist for * 'wishlist_id' // id of the wishlist we need to retrieve * ]. * @return YITH_WCWL_Wishlist|bool */ public static function get_current_wishlist( $args = array() ) { $defaults = array( 'action_params' => get_query_var( YITH_WCWL()->wishlist_param, false ), 'user_id' => isset( $_GET['user_id'] ) ? intval( $_GET['user_id'] ) : false, // phpcs:ignore WordPress.Security.NonceVerification.Recommended 'wishlist_id' => false, ); /** * Extracted variables: * * @var $action_params * @var $user_id * @var $wishlist_id */ $args = wp_parse_args( $args, $defaults ); extract( $args ); // phpcs:ignore WordPress.PHP.DontExtract // retrieve options from query string. /** * APPLY_FILTERS: yith_wcwl_current_wishlist_view_params * * Filter the array of parameters to see the current wishlist. * * @param array $params Array of parameters * * @return array */ $action_params = explode( '/', apply_filters( 'yith_wcwl_current_wishlist_view_params', $action_params ) ); $action = ( isset( $action_params[0] ) ) ? $action_params[0] : 'view'; $value = ( isset( $action_params[1] ) ) ? $action_params[1] : ''; if ( ! empty( $wishlist_id ) ) { return self::get_wishlist( $wishlist_id ); } if ( ! empty( $user_id ) ) { return self::get_default_wishlist( $user_id ); } if ( empty( $action ) || ! in_array( $action, YITH_WCWL()->get_available_views(), true ) || in_array( $action, array( 'view', 'user' ), true ) || ( in_array( $action, array( 'manage', 'create' ), true ) && ! yith_wcwl_wishlists()->is_multi_wishlist_enabled() ) ) { switch ( $action ) { case 'user': $user_id = $value; $user_id = ( ! $user_id ) ? get_query_var( $user_id, false ) : $user_id; return self::get_default_wishlist( intval( $user_id ) ); case 'view': default: return self::get_wishlist( sanitize_text_field( $value ) ); } } return false; } /** * Retrieve default wishlist for current user (or current session) * * @param string|int|bool $id Customer or session id; false if you want to use current customer or session. * @param string $context Context; when on edit context, wishlist will be created, if not exists. * * @return \YITH_WCWL_Wishlist|bool Wishlist object or false on failure */ public static function get_default_wishlist( $id = false, $context = 'read' ) { try { $default_wishlist = WC_Data_Store::load( 'wishlist' )->get_default_wishlist( $id, $context ); /** * APPLY_FILTERS: yith_wcwl_default_wishlist * * Filter the default wishlist created. * * @param YITH_WCWL_Wishlist $default_wishlist Default wishlist * @param int $id Customer or session ID * @param string $context Context * * @return YITH_WCWL_Wishlist */ return apply_filters( 'yith_wcwl_default_wishlist', $default_wishlist, $id, $context ); } catch ( Exception $e ) { wc_caught_exception( $e, __FUNCTION__, func_get_args() ); return false; } } /** * Retrieve default wishlist for current user (or current session) * * @param string|int|bool $id Customer or session id; false if you want to use current customer or session. * @return \YITH_WCWL_Wishlist|bool Wishlist object or false on failure */ public static function generate_default_wishlist( $id = false ) { return self::get_default_wishlist( $id ); } /** * Generate new token for a wishlist * * @return string|bool Brand new token, or false on failure */ public static function generate_wishlist_token() { try { $token = WC_Data_Store::load( 'wishlist' )->generate_token(); return $token; } catch ( Exception $e ) { wc_caught_exception( $e, __FUNCTION__, func_get_args() ); return false; } } /** * Retrieve a specific wishlist item from ID * * @param int|\YITH_WCWL_Wishlist_Item|stdClass $item_id Item identifier, or item itself. * @return \YITH_WCWL_Wishlist_Item|bool Wishlist item, or false on failure */ public static function get_wishlist_item( $item_id = 0 ) { if ( is_numeric( $item_id ) ) { $id = $item_id; } elseif ( $item_id instanceof YITH_WCWL_Wishlist_Item ) { $id = $item_id->get_id(); } elseif ( is_object( $item_id ) && ! empty( $item_id->ID ) ) { $id = $item_id->ID; } else { $id = false; } if ( $id ) { try { return new YITH_WCWL_Wishlist_Item( $id ); } catch ( Exception $e ) { return false; } } return false; } /** * Retrieve item from a wishlist by product id * * @param int|string $wishlist_id Wishlist id or token. * @param int $product_id Product ID. * @return YITH_WCWL_Wishlist_Item|bool Item, or false when no item found */ public static function get_wishlist_item_by_product_id( $wishlist_id, $product_id ) { $wishlist = self::get_wishlist( $wishlist_id ); if ( $wishlist ) { return $wishlist->get_product( $product_id ); } return false; } /** * Query database to search for wishlist items that matches specific parameters * * @param array $args Arguments array; it may contains any of the following:<br/> * [<br/> * 'user_id' // Owner of the wishlist; default to current user logged in (if any), or false for cookie wishlist<br/> * 'product_id' // Product to search in the wishlist<br/> * 'wishlist_id' // wishlist_id for a specific wishlist, false for default, or all for any wishlist<br/> * 'wishlist_token' // wishlist token, or false as default<br/> * 'wishlist_visibility' // all, visible, public, shared, private<br/> * 'is_default' => // whether searched wishlist should be default one <br/> * 'id' => false, // only for table select<br/> * 'limit' => false, // pagination param; number of items per page. 0 to get all items<br/> * 'offset' => 0 // pagination param; offset for the current set. 0 to start from the first item<br/> * ]. * * @return \YITH_WCWL_Wishlist_Item[]|bool A list of matching items or false on failure */ public static function get_wishlist_items( $args = array() ) { /** * APPLY_FILTERS: yith_wcwl_wishlist_items_query_args * * Filter the array of parameters to get wishlist items. * * @param array $args Array of parameters * * @return array */ $args = apply_filters( 'yith_wcwl_wishlist_items_query_args', $args ); try { $results = WC_Data_Store::load( 'wishlist-item' )->query( $args ); /** * APPLY_FILTERS: yith_wcwl_wishlist_item_query * * Filter the result of the query to get wishlist items. * * @param array $results Query results * @param array $args Array of parameters * * @return array */ return apply_filters( 'yith_wcwl_wishlist_item_query', $results, $args ); } catch ( Exception $e ) { wc_caught_exception( $e, __FUNCTION__, func_get_args() ); return false; } } /** * Query database to count wishlist items that matches specific parameters * * @param array $args Same parameters allowed for {@see get_wishlist_items}. * @return int Count */ public static function get_wishlist_items_count( $args = array() ) { /** * APPLY_FILTERS: yith_wcwl_wishlist_items_count_query_args * * Filter the array of parameters to get wishlist items count. * * @param array $args Array of parameters * * @return array */ $args = apply_filters( 'yith_wcwl_wishlist_items_count_query_args', $args ); try { $result = WC_Data_Store::load( 'wishlist-item' )->count( $args ); /** * APPLY_FILTERS: yith_wcwl_wishlist_item_count_query * * Filter the result of the query to get wishlist items count. * * @param int $result Query results * @param array $args Array of parameters * * @return int */ return apply_filters( 'yith_wcwl_wishlist_item_count_query', $result, $args ); } catch ( Exception $e ) { wc_caught_exception( $e, __FUNCTION__, func_get_args() ); return 0; } } /** * Count how many times a specific product was added to wishlist * * @param int $product_id Product id. * @return int Count of times product was added to cart */ public static function get_times_added_count( $product_id ) { try { $result = WC_Data_Store::load( 'wishlist-item' )->count_times_added( $product_id ); /** * APPLY_FILTERS: yith_wcwl_wishlist_times_added_count_query * * Filter the result of the query to get how many times a product has been added to a wishlist. * * @param int $result Query results * @param int $product_id Product ID * * @return int */ return (int) apply_filters( 'yith_wcwl_wishlist_times_added_count_query', $result, $product_id ); } catch ( Exception $e ) { wc_caught_exception( $e, __FUNCTION__, func_get_args() ); return 0; } } /** * Count how many times a specific product was added to wishlist by the current user * * @param int $product_id Product id. * @return int Count of times product was added to cart */ public static function get_times_current_user_added_count( $product_id ) { try { $result = WC_Data_Store::load( 'wishlist-item' )->count_times_added( $product_id, 'current' ); /** * APPLY_FILTERS: yith_wcwl_wishlist_times_current_user_added_count_query * * Filter the result of the query to get how many times a product has been added to a wishlist by the current user. * * @param int $result Query results * @param int $product_id Product ID * * @return int */ return (int) apply_filters( 'yith_wcwl_wishlist_times_current_user_added_count_query', $result, $product_id ); } catch ( Exception $e ) { wc_caught_exception( $e, __FUNCTION__, func_get_args() ); return 0; } } } } includes/class-yith-wcwl-cron.php 0000777 00000003577 15251156646 0013112 0 ustar 00 <?php /** * Wishlist Cron Handler * * @package YITH\Wishlist\Classes * @author YITH <plugins@yithemes.com> * @version 3.0.0 */ defined( 'YITH_WCWL' ) || exit; // Exit if accessed directly if ( ! class_exists( 'YITH_WCWL_Cron' ) ) { /** * This class handles cron for wishlist plugin * * @since 3.0.0 */ class YITH_WCWL_Cron { use YITH_WCWL_Extensible_Singleton_Trait; /** * Array of events to schedule * * @var array */ protected $crons = array(); /** * Constructor * * @return void */ public function __construct() { add_action( 'init', array( $this, 'schedule' ) ); } /** * Returns registered crons * * @return array Array of registered crons ans callbacks */ public function get_crons() { if ( empty( $this->crons ) ) { $this->crons = array( 'yith_wcwl_delete_expired_wishlists' => array( 'schedule' => 'daily', 'callback' => array( $this, 'delete_expired_wishlists' ), ), ); } /** * APPLY_FILTERS: yith_wcwl_crons * * Filter the cron tasks created in the plugin. * * @param array $crons Plugin crons * * @return array */ return apply_filters( 'yith_wcwl_crons', $this->crons ); } /** * Schedule events not scheduled yet; register callbacks for each event * * @return void */ public function schedule() { $crons = $this->get_crons(); if ( ! empty( $crons ) ) { foreach ( $crons as $hook => $data ) { add_action( $hook, $data['callback'] ); if ( ! wp_next_scheduled( $hook ) ) { wp_schedule_event( time() + MINUTE_IN_SECONDS, $data['schedule'], $hook ); } } } } /** * Delete expired session wishlist * * @return void */ public function delete_expired_wishlists() { try { WC_Data_Store::load( 'wishlist' )->delete_expired(); } catch ( Exception $e ) { return; } } } } includes/class-yith-wcwl.php 0000777 00000030475 15251156646 0012150 0 ustar 00 <?php /** * Main class * * @package YITH\Wishlist\Classes * @author YITH <plugins@yithemes.com> * @version 3.0.0 */ defined( 'YITH_WCWL' ) || exit; // Exit if accessed directly if ( ! class_exists( 'YITH_WCWL' ) ) { /** * WooCommerce Wishlist * * @since 1.0.0 */ class YITH_WCWL extends YITH_WCWL_Legacy { use YITH_WCWL_Extensible_Singleton_Trait; /** * Admin class * * @var YITH_WCWL_Admin */ protected $wcwl_admin; /** * Frontend class * * @var YITH_WCWL_Frontend */ protected $wcwl_frontend; /** * Cron class * * @var YITH_WCWL_Cron */ protected $wcwl_cron; /** * Session class * * @var YITH_WCWL_Session */ protected $wcwl_session; /** * Emails * * @var array */ public $emails = array(); /** * Last operation token * * @since 2.0.0 * @var string */ public $last_operation_token; /** * Query string parameter used to generate Wishlist urls * * @since 2.1.2 * @var string */ public $wishlist_param = 'wishlist-action'; /** * Constructor. * * @since 1.0.0 */ public function __construct() { parent::__construct(); // register data stores. add_filter( 'woocommerce_data_stores', array( $this, 'register_data_stores' ) ); // init frontend class. $this->wcwl_frontend = YITH_WCWL_Frontend::get_instance(); // init crons. $this->wcwl_cron = YITH_WCWL_Cron::get_instance(); // init session. $this->wcwl_session = YITH_WCWL_Session::get_instance(); // init admin handling. if ( is_admin() ) { $this->wcwl_admin = YITH_WCWL_Admin::get_instance(); } YITH_WCWL_Install::get_instance(); YITH_WCWL_Rest_Server::get_instance(); // load plugin-fw. add_action( 'plugins_loaded', array( $this, 'privacy_loader' ), 20 ); // add rewrite rule. add_action( 'init', array( $this, 'add_rewrite_rules' ), 0 ); add_filter( 'query_vars', array( $this, 'add_public_query_var' ) ); // Polylang integration. add_filter( 'pll_translation_url', array( $this, 'get_pll_wishlist_url' ), 10, 1 ); add_action( 'before_woocommerce_init', array( $this, 'declare_wc_features_support' ) ); } /* === PRIVACY LOADER === */ /** * Loads privacy class * * @return void * @since 2.0.0 */ public function privacy_loader() { if ( class_exists( 'YITH_Privacy_Plugin_Abstract' ) ) { require_once YITH_WCWL_INC . 'class-yith-wcwl-privacy.php'; new YITH_WCWL_Privacy(); } } /* === GENERAL METHODS === */ /** * Checks whether current user can add to the wishlist * * TODO: merge this into \YITH_WCWL_Wishlist::current_user_can * * @param int|bool $user_id User id to test; false to use current user id. * @return bool Whether current user can add to wishlist * @since 3.0.0 */ public function can_user_add_to_wishlist( $user_id = false ) { $user_id = $user_id ? $user_id : get_current_user_id(); $disable_wishlist_for_unauthenticated_users = get_option( 'yith_wcwl_disable_wishlist_for_unauthenticated_users' ); $return = true; if ( 'yes' === $disable_wishlist_for_unauthenticated_users && ! $user_id ) { $return = false; } /** * APPLY_FILTERS: yith_wcwl_can_user_add_to_wishlist * * Filter whether the current user can add products to the wishlist. * * @param bool $can_add_to_wishlist Whether the product is already in the wishlist * @param int $user_id User ID * * @return bool */ return apply_filters( 'yith_wcwl_can_user_add_to_wishlist', $return, $user_id ); } /** * Register custom plugin Data Stores classes * * @param array $data_stores Array of registered data stores. * @return array Array of filtered data store */ public function register_data_stores( $data_stores ) { $data_stores[ 'wishlist' ] = 'YITH_WCWL_Wishlist_Data_Store'; $data_stores[ 'wishlist-item' ] = 'YITH_WCWL_Wishlist_Item_Data_Store'; return $data_stores; } /** * Add rewrite rules for wishlist * * @return void * @since 2.0.0 */ public function add_rewrite_rules() { global $wp_query; // filter wishlist param. /** * APPLY_FILTERS: yith_wcwl_wishlist_param * * Filter the wishlist param. * * @param string $wishlist_param Wishlist param * * @return string */ $this->wishlist_param = apply_filters( 'yith_wcwl_wishlist_param', $this->wishlist_param ); $wishlist_page_id = get_option( 'yith_wcwl_wishlist_page_id' ); $wishlist_page_id = yith_wcwl_object_id( $wishlist_page_id, 'page', true, 'default' ); if ( empty( $wishlist_page_id ) ) { return; } $wishlist_page = get_post( $wishlist_page_id ); $wishlist_page_slug = $wishlist_page ? $wishlist_page->post_name : false; if ( empty( $wishlist_page_slug ) ) { return; } if ( defined( 'POLYLANG_VERSION' ) || defined( 'ICL_PLUGIN_PATH' ) ) { return; } $regex_paged = '((?!wp-json/.*)([^/]+/)*' . urldecode( $wishlist_page_slug ) . ')(/(.*))?/page/([0-9]{1,})/?$'; $regex_simple = '((?!wp-json/.*)([^/]+/)*' . urldecode( $wishlist_page_slug ) . ')(/(.*))?/?$'; add_rewrite_rule( $regex_paged, 'index.php?pagename=$matches[1]&' . $this->wishlist_param . '=$matches[4]&paged=$matches[5]', 'top' ); add_rewrite_rule( $regex_simple, 'index.php?pagename=$matches[1]&' . $this->wishlist_param . '=$matches[4]', 'top' ); $rewrite_rules = get_option( 'rewrite_rules' ); if ( ! is_array( $rewrite_rules ) || ! array_key_exists( $regex_paged, $rewrite_rules ) || ! array_key_exists( $regex_simple, $rewrite_rules ) ) { flush_rewrite_rules(); } } /** * Adds public query var for wishlist * * @param array $public_var Array of available query vars. * @return array * @since 2.0.0 */ public function add_public_query_var( $public_var ) { $public_var[] = $this->wishlist_param; $public_var[] = 'wishlist_id'; return $public_var; } /** * Return wishlist page id, if any * * @return int Wishlist page id. */ public function get_wishlist_page_id() { $wishlist_page_id = get_option( 'yith_wcwl_wishlist_page_id' ); $wishlist_page_id = yith_wcwl_object_id( $wishlist_page_id ); /** * APPLY_FILTERS: yith_wcwl_wishlist_page_id * * Filter the wishlist page ID. * * @param int $wishlist_page_id Wishlist page ID * * @return int */ return (int) apply_filters( 'yith_wcwl_wishlist_page_id', $wishlist_page_id ); } /** * Build wishlist page URL. * * @param string $action Action string to use in the url. * * @return string * @since 1.0.0 */ public function get_wishlist_url( $action = '' ) { global $sitepress; $wishlist_page_id = $this->get_wishlist_page_id(); $wishlist_permalink = get_the_permalink( $wishlist_page_id ); $action_params = explode( '/', $action ); $view = $action_params[ 0 ]; $data = isset( $action_params[ 1 ] ) ? $action_params[ 1 ] : ''; if ( 'view' === $action && empty( $data ) ) { return $wishlist_permalink; } if ( get_option( 'permalink_structure' ) && ! defined( 'ICL_PLUGIN_PATH' ) && ! defined( 'POLYLANG_VERSION' ) ) { $wishlist_permalink = trailingslashit( $wishlist_permalink ); $base_url = trailingslashit( $wishlist_permalink . $action ); } else { $base_url = $wishlist_permalink; $params = array(); if ( ! empty( $data ) ) { $params[ $this->wishlist_param ] = $view; if ( 'view' === $view ) { $params[ 'wishlist_id' ] = $data; } elseif ( 'user' === $view ) { $params[ 'user_id' ] = $data; } } else { $params[ $this->wishlist_param ] = $view; } $base_url = add_query_arg( $params, $base_url ); } if ( defined( 'ICL_PLUGIN_PATH' ) && $sitepress->get_current_language() !== $sitepress->get_default_language() ) { $base_url = add_query_arg( 'lang', $sitepress->get_current_language(), $base_url ); } /** * APPLY_FILTERS: yith_wcwl_wishlist_page_url * * Filter the wishlist page URL. * * @param string $wishlist_page_url Wishlist page URL * @param string $action Action * * @return string */ return apply_filters( 'yith_wcwl_wishlist_page_url', esc_url_raw( $base_url ), $action ); } /** * Retrieve url for the wishlist that was affected by last operation * * @return string Url to view last operation wishlist */ public function get_last_operation_url() { $action = 'view'; if ( ! empty( $this->last_operation_token ) ) { $action .= "/{$this->last_operation_token}"; } return $this->get_wishlist_url( $action ); } /** * Generates Add to Wishlist url, to use when customer do not have js enabled * * @param int $product_id Product id to add to wishlist. * @param array $args Any of the following parameters * [ * 'base_url' => '' * 'wishlist_id' => 0, * 'quantity' => 1, * 'user_id' => false, * 'dateadded' => '', * 'wishlist_name' => '', * 'wishlist_visibility' => 0 * ]. * @return string Add to wishlist url */ public function get_add_to_wishlist_url( $product_id, $args = array() ) { $args = array_merge( array( 'add_to_wishlist' => $product_id, ), $args ); if ( isset( $args[ 'base_url' ] ) ) { $base_url = $args[ 'base_url' ]; unset( $args[ 'base_url' ] ); $url = add_query_arg( $args, $base_url ); } else { $url = add_query_arg( $args ); } /** * APPLY_FILTERS: yith_wcwl_add_to_wishlist_url * * Filter the URL to add products to the wishlist. * * @param string $url URL to add to wishlist * @param int $product_id Product ID * @param array $args Array of parameters * * @return string */ return apply_filters( 'yith_wcwl_add_to_wishlist_url', esc_url_raw( wp_nonce_url( $url, 'add_to_wishlist' ) ), $product_id, $args ); } /** * Build the URL used to remove an item from the wishlist. * * @param int $item_id Id of the item to remove. * @return string * @since 1.0.0 */ public function get_remove_url( $item_id ) { return esc_url( wp_nonce_url( add_query_arg( 'remove_from_wishlist', $item_id ), 'remove_from_wishlist' ) ); } /** * Returns available views for wishlist page * * @return string[] * @since 3.0.0 */ public function get_available_views() { /** * APPLY_FILTERS: yith_wcwl_available_wishlist_views * * Filter the available views in the wishlist page. * * @param array $views Available views * * @return array */ $available_views = apply_filters( 'yith_wcwl_available_wishlist_views', array( 'view', 'user' ) ); return $available_views; } /* === POLYLANG INTEGRATION === */ /** * Filters translation url for the wishlist page, when PolyLang is enabled * * @param string $url Translation url. * @return string Filtered translation url for current page/post. */ public function get_pll_wishlist_url( $url ) { // phpcs:disable WordPress.Security.NonceVerification.Recommended if ( yith_wcwl_is_wishlist_page() && isset( $_GET[ $this->wishlist_param ] ) ) { $wishlist_action = sanitize_text_field( wp_unslash( $_GET[ $this->wishlist_param ] ) ); $user_id = isset( $_GET[ 'user_id' ] ) ? sanitize_text_field( wp_unslash( $_GET[ 'user_id' ] ) ) : ''; $wishlist_id = isset( $_GET[ 'wishlist_id' ] ) ? sanitize_text_field( wp_unslash( $_GET[ 'wishlist_id' ] ) ) : ''; $params = array_filter( array( $this->wishlist_param => $wishlist_action, 'user_id' => $user_id, 'wishlist_id' => $wishlist_id, ) ); $url = add_query_arg( $params, $url ); } // phpcs:enable WordPress.Security.NonceVerification.Recommended return $url; } /** * Declare support for WooCommerce features. * * @since 3.22.0 */ public function declare_wc_features_support() { if ( class_exists( '\Automattic\WooCommerce\Utilities\FeaturesUtil' ) ) { \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'custom_order_tables', YITH_WCWL_INIT, true ); } } } } includes/functions-yith-wcwl.php 0000777 00000100505 15251156646 0013043 0 ustar 00 <?php /** * Functions file * * @package YITH\Wishlist\Functions * @author YITH <plugins@yithemes.com> * @version 3.0.0 */ if ( ! defined( 'YITH_WCWL' ) ) { exit; } // Exit if accessed directly /* === TESTER FUNCTIONS === */ if ( ! function_exists( 'yith_wcwl_is_wishlist' ) ) { /** * Check if we're printing wishlist shortcode * * @return bool * @since 2.0.0 */ function yith_wcwl_is_wishlist() { global $yith_wcwl_is_wishlist; return $yith_wcwl_is_wishlist; } } if ( ! function_exists( 'yith_wcwl_is_wishlist_page' ) ) { /** * Check if current page is wishlist * * @return bool * @since 2.0.13 */ function yith_wcwl_is_wishlist_page() { $wishlist_page_id = YITH_WCWL()->get_wishlist_page_id(); if ( ! $wishlist_page_id ) { return false; } /** * APPLY_FILTERS: yith_wcwl_is_wishlist_page * * Filter whether the current page is the wishlist page. * * @param bool $is_wishlist_page Whether current page is wishlist page or not * * @return bool */ return apply_filters( 'yith_wcwl_is_wishlist_page', is_page( $wishlist_page_id ) ); } } if ( ! function_exists( 'yith_wcwl_is_single' ) ) { /** * Returns true if it finds that you're printing a single product * Should return false in any loop (including the ones inside single product page) * * @return bool Whether you're currently on single product template * @since 3.0.0 */ function yith_wcwl_is_single() { /** * APPLY_FILTERS: yith_wcwl_is_single * * Filter whether the ATW button is being printed in a single product page. * * @param bool $is_product Whether current page is a product page or not * * @return bool */ return apply_filters( 'yith_wcwl_is_single', is_product() && ! in_array( wc_get_loop_prop( 'name' ), array( 'related', 'up-sells' ), true ) && ! wc_get_loop_prop( 'is_shortcode' ) ); } } if ( ! function_exists( 'yith_wcwl_is_mobile' ) ) { /** * Returns true if we're currently on mobile view * * @return bool Whether you're currently on mobile view * @since 3.0.0 */ function yith_wcwl_is_mobile() { global $yith_wcwl_is_mobile; /** * APPLY_FILTERS: yith_wcwl_is_wishlist_responsive * * Filter if is enabled the responsive layout. * * @param bool $is_wishlist_responsive Whether responsive layout is enabled or not * * @return bool */ return apply_filters( 'yith_wcwl_is_wishlist_responsive', true ) && ( wp_is_mobile() || $yith_wcwl_is_mobile ); } } /* === TEMPLATE FUNCTIONS === */ if ( ! function_exists( 'yith_wcwl_locate_template' ) ) { /** * Locate the templates and return the path of the file found * * @param string $path Path to locate. * @param array $var Unused. * * @return string * @since 1.0.0 */ function yith_wcwl_locate_template( $path, $var = null ) { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter, Universal.NamingConventions.NoReservedKeywordParameterNames.varFound $woocommerce_base = WC()->template_path(); $template_woocommerce_path = $woocommerce_base . $path; $template_path = '/' . $path; $plugin_path = YITH_WCWL_DIR . 'templates/' . $path; $located = locate_template( array( $template_woocommerce_path, // Search in <theme>/woocommerce/. $template_path, // Search in <theme>/. ) ); if ( ! $located && file_exists( $plugin_path ) ) { return apply_filters( 'yith_wcwl_locate_template', $plugin_path, $path ); } /** * APPLY_FILTERS: yith_wcwl_locate_template * * Filter the location of the templates. * * @param string $located Template found * @param string $path Template path * * @return string */ return apply_filters( 'yith_wcwl_locate_template', $located, $path ); } } if ( ! function_exists( 'yith_wcwl_get_template' ) ) { /** * Retrieve a template file. * * @param string $path Path to get. * @param mixed $var Variables to send to template. * @param bool $return Whether to return or print the template. * * @return string|void * @since 1.0.0 */ function yith_wcwl_get_template( $path, $var = null, $return = false ) { // phpcs:ignore Universal.NamingConventions.NoReservedKeywordParameterNames.varFound, Universal.NamingConventions.NoReservedKeywordParameterNames.returnFound $located = yith_wcwl_locate_template( $path, $var ); if ( $var && is_array( $var ) ) { $atts = $var; extract( $var ); // phpcs:ignore WordPress.PHP.DontExtract.extract_extract } if ( $return ) { ob_start(); } if (file_exists($located)) { // include file located. include $located; } if ( $return ) { return ob_get_clean(); } } } if ( ! function_exists( 'yith_wcwl_get_view' ) ) { /** * Retrieve a template file. * * @param string $path Path to get. * @param mixed $args the args to use in the view. * @param bool $return Whether to return or print the template. * * @return string|void * @since 1.0.0 */ function yith_wcwl_get_view( $path, $args = null, $return = false ) { $fullpath = strpos( $path, YITH_WCWL_VIEWS ) === 0 ? $path : YITH_WCWL_VIEWS . $path; if ( $args && is_array( $args ) ) { $atts = $args; extract( $args ); // phpcs:ignore WordPress.PHP.DontExtract.extract_extract } if ( $return ) { ob_start(); } file_exists( $fullpath ) && include $fullpath; if ( $return ) { return ob_get_clean(); } } } if ( ! function_exists( 'yith_wcwl_get_template_part' ) ) { /** * Search and include a template part * * @param string $template Template to include. * @param string $template_part Template part. * @param string $template_layout Template variation. * @param array $var Array of variables to be passed to template. * @param bool $return Whether to return template or print it. * * @return string|null */ function yith_wcwl_get_template_part( $template = '', $template_part = '', $template_layout = '', $var = array(), $return = false ) { // phpcs:ignore Universal.NamingConventions.NoReservedKeywordParameterNames.varFound, Universal.NamingConventions.NoReservedKeywordParameterNames.returnFound if ( ! empty( $template_part ) ) { $template_part = '-' . $template_part; } if ( ! empty( $template_layout ) ) { $template_layout = '-' . $template_layout; } /** * APPLY_FILTERS: yith_wcwl_template_part_hierarchy * * Filter the hierarchy structure of the plugin templates and templates parts. * * @param array $template_hierarchy Template hierarchy * @param string $template Template * @param string $template_part Template part * @param string $template_layout Template layout * @param array $var Array of data * * @return array */ $template_hierarchy = apply_filters( 'yith_wcwl_template_part_hierarchy', array_merge( ! yith_wcwl_is_mobile() ? array() : array( "wishlist-{$template}{$template_layout}{$template_part}-mobile.php", "wishlist-{$template}{$template_part}-mobile.php", ), array( "wishlist-{$template}{$template_layout}{$template_part}.php", "wishlist-{$template}{$template_part}.php", ) ), $template, $template_part, $template_layout, $var ); foreach ( $template_hierarchy as $filename ) { $located = yith_wcwl_locate_template( $filename ); if ( $located ) { return yith_wcwl_get_template( $filename, $var, $return ); } } } } if ( ! function_exists( 'yith_wcwl_get_icon' ) ) { /** * Get the SVG icon string * * @param string $icon The icon name. * @return false|string */ function yith_wcwl_get_icon( $icon ) { if ( 0 === strpos( $icon, '<svg' ) ) { return $icon; } $path = YITH_WCWL_ASSETS_ICONS . $icon . ( substr( $icon, -4 ) === '.svg' ? '' : '.svg' ); ob_start(); if ( file_exists( $path ) ) { include $path; } return ob_get_clean(); } } if ( ! function_exists( 'yith_wcwl_get_icon_url' ) ) { /** * Get the icon url * * @param string $icon The icon name. * @return string */ function yith_wcwl_get_icon_url( $icon ) { return YITH_WCWL_ASSETS_ICONS_URL . $icon . ( substr( $icon, -4 ) === '.svg' ? '' : '.svg' ); } } /* === COUNT FUNCTIONS === */ if ( ! function_exists( 'yith_wcwl_count_products' ) ) { /** * Retrieve the number of products in the wishlist. * * @param string|bool $wishlist_token Optional wishlist token. * * @return int * @since 1.0.0 */ function yith_wcwl_count_products( $wishlist_token = false ) { return yith_wcwl_wishlists()->count_items_in_wishlist( $wishlist_token ); } } if ( ! function_exists( 'yith_wcwl_count_all_products' ) ) { /** * Retrieve the number of products in all the wishlists. * * @return int * @since 2.0.13 */ function yith_wcwl_count_all_products() { return yith_wcwl_wishlists()->count_all_items(); } } if ( ! function_exists( 'yith_wcwl_count_add_to_wishlist' ) ) { /** * Count number of times a product was added to users wishlists * * @param int|bool $product_id Product id. * * @return int Number of times the product was added to wishlists * @since 2.0.13 */ function yith_wcwl_count_add_to_wishlist( $product_id = false ) { return yith_wcwl_wishlists()->count_add_to_wishlist( $product_id ); } } if ( ! function_exists( 'yith_wcwl_get_count_text' ) ) { /** * Returns the label that states how many users added a specific product to wishlist * * @param int|bool $product_id Product id or false, when you want to use global product as reference. * * @return string Label with count of items */ function yith_wcwl_get_count_text( $product_id = false ) { $count = yith_wcwl_count_add_to_wishlist( $product_id ); $current_user_count = $count ? YITH_WCWL_Wishlist_Factory::get_times_current_user_added_count( $product_id ) : 0; // if no user added to wishlist, return empty string. if ( ! $count ) { /** * APPLY_FILTERS: yith_wcwl_count_text_empty * * Filter the text shown when a product has not been added to any wishlist. * * @param string $text Text * @param int $product_id Product ID * * @return string */ return apply_filters( 'yith_wcwl_count_text_empty', '', $product_id ); } elseif ( ! $current_user_count ) { // translators: 1. Number of users. $count_text = sprintf( _n( '%d user', '%d users', $count, 'yith-woocommerce-wishlist' ), $count ); $text = _n( 'has this item in wishlist', 'have this item in wishlist', $count, 'yith-woocommerce-wishlist' ); } elseif ( $count === $current_user_count ) { $count_text = __( 'You\'re the first', 'yith-woocommerce-wishlist' ); $text = __( 'to add this item in wishlist', 'yith-woocommerce-wishlist' ); } else { $other_count = $count - $current_user_count; // translators: 1. Count of users when many, or "another" when only one. $count_text = sprintf( _n( 'You and %s user', 'You and %d users', $other_count, 'yith-woocommerce-wishlist' ), 1 === $other_count ? __( 'another', 'yith-woocommerce-wishlist' ) : $other_count ); // phpcs:ignore WordPress.WP.I18n.MismatchedPlaceholders $text = __( 'have this item in wishlist', 'yith-woocommerce-wishlist' ); } $label = sprintf( '<div class="count-add-to-wishlist"><span class="count">%s</span> %s</div>', $count_text, $text ); /** * APPLY_FILTERS: yith_wcwl_count_text * * Filter the text that states how many users added a specific product to wishlist. * * @param string $label Text * @param int $product_id Product ID * @param int $current_user_count Current user count * @param int $count Total count * * @return string */ return apply_filters( 'yith_wcwl_count_text', $label, $product_id, $current_user_count, $count ); } } /* === COOKIE FUNCTIONS === */ if ( ! function_exists( 'yith_wcwl_get_cookie_expiration' ) ) { /** * Returns default expiration for wishlist cookie * * @return int Number of seconds the cookie should last. */ function yith_wcwl_get_cookie_expiration() { /** * APPLY_FILTERS: yith_wcwl_cookie_expiration * * Filter the cookie expiration. * * @param int $cookie_expiration Cookie expiration * * @return int */ return intval( apply_filters( 'yith_wcwl_cookie_expiration', 60 * 60 * 24 * 30 ) ); } } if ( ! function_exists( 'yith_setcookie' ) ) { /** * Create a cookie. * * @param string $name Cookie name. * @param mixed $value Cookie value. * @param int $time Cookie expiration time. * @param bool $secure Whether cookie should be available to secured connection only. * @param bool $httponly Whether cookie should be available to HTTP request only (no js handling). * * @return bool * @since 1.0.0 */ function yith_setcookie( $name, $value = array(), $time = null, $secure = false, $httponly = false ) { /** * APPLY_FILTERS: yith_wcwl_set_cookie * * Filter whether to set the cookie. * * @param bool $set_cookie Whether to set cookie or not * * @return bool */ if ( ! apply_filters( 'yith_wcwl_set_cookie', true ) || empty( $name ) ) { return false; } $time = ! empty( $time ) ? $time : time() + yith_wcwl_get_cookie_expiration(); $value = wp_json_encode( stripslashes_deep( $value ) ); /** * APPLY_FILTERS: yith_wcwl_cookie_expiration_time * * Filter the cookie expiration time. * * @param int $time Cookie expiration time * * @return int */ $expiration = apply_filters( 'yith_wcwl_cookie_expiration_time', $time ); // Default 30 days. $_COOKIE[ $name ] = $value; wc_setcookie( $name, $value, $expiration, $secure, $httponly ); return true; } } if ( ! function_exists( 'yith_getcookie' ) ) { /** * Retrieve the value of a cookie. * * @param string $name Cookie name. * * @return mixed * @since 1.0.0 */ function yith_getcookie( $name ) { if ( isset( $_COOKIE[ $name ] ) ) { return json_decode( sanitize_text_field( wp_unslash( $_COOKIE[ $name ] ) ), true ); } return array(); } } if ( ! function_exists( 'yith_destroycookie' ) ) { /** * Destroy a cookie. * * @param string $name Cookie name. * * @return void * @since 1.0.0 */ function yith_destroycookie( $name ) { yith_setcookie( $name, array(), time() - 3600 ); } } /* === GET FUNCTIONS === */ if ( ! function_exists( 'yith_wcwl_get_hidden_products' ) ) { /** * Retrieves a list of hidden products, whatever WC version is running * * WC switched from meta _visibility to product_visibility taxonomy since version 3.0.0, * forcing a split handling (Thank you, WC!) * * @return array List of hidden product ids * @since 2.1.1 */ function yith_wcwl_get_hidden_products() { $hidden_products = get_transient( 'yith_wcwl_hidden_products' ); if ( false === $hidden_products ) { if ( version_compare( WC()->version, '3.0.0', '<' ) ) { // phpcs:disable WordPress.DB.SlowDBQuery.slow_db_query_meta_query $hidden_products = get_posts( array( 'post_type' => 'product', 'post_status' => 'publish', 'posts_per_page' => -1, 'fields' => 'ids', 'meta_query' => array( array( 'key' => '_visibility', 'value' => 'visible', ), ), ) ); // phpcs:enable WordPress.DB.SlowDBQuery.slow_db_query_meta_query } else { $hidden_products = wc_get_products( array( 'limit' => -1, 'status' => 'publish', 'return' => 'ids', 'visibility' => 'hidden', ) ); } /** * Array_filter was added to prevent errors when previous query returns for some reason just 0 index. * * @since 2.2.6 */ $hidden_products = array_filter( $hidden_products ); set_transient( 'yith_wcwl_hidden_products', $hidden_products, 30 * DAY_IN_SECONDS ); } /** * APPLY_FILTERS: yith_wcwl_hidden_products * * Filter the array of hidden products. * * @param array $hidden_products Hidden products * * @return array */ return apply_filters( 'yith_wcwl_hidden_products', $hidden_products ); } } if ( ! function_exists( 'yith_wcwl_get_wishlist' ) ) { /** * Retrieves wishlist by ID * * @param int|string|false $wishlist_id Wishlist ID or Wishlist Token, or false to retrieve the default one. * * @return \YITH_WCWL_Wishlist|bool Wishlist object; false on error */ function yith_wcwl_get_wishlist( $wishlist_id = false ) { return YITH_WCWL_Wishlist_Factory::get_wishlist( $wishlist_id ); } } if ( ! function_exists( 'yith_wcwl_get_plugin_icons' ) ) { /** * Return array of available icons * * @param string $none_label Label to use for none option. * @param string $custom_label Label to use for custom option. * * @return array Array of available icons, in class => name format * @deprecated since 4.0 due to new icons-pack usage */ function yith_wcwl_get_plugin_icons( $none_label = '', $custom_label = '' ) { wc_deprecated_function( 'yith_wcwl_get_plugin_icons', '4.0.0' ); $icons = json_decode( file_get_contents( YITH_WCWL_DIR . 'assets/js/admin/yith-wcwl-icons.json' ), true ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents $icons[ 'none' ] = $none_label ?: __( 'None', 'yith-woocommerce-wishlist' ); $icons[ 'custom' ] = $custom_label ?: __( 'Custom', 'yith-woocommerce-wishlist' ); /** * APPLY_FILTERS: yith_wcwl_plugin_icons * * Filter the icons used in the plugin. * * @param array $icons Icons * @param string $none_label Label to use for none option * @param string $custom_label Label to use for custom option * * @return array */ return apply_filters( 'yith_wcwl_plugin_icons', $icons, $none_label, $custom_label ); } } if ( ! function_exists( 'yith_wcwl_get_icons_list' ) ) { /** * Return array of available icons * * @param string|string[] $context The context of the icons you want. * * @return array Array of available icons, in class => name format */ function yith_wcwl_get_plugin_icons_list( $context = '' ) { static $icons = null; if ( is_null( $icons ) ) { $icons = include YITH_WCWL_DIR . '/plugin-options/icons-list.php'; foreach ( $icons as $icon => &$icon_details ) { if ( empty( $icon_details[ 'svg' ] ) ) { if ( ! empty( $icon_details[ 'path' ] ) && file_exists( $icon_details[ 'path' ] ) ) { ob_start(); include $icon_details[ 'path' ]; $icon_details[ 'svg' ] = ob_get_clean(); } else { $icon_details[ 'svg' ] = yith_wcwl_get_icon( $icon ); } } } } $list = $icons; if ( $context ) { $list = array_filter( $icons, function ( $icon ) use ( $context ) { return is_array( $context ) ? array_intersect( $context, $icon[ 'tags' ] ) : in_array( $context, $icon[ 'tags' ], true ); } ); } /** * APPLY_FILTERS: yith_wcwl_plugin_icons_list * * Filter the icons used in the plugin. * * @param array $list Icons * * @return array */ return apply_filters( 'yith_wcwl_plugin_icons_list', $list ); } } if ( ! function_exists( 'yith_wcwl_get_plugin_icons_options' ) ) { /** * Return array of options 'value' => 'label' of icons * * @param string|string[] $context The icon context. * @return array The array of icons options used in the plugin icons selectors */ function yith_wcwl_get_plugin_icons_options( $context = '' ) { $icons = yith_wcwl_get_plugin_icons_list( $context ); $icons_options = array_combine( array_keys( $icons ), array_column( $icons, 'label' ) ); /** * APPLY_FILTERS: yith_wcwl_plugin_icons_options * * Filter the icons options used in the icons selectors. * * @param array $icons_options The icons options. * * @return array */ return apply_filters( 'yith_wcwl_plugin_icons_options', $icons_options ); } } if ( ! function_exists( 'yith_wcwl_get_privacy_label' ) ) { /** * Returns privacy label * * @param int $privacy Privacy value. * @param bool|string $extended Either to show extended, simplified label or get only the extension. * * @return string Privacy label * @since 3.0.0 */ function yith_wcwl_get_privacy_label( $privacy, $extended = false ) { $extension = ''; switch ( $privacy ) { case 1: $privacy_label = 'shared'; $privacy_text = __( 'Shared', 'yith-woocommerce-wishlist' ); $extension = __( 'Only people with the link can view it', 'yith-woocommerce-wishlist' ); break; case 2: $privacy_label = 'private'; $privacy_text = __( 'Private', 'yith-woocommerce-wishlist' ); $extension = __( 'Only you can view it', 'yith-woocommerce-wishlist' ); break; default: $privacy_label = 'public'; $privacy_text = __( 'Public', 'yith-woocommerce-wishlist' ); $extension = __( 'Anybody can view it', 'yith-woocommerce-wishlist' ); break; } if ( $extended ) { if ( 'only_extension' === $extended ) { $privacy_text = $extension; } else { $privacy_text = '<b>' . $privacy_text . '</b> - ' . $extension; } } /** * APPLY_FILTERS: yith_wcwl_{$privacy_label}_wishlist_visibility * * Filter the privacy label for the wishlist privacy status. * * @param string $privacy_text Privacy text * @param bool $extended Whether to show extended or simplified label * @param int $privacy Privacy value * * @return string */ return apply_filters( "yith_wcwl_{$privacy_label}_wishlist_visibility", $privacy_text, $extended, $privacy ); } } if ( ! function_exists( 'yith_wcwl_get_privacy_value' ) ) { /** * Returns privacy numeric value * * @param string $privacy_label Privacy label. * * @return int Privacy value * @since 3.0.0 */ function yith_wcwl_get_privacy_value( $privacy_label ) { switch ( $privacy_label ) { case 'shared': $privacy_value = 1; break; case 'private': $privacy_value = 2; break; default: $privacy_value = 0; break; } /** * APPLY_FILTERS: yith_wcwl_privacy_value * * Filter the privacy value. * * @param int $privacy_value Privacy value * @param string $privacy_label Privacy label * * @return string */ return apply_filters( 'yith_wcwl_privacy_value', $privacy_value, $privacy_label ); } } if ( ! function_exists( 'yith_wcwl_get_current_url' ) ) { /** * Retrieves current url * * @return string Current url * @since 3.0.0 */ function yith_wcwl_get_current_url() { global $wp; /** * Returns empty string by default, to avoid problems with unexpected redirects * Added filter to change default behaviour, passing what we think is current page url * * @since 3.0.12 */ /** * APPLY_FILTERS: yith_wcwl_current_url * * Filter the current URL. * * @param string $current_url Current URL * @param string $url URL * * @return string */ return apply_filters( 'yith_wcwl_current_url', '', add_query_arg( $wp->query_vars, home_url( $wp->request ) ) ); } } /* === UTILITY FUNCTIONS === */ if ( ! function_exists( 'yith_wcwl_merge_in_array' ) ) { /** * Merges an array of items into a specific position of an array * * @param array $array Origin array. * @param array $element Elements to merge. * @param string $pivot Index to use as pivot. * @param string $position Where elements should be merged (before or after the pivot). * * @return array Result of the merge */ function yith_wcwl_merge_in_array( $array, $element, $pivot, $position = 'after' ) { // phpcs:ignore Universal.NamingConventions.NoReservedKeywordParameterNames.arrayFound // search for the pivot inside array. $pos = array_search( $pivot, array_keys( $array ), true ); if ( false === $pos ) { return $array; } // separate array into chunks. $i = 'after' === $position ? 1 : 0; $part_1 = array_slice( $array, 0, $pos + $i ); $part_2 = array_slice( $array, $pos + $i ); return array_merge( $part_1, $element, $part_2 ); } } if ( ! function_exists( 'yith_wcwl_maybe_format_field_array' ) ) { /** * Take a field structure from plugin saved data, and format it as required by WC to print fields * * @param array $field_structure Array of fields as saved on db. * * @return array Array of fields as required by WC */ function yith_wcwl_maybe_format_field_array( $field_structure ) { $fields = array(); if ( empty( $field_structure ) ) { return array(); } foreach ( $field_structure as $field ) { if ( isset( $field[ 'active' ] ) && 'yes' !== $field[ 'active' ] ) { continue; } if ( empty( $field[ 'label' ] ) ) { continue; } // format type. $field_id = sanitize_title_with_dashes( $field[ 'label' ] ); // format options, if needed. if ( ! empty( $field[ 'options' ] ) ) { $options = array(); $raw_options = explode( '|', $field[ 'options' ] ); if ( ! empty( $raw_options ) ) { foreach ( $raw_options as $raw_option ) { if ( strpos( $raw_option, '::' ) === false ) { continue; } list( $id, $value ) = explode( '::', $raw_option ); $options[ $id ] = $value; } } $field[ 'options' ] = $options; } // format class. $field[ 'class' ] = array( 'form-row-' . $field[ 'position' ] ); // format requires. $field[ 'required' ] = isset( $field[ 'required' ] ) && 'yes' === $field[ 'required' ]; // set custom attributes when field is required. if ( $field[ 'required' ] ) { $field[ 'custom_attributes' ] = array( 'required' => 'required', ); } // if type requires options, but no options was defined, skip field printing. if ( in_array( $field[ 'type' ], array( 'select', 'radio' ), true ) && empty( $field[ 'options' ] ) ) { continue; } $fields[ $field_id ] = $field; } return $fields; } } if ( ! function_exists( 'yith_wcwl_add_notice' ) ) { /** * Calls wc_add_notice, when it exists * * @param string $message Message to print. * @param string $notice_type Notice type (succcess|error|notice). * @param array $data Optional notice data. * * @since 3.0.10 */ function yith_wcwl_add_notice( $message, $notice_type = 'success', $data = array() ) { function_exists( 'wc_add_notice' ) && wc_add_notice( $message, $notice_type, $data ); } } if ( ! function_exists( 'yith_wcwl_object_id' ) ) { /** * Retrieve translated object id, if a translation plugin is active * * @param int $id Original object id. * @param string $type Object type. * @param bool $return_original Whether to return original object if no translation is found. * @param string $lang Language to use for translation (). * * @return int Translation id * @since 1.0.0 */ function yith_wcwl_object_id( $id, $type = 'page', $return_original = true, $lang = null ) { // process special value for $lang. if ( 'default' === $lang ) { if ( defined( 'ICL_SITEPRESS_VERSION' ) ) { // wpml default language. global $sitepress; $lang = $sitepress->get_default_language(); } elseif ( function_exists( 'pll_default_language' ) ) { // polylang default language. $lang = pll_default_language( 'locale' ); } else { // cannot determine default language. $lang = null; } } // Should work with WPML and PolyLang. $id = apply_filters( 'wpml_object_id', $id, $type, $return_original, $lang ); // Space for additional translations. /** * APPLY_FILTERS: yith_wcwl_object_id * * Filter the Wishlist object ID. * * @param int $id Object ID * @param string $type Object type * @param bool $return_original Whether to return original object if no translation is found * @param string $lang Language to use for translation * * @return int */ $id = apply_filters( 'yith_wcwl_object_id', $id, $type, $return_original, $lang ); return $id; } } if ( ! function_exists( 'yith_wcwl_kses_icon' ) ) { /** * Escape output of wishlist icon * * @param string $data Data to escape. * @return string Escaped data */ function yith_wcwl_kses_icon( $data ) { /** * APPLY_FILTERS: yith_wcwl_allowed_icon_html * * Filter the allowed HTML for the icons. * * @param array $allowed_icon_html Allowed HTML * * @return array */ $allowed_icon_html = apply_filters( 'yith_wcwl_allowed_icon_html', array( 'i' => array( 'class' => true, ), 'img' => array( 'src' => true, 'alt' => true, 'width' => true, 'height' => true, ), 'svg' => array( 'id' => true, 'class' => true, 'width' => true, 'height' => true, 'viewbox' => true, 'fill' => true, 'xmlns' => true, 'aria-hidden' => true, 'stroke' => true, 'stroke-width' => true, ), 'path' => array( 'd' => true, 'fill' => true, 'stroke' => true, 'clip-rule' => true, 'fill-rule' => true, 'stroke-linecap' => true, 'stroke-linejoin' => true, ), 'g' => array( 'clip-path' => true, ), 'clipPath' => array( 'id' => true, ), 'defs' => array(), 'rect' => array( 'id' => true, 'width' => true, 'height' => true, 'fill' => true, ), ) ); return wp_kses( $data, $allowed_icon_html ); } } if ( ! function_exists( 'yith_wcwl_get_feedback_duration' ) ) { /** * Get the feedback duration * * @return int */ function yith_wcwl_get_feedback_duration() { /** * APPLY_FILTERS: yith_wcwl_feedback_duration * * Filter the feedback duration time. * * @param int $duration The duration time. * * @return int */ return absint( apply_filters( 'yith_wcwl_feedback_duration', 3000 ) ); } } if ( ! function_exists( 'yith_wcwl_get_modal_colors_defaults' ) ) { /** * Get modal colors default values * * @return string[] */ function yith_wcwl_get_modal_colors_defaults() { return array( 'overlay' => '#0000004d', 'icon' => '#007565', 'primary_button' => '#007565', 'primary_button_hover' => '#007565', 'primary_button_text' => '#fff', 'primary_button_text_hover' => '#fff', 'secondary_button' => '#e8e8e8', 'secondary_button_hover' => '#d8d8d8', 'secondary_button_text' => '#777', 'secondary_button_text_hover' => '#777', ); } } /* === INSTANCE CLASS FUNCTIONS === */ if ( ! function_exists( 'yith_wcwl' ) ) { /** * Unique access to instance of YITH_WCWL class * * @return \YITH_WCWL|\YITH_WCWL_Extended|\YITH_WCWL_Premium * @since 2.0.0 */ function yith_wcwl() { return YITH_WCWL::get_instance(); } } if ( ! function_exists( 'yith_wcwl_install' ) ) { /** * Unique access to instance of YITH_WCWL_Install class * * @return \YITH_WCWL_Install * @since 2.0.0 */ function yith_wcwl_install() { return YITH_WCWL_Install::get_instance(); } } if ( ! function_exists( 'yith_wcwl_frontend' ) ) { /** * Unique access to instance of YITH_WCWL_Frontend class * * @return \YITH_WCWL_Frontend|\YITH_WCWL_Frontend_Extended|\YITH_WCWL_Frontend_Premium * @since 2.0.0 */ function yith_wcwl_frontend() { return YITH_WCWL_Frontend::get_instance(); } } if ( ! function_exists( 'yith_wcwl_admin' ) ) { /** * Unique access to instance of YITH_WCWL_Admin class * * @return YITH_WCWL_Admin|YITH_WCWL_Admin_Extended|YITH_WCWL_Admin_Premium * @since 2.0.0 */ function yith_wcwl_admin() { return YITH_WCWL_Admin::get_instance(); } } if ( ! function_exists( 'yith_wcwl_session' ) ) { /** * Unique access to instance of YITH_WCWL_Session class * * @return YITH_WCWL_Session */ function yith_wcwl_session() { return YITH_WCWL_Session::get_instance(); } } if ( ! function_exists( 'yith_wcwl_emails' ) ) { /** * Unique access to instance of YITH_WCWL_Emails class * * @return YITH_WCWL_Emails|YITH_WCWL_Emails_Premium|YITH_WCWL_Emails_Extended * @since 2.0.0 */ function yith_wcwl_emails() { return YITH_WCWL_Emails::get_instance(); } } if ( ! function_exists( 'yith_wcwl_cron' ) ) { /** * Unique access to instance of YITH_WCWL_Cron class * * @return \YITH_WCWL_Cron|YITH_WCWL_Cron_Extended|YITH_WCWL_Cron_Premium * @since 3.0.0 */ function yith_wcwl_cron() { return YITH_WCWL_Cron::get_instance(); } } if ( ! function_exists( 'yith_wcwl_wishlists' ) ) { /** * Unique access to instance of YITH_WCWL_Wishlists class * * @return YITH_WCWL_Wishlists|YITH_WCWL_Wishlists_Premium * @since 4.0.0 */ function yith_wcwl_wishlists() { return YITH_WCWL_Wishlists::get_instance(); } } /* === DEPRECATED FUNCTIONS === */ includes/abstract-yith-wcwl-db.php 0000777 00000010615 15251156646 0013223 0 ustar 00 <?php /** * Handle DB tables and actions * * @package YITH\Wishlist\Classes * @author YITH <plugins@yithemes.com> * @version 4.0 */ defined( 'YITH_WCWL' ) || exit; // Exit if accessed directly. if ( ! class_exists( 'YITH_WCWL_DB' ) ) { /** * Class YITH_WCWL_DB * * @abstract */ abstract class YITH_WCWL_DB { // Version and option name. const DB_VERSION = '4.0.0'; const DB_VERSION_OPTION = 'yith_wcwl_db_version'; // Table names. const WISHLIST_ITEMS_TABLE = 'yith_wcwl'; const WISHLISTS_TABLE = 'yith_wcwl_lists'; const WISHLIST_ITEM_META_TABLE = 'yith_wcwl_itemmeta'; /** * Check if DB needs to be updated, and do it if so */ static public function maybe_update() { if ( version_compare( self::get_current_version(), self::DB_VERSION, '<' ) ) { self::create_tables(); if ( self::has_tables() ) { update_option( self::DB_VERSION_OPTION, self::DB_VERSION ); } } } /** * Register custom tables in $wpdb global object */ static public function define_tables() { global $wpdb; $tables = array( 'yith_wcwl_items' => self::WISHLIST_ITEMS_TABLE, 'yith_wcwl_wishlists' => self::WISHLISTS_TABLE, 'yith_wcwl_itemmeta' => self::WISHLIST_ITEM_META_TABLE, ); foreach ( $tables as $name => $table ) { $wpdb->$name = $wpdb->prefix . $table; $wpdb->tables[] = $table; } // TODO: maybe deprecate these constants define( 'YITH_WCWL_ITEMS_TABLE', $wpdb->prefix . self::WISHLIST_ITEMS_TABLE ); define( 'YITH_WCWL_WISHLISTS_TABLE', $wpdb->prefix . self::WISHLISTS_TABLE ); } /** * Run SQL command to create (or update) tables. */ static private function create_tables() { global $wpdb; //$wpdb->hide_errors(); require_once ABSPATH . 'wp-admin/includes/upgrade.php'; $wishlist_items_table = $wpdb->prefix . self::WISHLIST_ITEMS_TABLE; $wishlists_table = $wpdb->prefix . self::WISHLISTS_TABLE; $wishlist_item_meta_table = $wpdb->prefix . self::WISHLIST_ITEM_META_TABLE; $collate = ''; // Used since the 4.0 Version, so it's used just for the new tables if ( method_exists( $wpdb, 'has_cap' ) && $wpdb->has_cap( 'collation' ) ) { $collate = $wpdb->get_charset_collate(); } $sql = "CREATE TABLE {$wishlists_table} ( ID BIGINT( 20 ) NOT NULL AUTO_INCREMENT, user_id BIGINT( 20 ) NULL DEFAULT NULL, session_id VARCHAR( 255 ) DEFAULT NULL, wishlist_slug VARCHAR( 200 ) NOT NULL, wishlist_name TEXT, wishlist_token VARCHAR( 64 ) NOT NULL UNIQUE, wishlist_privacy TINYINT( 1 ) NOT NULL DEFAULT 0, is_default TINYINT( 1 ) NOT NULL DEFAULT 0, dateadded timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, expiration timestamp NULL DEFAULT NULL, PRIMARY KEY ( ID ), KEY wishlist_slug ( wishlist_slug ) ) DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; CREATE TABLE {$wishlist_items_table} ( ID BIGINT( 20 ) NOT NULL AUTO_INCREMENT, prod_id BIGINT( 20 ) NOT NULL, quantity INT( 11 ) NOT NULL, user_id BIGINT( 20 ) NULL DEFAULT NULL, wishlist_id BIGINT( 20 ) NULL, position INT( 11 ) DEFAULT 0, original_price DECIMAL( 9,3 ) NULL DEFAULT NULL, original_currency CHAR( 3 ) NULL DEFAULT NULL, dateadded timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, on_sale tinyint NOT NULL DEFAULT 0, PRIMARY KEY ( ID ), KEY prod_id ( prod_id ) ) DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; CREATE TABLE {$wishlist_item_meta_table} ( meta_id BIGINT( 20 ) NOT NULL AUTO_INCREMENT, yith_wcwl_item_id BIGINT( 20 ) NOT NULL, meta_key varchar(255) NULL, meta_value longtext NULL, PRIMARY KEY ( meta_id ), KEY item_id ( yith_wcwl_item_id ), KEY meta_key ( meta_key ) ) $collate; "; dbDelta( $sql ); } /** * Get the DB version * * @return string */ static public function get_current_version() { return get_option( self::DB_VERSION_OPTION, '0.0.0' ); } /** * Check if all the plugin custom tables exists * * @return bool */ static public function has_tables() { global $wpdb; $tables_common_prefix = $wpdb->prefix . self::WISHLIST_ITEMS_TABLE; $number_of_tables = (int) $wpdb->query( $wpdb->prepare( 'SHOW TABLES LIKE %s', "{$tables_common_prefix}%" ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery return 3 === $number_of_tables; } } } includes/class-yith-wcwl-wishlist-item.php 0000777 00000046341 15251156646 0014747 0 ustar 00 <?php /** * Wishlist Item class * * @package YITH\Wishlist\Classes\Wishlists * @author YITH <plugins@yithemes.com> * @version 3.0.0 */ defined( 'YITH_WCWL' ) || exit; // Exit if accessed directly. if ( ! class_exists( 'YITH_WCWL_Wishlist_Item' ) ) { /** * This class describes Wishlist Item object, and it is meant to be created by YITH_WCWL_Wishlist class, via * get_items method * * @since 3.0.0 */ class YITH_WCWL_Wishlist_Item extends WC_Data implements ArrayAccess { /** * Item Data array * * @since 3.0.0 * @var array */ protected $data = array( 'wishlist_id' => 0, 'product_id' => 0, 'quantity' => 1, 'user_id' => 0, 'date_added' => '', 'position' => 0, 'original_price' => 0, 'original_currency' => '', 'on_sale' => 0, ); /** * Register product to avoid retrieving it more than once * * @var \WC_Product */ protected $product = null; /** * Register origin wishlist ID; * if item is moved to another wishlist, we can then clear origin wishlist cache * * @var int */ protected $origin_wishlist_id = 0; /** * Stores meta in cache for future reads. * A group must be set to to enable caching. * * @var string */ protected $cache_group = 'wishlist-items'; /** * Constructor. * * @param int|object|array $item ID to load from the DB, or YITH_WCWL_Wishlist_Item object. * @throws Exception When cannot loading correct Data Store object. */ public function __construct( $item = 0 ) { parent::__construct( $item ); if ( $item instanceof YITH_WCWL_Wishlist_Item ) { $this->set_id( $item->get_id() ); } elseif ( is_numeric( $item ) && $item > 0 ) { $this->set_id( $item ); } else { $this->set_object_read( true ); } $this->data_store = WC_Data_Store::load( 'wishlist-item' ); if ( $this->get_id() > 0 ) { $this->data_store->read( $this ); } if ( $this->get_object_read() ) { $this->origin_wishlist_id = $this->get_wishlist_id(); } } /* === GETTERS === */ /** * Get wishlist ID for current item * * @param string $context Context. * @return int Wishlist ID */ public function get_wishlist_id( $context = 'view' ) { return (int) $this->get_prop( 'wishlist_id', $context ); } /** * Get origin wishlist ID for current item * * @return int Wishlist ID */ public function get_origin_wishlist_id() { return (int) $this->origin_wishlist_id; } /** * Get origin product ID for current item (no WPML filtering) * * @param string $context Context. * * @return int Wishlist ID */ public function get_original_product_id( $context = 'view' ) { return (int) $this->get_prop( 'product_id', $context ); } /** * Get product ID for current item * * @param string $context Context. * @return int Product ID */ public function get_product_id( $context = 'view' ) { return yit_wpml_object_id( $this->get_original_product_id( $context ), 'product', true ); } /** * Return product object related to current item * * @param string $context Context. * @return \WC_Product Product */ public function get_product( $context = 'view' ) { if ( empty( $this->product ) ) { $product = wc_get_product( $this->get_product_id( $context ) ); if ( $product ) { $this->product = $product; } } return $this->product; } /** * Return price of the produce related to current item * * @param string $context Context. * @return float */ public function get_product_price( $context = 'view' ) { $product = $this->get_product( $context ); if ( ! $product ) { return 0; } switch ( $product->get_type() ) { case 'variable': /** * Product used is a variation; we can then retrieve minimum variation price * * @var $product \WC_Product_Variable */ return (float) $product->get_variation_price( 'min' ); default: $sale_price = $product->get_sale_price(); return $sale_price ? (float) $sale_price : (float) $product->get_price(); } } /** * Retrieve formatted price for current item * * @param string $context Context. * @return string Formatter price */ public function get_formatted_product_price( $context = 'view' ) { $product = $this->get_product( $context ); $base_price = $product->is_type( 'variable' ) ? $product->get_variation_regular_price( 'max' ) : $product->get_price(); if ( '' === $base_price ) { $formatted_price = ''; } elseif ( ! $base_price ) { /** * APPLY_FILTERS: yith_free_text * * Filter the text shown when a product in the wishlist has no price. * * @param string $text Text * @param WC_Product $product Product object * * @return string */ $formatted_price = apply_filters( 'yith_free_text', __( 'Free!', 'yith-woocommerce-wishlist' ), $product ); } else { $formatted_price = $product->get_price_html(); } /** * APPLY_FILTERS: yith_wcwl_item_formatted_price * * Filter the formatted price for a wishlist item. * * @param string $formatted_price Formatted price * @param string $base_price Base price * @param WC_Product $product Product object * * @return string */ return apply_filters( 'yith_wcwl_item_formatted_price', $formatted_price, $base_price, $product ); } /** * Return formatted product name * * @param string $context Context. * @return string Formatted name; empty string on failure */ public function get_formatted_product_name( $context = 'view' ) { $product = $this->get_product( $context ); if ( ! $product ) { return ''; } return $product->get_formatted_name(); } /** * Get quantity for current item * * @param string $context Context. * @return int Quantity */ public function get_quantity( $context = 'view' ) { /** * APPLY_FILTERS: yith_wcwl_min_item_quantity * * Filter the minimum wishlist item quantity. * * @param int Minimum quantity * * @return int */ $min_quantity = apply_filters( 'yith_wcwl_min_item_quantity', 1 ); $quantity = (int) $this->get_prop( 'quantity', $context ); return max( $min_quantity, $quantity ); } /** * Get user ID for current item * * @param string $context Context. * @return int User ID */ public function get_user_id( $context = 'view' ) { return (int) $this->get_prop( 'user_id', $context ); } /** * Get user for current item * * @param string $context Context. * @return \WP_User|bool User */ public function get_user( $context = 'view' ) { $user_id = (int) $this->get_prop( 'user_id', $context ); if ( ! $user_id ) { return false; } return get_user_by( 'id', $user_id ); } /** * Get wishlist date added * * @param string $context Context. * @return \WC_DateTime|string Wishlist date of creation */ public function get_date_added( $context = 'view' ) { $date_added = $this->get_prop( 'date_added', $context ); if ( $date_added && 'view' === $context ) { return $date_added->date_i18n( 'Y-m-d H:i:s' ); } else { return $date_added; } } /** * Get formatted wishlist date added * * @param string $format Date format (if empty, WP date format will be applied). * @return string Wishlist date of creation */ public function get_date_added_formatted( $format = '' ) { $date_added = $this->get_date_added( 'edit' ); if ( $date_added ) { $format = $format ? $format : get_option( 'date_format' ); return $date_added->date_i18n( $format ); } return ''; } /** * Get related wishlist * * @return YITH_WCWL_Wishlist|bool Wishlist object, or false on failure */ public function get_wishlist() { $wishlist_id = $this->get_wishlist_id(); if ( ! $wishlist_id ) { return false; } return YITH_WCWL_Wishlist_Factory::get_wishlist( $wishlist_id ); } /** * Get related wishlist slug * * @return string|bool Wishlist slug, or false on failure */ public function get_wishlist_slug() { $wishlist = $this->get_wishlist(); if ( ! $wishlist ) { return false; } return $wishlist->get_slug(); } /** * Get related wishlist name * * @return string|bool Wishlist name, or false on failure */ public function get_wishlist_name() { $wishlist = $this->get_wishlist(); if ( ! $wishlist ) { return false; } return $wishlist->get_name(); } /** * Get related wishlist token * * @return string|bool Wishlist token, or false on failure */ public function get_wishlist_token() { $wishlist = $this->get_wishlist(); if ( ! $wishlist ) { return false; } return $wishlist->get_token(); } /** * Return item position inside the list * * @param string $context Context. * @return int Position */ public function get_position( $context = 'view' ) { return (int) $this->get_prop( 'position', $context ); } /** * Return original price * * @param string $context Context. * @return string Original price */ public function get_original_price( $context = 'view' ) { $price = $this->get_prop( 'original_price', 'edit' ); if ( 'view' === $context ) { return wc_price( $price, array( 'currency' => $this->get_original_currency(), ) ); } return $price; } /** * Return original currency * * @param string $context Context. * @return string Original price */ public function get_original_currency( $context = 'view' ) { $currency = $this->get_prop( 'original_currency', 'edit' ); if ( 'view' === $context && ! $currency ) { $currency = get_woocommerce_currency(); } return $currency; } /** * Returns a formatted HTML template for the "Price variation" label * * @return string HTML for the template, or empty string if price variation is not applicable to current item */ public function get_price_variation() { $original_currency = $this->get_original_currency( 'edit' ); // if currency changed, makes no sense to make comparisons. if ( get_woocommerce_currency() !== $original_currency ) { return ''; } $original_price = $this->get_original_price( 'edit' ); // original price wasn't stored in the wishlist. if ( ! $original_price ) { return ''; } $product = $this->get_product(); $current_price = $this->get_product_price(); if ( ! $current_price || ! is_numeric( $current_price ) ) { return ''; } $difference = $original_price - $current_price; /** * APPLY_FILTERS: yith_wcwl_hide_price_increase * * Filter whether to show the price difference in the wishlist. * * @param bool $show_difference Whether to show price difference or not * @param WC_Product $product Product object * @param string $original_price Original price * @param string $original_currency Original currency * @param float $difference Price difference * * @return bool */ if ( $difference <= 0 && apply_filters( 'yith_wcwl_hide_price_increase', true, $product, $original_price, $original_currency, $difference ) ) { return ''; } $percentage_difference = -1 * round( $difference / $original_price * 100, 2 ); $class = $percentage_difference > 0 ? 'increase' : 'decrease'; /** * APPLY_FILTERS: yith_wcwl_price_variation_template * * Filter the HTML string to show the price difference in the wishlist. * * @param string $html HTML string * * @return string */ $template = apply_filters( 'yith_wcwl_price_variation_template', sprintf( '<small class="price-variation %s"><span class="variation-rate">%s</span><span class="old-price">%s</span></small>', $class, // translators: 1. % of reduction/increase in price. _x( 'Price is %1$s%%', 'Part of the template that shows price variation since addition to list; placeholder will be replaced with a percentage', 'yith-woocommerce-wishlist' ), // translators: 2: original product price. _x( '(Was %2$s when added in list)', 'Part of the template that shows price variation since addition to list; placeholder will be replaced with a price', 'yith-woocommerce-wishlist' ) ), $class, $percentage_difference, $original_price, $original_currency, $this ); $template = sprintf( $template, $percentage_difference, wc_price( $original_price, array( 'currency' => $original_currency ) ) ); return $template; } /** * Return state of on_sale flag * Important: this flag is used for email campaigns, and doesn't necessarily represent * current on_sale status for the product * Plugins checks every day to find on_sale products, and to schedule email sending * * @param string $context Context. * @return bool Whether product was on sale during last check that plugin performed */ public function is_on_sale( $context = 'view' ) { return (bool) $this->get_prop( 'on_sale', $context ); } /** * Returns url to remove item from wishlist * * @return string Remove url. */ public function get_remove_url() { $base_url = $this->get_wishlist()->get_url(); /** * APPLY_FILTERS: yith_wcwl_wishlist_item_remove_url * * Filter the URL to remove an item from the wishlist. * * @param string $url URL to remove item from the wishlist * * @return string */ return apply_filters( 'yith_wcwl_wishlist_item_remove_url', wp_nonce_url( add_query_arg( 'remove_from_wishlist', $this->get_product_id(), $base_url ), 'remove_from_wishlist' ), $this ); } /** * Get product availability class * * @param string $context Context of the operation. * @return string Availability class. */ public function get_stock_status( $context = 'view' ) { $product = $this->get_product( $context ); if ( ! $product ) { return false; } $availability = $product->get_availability(); $stock_status = isset( $availability['class'] ) ? $availability['class'] : false; return $stock_status; } /** * Checks whether product is purchasable or not * * @param string $context Context of the operation. * @return bool Whether product is purchasable or not */ public function is_purchasable( $context = 'view' ) { $product = $this->get_product( $context ); if ( ! $product ) { return false; } return $product->is_purchasable(); } /* === SETTERS === */ /** * Set wishlist ID for current item * * @param int $wishlist_id Wishlist ID. */ public function set_wishlist_id( $wishlist_id ) { $this->set_prop( 'wishlist_id', $wishlist_id ); $wishlist = yith_wcwl_get_wishlist( $wishlist_id ); if ( $wishlist && $this->get_user_id() !== $wishlist->get_user_id() ) { $this->set_user_id( $wishlist->get_user_id() ); } } /** * Set product ID for current item * * @param int $product_id Product ID. */ public function set_product_id( $product_id ) { $product_id = yith_wcwl_object_id( $product_id, 'product', true, 'default' ); if ( ! empty( $this->product ) ) { $this->product = null; } $this->set_prop( 'product_id', $product_id ); } /** * Set quantity for current item * * @param int $quantity Quantity. */ public function set_quantity( $quantity ) { $this->set_prop( 'quantity', $quantity ); } /** * Set user ID for current item * * @param int $user_id User ID. */ public function set_user_id( $user_id ) { $this->set_prop( 'user_id', $user_id ); } /** * Set date added for current item * * @param int $date_added Date added. */ public function set_date_added( $date_added ) { $this->set_date_prop( 'date_added', $date_added ); } /** * Set position in wishlist for current item * * @param int $position Position. */ public function set_position( $position ) { $this->set_prop( 'position', (int) $position ); } /** * Set original price * * @param double $original_price Price. */ public function set_original_price( $original_price ) { $this->set_prop( 'original_price', $original_price ); } /** * Set original currency * * @param string $original_currency Currency. */ public function set_original_currency( $original_currency ) { $this->set_prop( 'original_currency', $original_currency ); } /** * Set on sale value * * @param bool $on_sale Whether product was found as on sale. * @return void */ public function set_on_sale( $on_sale ) { if ( $this->get_object_read() && $on_sale && $this->is_on_sale() !== $on_sale ) { /** * DO_ACTION: yith_wcwl_item_is_on_sale * * Allows to fire some action when a wishlist item is set on sale. * * @param YITH_WCWL_Wishlist_Item $wishlist_item Wishlist item object */ do_action( 'yith_wcwl_item_is_on_sale', $this ); } $this->set_prop( 'on_sale', $on_sale ); } /* === ARRAY ACCESS METHODS === */ /** * OffsetSet for ArrayAccess. * * @param string $offset Offset. * @param mixed $value Value. */ #[\ReturnTypeWillChange] public function offsetSet( $offset, $value ) { $offset = $this->map_legacy_offsets( $offset ); if ( array_key_exists( $offset, $this->data ) ) { $setter = "set_$offset"; if ( is_callable( array( $this, $setter ) ) ) { $this->$setter( $value ); } } } /** * OffsetUnset for ArrayAccess. * * @param string $offset Offset. */ #[\ReturnTypeWillChange] public function offsetUnset( $offset ) { $offset = $this->map_legacy_offsets( $offset ); if ( array_key_exists( $offset, $this->data ) ) { unset( $this->data[ $offset ] ); } if ( array_key_exists( $offset, $this->changes ) ) { unset( $this->changes[ $offset ] ); } } /** * OffsetExists for ArrayAccess. * * @param string $offset Offset. * @return bool */ #[\ReturnTypeWillChange] public function offsetExists( $offset ) { $offset = $this->map_legacy_offsets( $offset ); $getter = "get_$offset"; if ( is_callable( array( $this, $getter ) ) ) { return true; } return false; } /** * OffsetGet for ArrayAccess. * * @param string $offset Offset. * @return mixed */ #[\ReturnTypeWillChange] public function offsetGet( $offset ) { $offset = $this->map_legacy_offsets( $offset ); $getter = "get_$offset"; if ( is_callable( array( $this, $getter ) ) ) { return $this->$getter(); } return null; } /** * Map legacy indexes to new properties, for ArrayAccess * * @param string $offset Offset to search. * @return string Mapped offset */ protected function map_legacy_offsets( $offset ) { $legacy_offset = $offset; if ( 'prod_id' === $offset ) { $offset = 'product_id'; } elseif ( 'dateadded' === $offset ) { $offset = 'date_added'; } /** * APPLY_FILTERS: yith_wcwl_wishlist_item_map_legacy_offsets * * Filter the wishlist item legacy offsets to index to new properties. * * @param string $offset Offset to search * @param string $legacy_offset Legacy offset * * @return string */ return apply_filters( 'yith_wcwl_wishlist_item_map_legacy_offsets', $offset, $legacy_offset ); } } } includes/data-stores/class-yith-wcwl-wishlist-data-store.php 0000777 00000122060 15251156646 0020273 0 ustar 00 <?php /** * Wishlist data store * * @author YITH <plugins@yithemes.com> * @package YITH\Wishlist\Classes\DataStores * @version 3.0.0 */ if ( ! defined( 'YITH_WCWL' ) ) { exit; } // Exit if accessed directly // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching if ( ! class_exists( 'YITH_WCWL_Wishlist_Data_Store' ) ) { /** * This class implements CRUD methods for wishlists * * @since 3.0.0 */ class YITH_WCWL_Wishlist_Data_Store { /** * Create a new wishlist and stores it on DB * * @param \YITH_WCWL_Wishlist $wishlist Wishlist to create. */ public function create( &$wishlist ) { global $wpdb; // set token if missing. if ( ! $wishlist->get_token() ) { $wishlist->set_token( $this->generate_token() ); } // set slug if missing. $wishlist_slug = $wishlist->get_slug(); if ( ! $wishlist_slug ) { $wishlist_slug = sanitize_title_with_dashes( $wishlist->get_name() ); $wishlist->set_slug( $wishlist_slug ); } // set date added if missing. if ( ! $wishlist->get_date_added() ) { $wishlist->set_date_added( gmdate( 'Y-m-d H:i:s' ) ); } // set default, if needed. if ( $this->should_be_default() ) { $wishlist->set_is_default( 1 ); } // set always at least an owner. if ( ! $wishlist->get_session_id() && ! $wishlist->get_user_id() ) { if ( is_user_logged_in() ) { $user_id = get_current_user_id(); /** * APPLY_FILTERS: yith_wcwl_add_wishlist_user_id * * Filter the user ID saved in the wishlist. * * @param int $user_id User ID * * @return int */ $wishlist->set_user_id( apply_filters( 'yith_wcwl_add_wishlist_user_id', $user_id ) ); } else { $session_id = YITH_WCWL_Session()->get_session_id(); /** * APPLY_FILTERS: yith_wcwl_add_wishlist_session_id * * Filter the session ID saved in the wishlist. * * @param string $session_id Session ID * * @return string */ $wishlist->set_session_id( apply_filters( 'yith_wcwl_add_wishlist_session_id', $session_id ) ); } } // avoid slug duplicate, adding -n to the end of the string. $wishlist->set_slug( $this->generate_slug( $wishlist_slug ) ); $columns = array( 'wishlist_privacy' => '%d', 'wishlist_name' => '%s', 'wishlist_slug' => '%s', 'wishlist_token' => '%s', 'is_default' => '%d', ); $values = array( /** * APPLY_FILTERS: yith_wcwl_add_wishlist_privacy * * Filter the wishlist privacy. * * @param int $privacy Wishlist privacy * * @return int */ apply_filters( 'yith_wcwl_add_wishlist_privacy', $wishlist->get_privacy() ), /** * APPLY_FILTERS: yith_wcwl_add_wishlist_name * * Filter the wishlist name. * * @param string $name Wishlist name * * @return string */ apply_filters( 'yith_wcwl_add_wishlist_name', $wishlist->get_name() ), /** * APPLY_FILTERS: yith_wcwl_add_wishlist_slug * * Filter the wishlist slug. * * @param string $slug Wishlist slug * * @return string */ apply_filters( 'yith_wcwl_add_wishlist_slug', $wishlist->get_slug() ), /** * APPLY_FILTERS: yith_wcwl_add_wishlist_token * * Filter the wishlist token. * * @param string $token Wishlist token * * @return string */ apply_filters( 'yith_wcwl_add_wishlist_token', $wishlist->get_token() ), /** * APPLY_FILTERS: yith_wcwl_add_wishlist_is_default * * Filter whether is the default wishlist. * * @param bool $bool Is default wishlist? * * @return bool */ apply_filters( 'yith_wcwl_add_wishlist_is_default', $wishlist->get_is_default() ), ); $session_id = $wishlist->get_session_id(); if ( $session_id ) { $columns['session_id'] = '%s'; $values[] = apply_filters( 'yith_wcwl_add_wishlist_session_id', $session_id ); } $user_id = $wishlist->get_user_id(); if ( $user_id ) { $columns['user_id'] = '%d'; $values[] = apply_filters( 'yith_wcwl_add_wishlist_user_id', $user_id ); } $date_added = $wishlist->get_date_added( 'edit' ); if ( $date_added ) { $columns['dateadded'] = 'FROM_UNIXTIME( %d )'; /** * APPLY_FILTERS: yith_wcwl_add_wishlist_date_added * * Filter the date when the wishlist was created. * * @param int $date_added Date when the wishlist was created (timestamp) * * @return int */ $values[] = apply_filters( 'yith_wcwl_add_wishlist_date_added', $date_added->getTimestamp() ); } $expiration = $wishlist->get_expiration( 'edit' ); if ( $expiration ) { $columns['expiration'] = 'FROM_UNIXTIME( %d )'; /** * APPLY_FILTERS: yith_wcwl_add_wishlist_expiration * * Filter the date when the wishlist will expire. * * @param int $expiration_date Date when the wishlist will expire (timestamp) * * @return int */ $values[] = apply_filters( 'yith_wcwl_add_wishlist_expiration', $expiration->getTimestamp() ); } // if session wishlist, set always an expiration. $session_expiration = YITH_WCWL_Session()->get_session_expiration(); if ( isset( $columns['session_id'] ) && ! $expiration && $session_expiration ) { $columns['expiration'] = 'FROM_UNIXTIME( %d )'; $values[] = apply_filters( 'yith_wcwl_add_wishlist_expiration', $session_expiration ); } $query_columns = implode( ', ', array_map( 'esc_sql', array_keys( $columns ) ) ); $query_values = implode( ', ', array_values( $columns ) ); $query = "INSERT INTO {$wpdb->yith_wcwl_wishlists} ( {$query_columns} ) VALUES ( {$query_values} ) "; do_action( 'yith_wcwl_before_create_wishlist_res_query', $query, $values ); $res = $wpdb->query( $wpdb->prepare( $query, $values ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared if ( $res ) { /** * APPLY_FILTERS: yith_wcwl_wishlist_correctly_created * * Filter the ID of the Wishlist created. * * @param int $id Wishlist ID * * @return int */ $id = apply_filters( 'yith_wcwl_wishlist_correctly_created', intval( $wpdb->insert_id ) ); $wishlist->set_id( $id ); $wishlist->apply_changes(); $this->clear_caches( $wishlist ); /** * DO_ACTION: yith_wcwl_new_wishlist * * Allows to fire some action when a new wishlist is created. * * @param int $wishlist_id Wishlist ID * @param YITH_WCWL_Wishlist $wishlist_data Wishlist object */ do_action( 'yith_wcwl_new_wishlist', $wishlist->get_id(), $wishlist ); } } /** * Read data from DB for a specific wishlist * * @param \YITH_WCWL_Wishlist $wishlist Wishlist object. * @throws Exception When cannot retrieve specified wishlist. */ public function read( &$wishlist ) { global $wpdb; $wishlist->set_defaults(); $id = $wishlist->get_id(); $token = $wishlist->get_token(); if ( ! $id && ! $token ) { throw new Exception( esc_html__( 'Invalid wishlist.', 'yith-woocommerce-wishlist' ) ); } $wishlist_data = $wishlist->get_id() ? wp_cache_get( 'wishlist-id-' . $wishlist->get_id(), 'wishlists' ) : wp_cache_get( 'wishlist-token-' . $wishlist->get_token(), 'wishlists' ); if ( ! $wishlist_data ) { // format query to retrieve wishlist. $query = false; if ( $id ) { $query = $wpdb->prepare( "SELECT * FROM {$wpdb->yith_wcwl_wishlists} WHERE ID = %d", $id ); } elseif ( $token ) { $query = $wpdb->prepare( "SELECT * FROM {$wpdb->yith_wcwl_wishlists} WHERE wishlist_token = %s", $token ); } // retrieve wishlist data. $wishlist_data = $wpdb->get_row( $query ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared wp_cache_set( 'wishlist-id-' . $wishlist->get_id(), $wishlist_data, 'wishlists' ); wp_cache_set( 'wishlist-token-' . $wishlist->get_token(), $wishlist_data, 'wishlists' ); } if ( ! $wishlist_data ) { throw new Exception( esc_html__( 'Invalid wishlist.', 'yith-woocommerce-wishlist' ) ); } // set wishlist props. $wishlist->set_props( array( 'id' => $wishlist_data->ID, 'privacy' => $wishlist_data->wishlist_privacy, 'user_id' => $wishlist_data->user_id, 'session_id' => isset( $wishlist_data->session_id ) ? $wishlist_data->session_id : '', 'name' => wc_clean( stripslashes( $wishlist_data->wishlist_name ) ), 'slug' => $wishlist_data->wishlist_slug, 'token' => $wishlist_data->wishlist_token, 'is_default' => $wishlist_data->is_default, 'date_added' => $wishlist_data->dateadded, 'expiration' => isset( $wishlist_data->expiration ) ? $wishlist_data->expiration : '', ) ); $wishlist->set_object_read( true ); } /** * Update wishlist data on DB * * @param \YITH_WCWL_Wishlist $wishlist Wishlist to save on db, with $changes property. */ public function update( &$wishlist ) { global $wpdb; if ( ! $wishlist->get_id() ) { return; } $data = $wishlist->get_data(); $changes = $wishlist->get_changes(); if ( array_intersect( array( 'user_id', 'session_id', 'slug', 'name', 'token', 'privacy', 'expiration', 'date_added', 'is_default' ), array_keys( $changes ) ) ) { $columns = array( 'wishlist_privacy' => '%d', 'wishlist_name' => '%s', 'wishlist_token' => '%s', 'is_default' => '%d', 'dateadded' => 'FROM_UNIXTIME( %d )', ); $values = array( $wishlist->get_privacy(), $wishlist->get_name(), $wishlist->get_token(), $wishlist->get_is_default(), $wishlist->get_date_added( 'edit' ) ? $wishlist->get_date_added( 'edit' )->getTimestamp() : time(), ); $session_id = $wishlist->get_session_id(); if ( $session_id ) { $columns['session_id'] = '%s'; /** * APPLY_FILTERS: yith_wcwl_update_wishlist_session_id * * Filter the session ID of the updated wishlist. * * @param string $session_id Session ID * * @return string */ $values[] = apply_filters( 'yith_wcwl_update_wishlist_session_id', $session_id ); } else { $columns['session_id'] = 'NULL'; } $user_id = $wishlist->get_user_id(); if ( $user_id ) { $columns['user_id'] = '%d'; /** * APPLY_FILTERS: yith_wcwl_update_wishlist_user_id * * Filter the user ID of the updated wishlist. * * @param int $user_id User ID * * @return int */ $values[] = apply_filters( 'yith_wcwl_update_wishlist_user_id', $user_id ); } else { $columns['user_id'] = 'NULL'; } $expiration = $wishlist->get_expiration( 'edit' ); if ( $expiration ) { $columns['expiration'] = 'FROM_UNIXTIME( %d )'; /** * APPLY_FILTERS: yith_wcwl_update_wishlist_expiration * * Filter the expiration date of the updated wishlist. * * @param int $expiration_date Date when the wishlist will expire (timestamp) * * @return int */ $values[] = apply_filters( 'yith_wcwl_update_wishlist_expiration', $expiration->getTimestamp() ); } else { $columns['expiration'] = 'NULL'; } $wishlist_slug = $wishlist->get_slug(); if ( isset( $changes['slug'] ) && $wishlist_slug !== $data['slug'] ) { $columns['wishlist_slug'] = '%s'; $values[] = $this->generate_slug( $wishlist_slug ); } $this->update_raw( $columns, $values, array( 'ID' => '%d' ), array( $wishlist->get_id() ) ); } $wishlist->apply_changes(); $this->clear_caches( $wishlist ); /** * DO_ACTION: yith_wcwl_update_wishlist * * Allows to fire some action when a wishlist is updated. * * @param int $wishlist_id Wishlist ID * @param YITH_WCWL_Wishlist $wishlist_data Wishlist object */ do_action( 'yith_wcwl_update_wishlist', $wishlist->get_id(), $wishlist ); } /** * Delete a wishlist from DB * * @param \YITH_WCWL_Wishlist $wishlist Wishlist to delete. */ public function delete( &$wishlist ) { global $wpdb; $id = $wishlist->get_id(); $is_default = $wishlist->is_default(); $user_id = $wishlist->get_user_id(); $session_id = $wishlist->get_session_id(); if ( ! $id ) { return; } /** * DO_ACTION: yith_wcwl_before_delete_wishlist * * Allows to fire some action before a wishlist is deleted. * * @param int $wishlist_id Wishlist ID */ do_action( 'yith_wcwl_before_delete_wishlist', $wishlist->get_id() ); $this->clear_caches( $wishlist ); // delete wishlist and all its items. $wpdb->delete( $wpdb->yith_wcwl_items, array( 'wishlist_id' => $id ) ); $wpdb->delete( $wpdb->yith_wcwl_wishlists, array( 'ID' => $id ) ); /** * DO_ACTION: yith_wcwl_delete_wishlist * * Allows to fire some action when a wishlist is deleted. * * @param int $wishlist_id Wishlist ID */ do_action( 'yith_wcwl_delete_wishlist', $wishlist->get_id() ); $wishlist->set_id( 0 ); /** * DO_ACTION: yith_wcwl_deleted_wishlist * * Allows to fire some action after a wishlist is deleted. * * @param int $id Wishlist ID */ do_action( 'yith_wcwl_deleted_wishlist', $id ); if ( $is_default && ( $user_id || $session_id ) ) { // retrieve other lists for the same user. $other_lists = $this->query( array_merge( array( 'orderby' => 'dateadded', 'order' => 'asc', ), $user_id ? array( 'user_id' => $user_id ) : array(), $session_id ? array( 'session_id' => $session_id ) : array() ) ); if ( ! empty( $other_lists ) ) { $new_default = $other_lists[0]; $new_default->set_is_default( 1 ); $new_default->save(); } } } /** * Delete expired session wishlist from DB * * @return void */ public function delete_expired() { global $wpdb; $wpdb->query( "DELETE FROM {$wpdb->yith_wcwl_items} WHERE wishlist_id IN ( SELECT ID FROM {$wpdb->yith_wcwl_wishlists} WHERE expiration < NOW() and user_id IS NULL )" ); $wpdb->query( "DELETE FROM {$wpdb->yith_wcwl_wishlists} WHERE expiration < NOW() and user_id IS NULL" ); } /** * Query database to search * * @param array $args Array of parameters used for the query:<br/> * [<br/> * 'id' // Wishlist id<br/> * 'user_id' // User id<br/> * 'session_id' // Session id<br/> * 'wishlist_slug' // Wishlist slug, exact match<br/> * 'wishlist_name' // Wishlist name, like<br/> * 'wishlist_token' // Wishlist token, exact match<br/> * 'wishlist_visibility' // all, visible, public, shared, private<br/> * 'user_search' // String to search within user fields<br/> * 's' // String to search within wishlist fields<br/> * 'is_default' // Whether searched wishlist is default<br/> * 'orderby' // Any of the table columns<br/> * 'order' // ASC, DESC<br/> * 'limit' // Limit of items to retrieve<br/> * 'offset' // Offset of items to retrieve<br/> * 'show_empty' // Whether to show empty wishlists<br/> * ]. * * @return \YITH_WCWL_Wishlist[] Array of matched wishlists. */ public function query( $args = array() ) { global $wpdb; $default = array( 'id' => false, 'user_id' => ( is_user_logged_in() ) ? get_current_user_id() : false, 'session_id' => ( ! is_user_logged_in() ) ? YITH_WCWL_Session()->maybe_get_session_id() : false, 'wishlist_slug' => false, 'wishlist_name' => false, 'wishlist_token' => false, /** * APPLY_FILTERS: yith_wcwl_wishlist_visibility_string_value * * Filter the wishlist visibility value. * * @param string $wishlist_visibility Wishlist visibility. Possible values are: all | visible | public | shared | private * * @return string */ 'wishlist_visibility' => apply_filters( 'yith_wcwl_wishlist_visibility_string_value', 'all' ), // all | visible | public | shared | private. 'user_search' => false, 's' => false, 'is_default' => false, 'orderby' => '', 'order' => 'DESC', 'limit' => false, 'offset' => 0, 'show_empty' => true, ); // if there is no current wishlist, and user was asking for current one, short-circuit query, as pointless. if ( ! is_user_logged_in() && ! YITH_WCWL_Session()->has_session() && ! isset( $args['user_id'] ) && ! isset( $args['session_id'] ) ) { return array(); } $args = wp_parse_args( $args, $default ); extract( $args ); // phpcs:ignore WordPress.PHP.DontExtract $sql = 'SELECT SQL_CALC_FOUND_ROWS l.ID'; $sql .= " FROM `{$wpdb->yith_wcwl_wishlists}` AS l"; if ( ! empty( $user_search ) || ! empty( $s ) || ( ! empty( $orderby ) && 'user_login' === $orderby ) ) { $sql .= " LEFT JOIN `{$wpdb->users}` AS u ON l.`user_id` = u.ID"; } if ( ! empty( $user_search ) || ! empty( $s ) ) { $sql .= " LEFT JOIN `{$wpdb->usermeta}` AS umn ON umn.`user_id` = u.`ID`"; $sql .= " LEFT JOIN `{$wpdb->usermeta}` AS ums ON ums.`user_id` = u.`ID`"; } $sql .= ' WHERE 1'; $sql_args = array(); if ( ! empty( $user_id ) ) { $sql .= ' AND l.`user_id` = %d'; $sql_args[] = $user_id; } if ( ! empty( $session_id ) ) { $sql .= ' AND l.`session_id` = %s AND l.`expiration` > NOW()'; $sql_args[] = $session_id; } if ( ! empty( $user_search ) && empty( $s ) ) { $sql .= ' AND ( umn.`meta_key` = %s AND ums.`meta_key` = %s AND ( u.`user_email` LIKE %s OR umn.`meta_value` LIKE %s OR ums.`meta_value` LIKE %s ) )'; $search_value = '%' . esc_sql( $user_search ) . '%'; $sql_args[] = 'first_name'; $sql_args[] = 'last_name'; $sql_args[] = $search_value; $sql_args[] = $search_value; $sql_args[] = $search_value; } if ( ! empty( $s ) ) { $sql .= ' AND ( ( umn.`meta_key` = %s AND ums.`meta_key` = %s AND ( u.`user_email` LIKE %s OR u.`user_login` LIKE %s OR umn.`meta_value` LIKE %s OR ums.`meta_value` LIKE %s ) ) OR l.wishlist_name LIKE %s OR l.wishlist_slug LIKE %s OR l.wishlist_token LIKE %s )'; $search_value = '%' . esc_sql( $s ) . '%'; $sql_args[] = 'first_name'; $sql_args[] = 'last_name'; $sql_args[] = $search_value; $sql_args[] = $search_value; $sql_args[] = $search_value; $sql_args[] = $search_value; $sql_args[] = $search_value; $sql_args[] = $search_value; $sql_args[] = $search_value; } if ( ! empty( $is_default ) ) { $sql .= ' AND l.`is_default` = %d'; $sql_args[] = $is_default; } if ( ! empty( $id ) ) { $sql .= ' AND l.`ID` = %d'; $sql_args[] = $id; } if ( isset( $wishlist_slug ) && false !== $wishlist_slug ) { $sql .= ' AND l.`wishlist_slug` = %s'; $sql_args[] = sanitize_title_with_dashes( $wishlist_slug ); } if ( ! empty( $wishlist_token ) ) { $sql .= ' AND l.`wishlist_token` = %s'; $sql_args[] = $wishlist_token; } if ( ! empty( $wishlist_name ) ) { $sql .= ' AND l.`wishlist_name` LIKE %s'; $sql_args[] = '%' . esc_sql( $wishlist_name ) . '%'; } if ( isset( $wishlist_visibility ) && 'all' !== $wishlist_visibility ) { if ( ! is_int( $wishlist_visibility ) ) { $wishlist_visibility = yith_wcwl_get_privacy_value( $wishlist_visibility ); } $sql .= ' AND l.`wishlist_privacy` = %d'; $sql_args[] = $wishlist_visibility; } if ( empty( $show_empty ) ) { $sql .= " AND l.`ID` IN ( SELECT wishlist_id FROM {$wpdb->yith_wcwl_items} )"; } $sql .= ' GROUP BY l.ID'; $sql .= ' ORDER BY'; if ( ! empty( $orderby ) && isset( $order ) ) { $sql .= ' ' . esc_sql( $orderby ) . ' ' . esc_sql( $order ) . ', '; } $sql .= ' is_default DESC'; if ( ! empty( $limit ) && isset( $offset ) ) { $sql .= ' LIMIT %d, %d'; $sql_args[] = $offset; $sql_args[] = $limit; } if ( ! empty( $sql_args ) ) { $sql = $wpdb->prepare( $sql, $sql_args ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared } $lists = $wpdb->get_col( $sql ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared if ( ! empty( $lists ) ) { $lists = array_map( array( 'YITH_WCWL_Wishlist_Factory', 'get_wishlist' ), $lists ); } else { $lists = array(); } /** * APPLY_FILTERS: yith_wcwl_get_wishlists * * Filter the wishlists retrieved in the query. * * @param array $lists Array of wishlists * @param array $args Array of arguments * * @return array */ return apply_filters( 'yith_wcwl_get_wishlists', $lists, $args ); } /** * Counts items that matches * * @param array $args Same parameters allowed for {@see query} method. * @return int Count of items */ public function count( $args = array() ) { // retrieve number of items found. return count( $this->query( $args ) ); } /** * Search user ids whose wishlists match passed parameters * NOTE: this will only retrieve wishlists for a logged in user, while guests wishlist will be ignored * * @param mixed $args Array of valid arguments<br/> * [<br/> * 'search' // String to match against first name / last name / user login or user email of wishlist owner<br/> * 'limit' // Pagination param: number of items to show in one page. 0 to show all items<br/> * 'offset' // Pagination param: offset for the current set. 0 to start from the first item<br/> * ]. * @return int[] Array of user ids */ public function search_users( $args = array() ) { global $wpdb; $default = array( 'search' => false, 'limit' => false, 'offset' => 0, ); $args = wp_parse_args( $args, $default ); extract( $args ); // phpcs:ignore WordPress.PHP.DontExtract $sql = "SELECT DISTINCT i.user_id FROM {$wpdb->yith_wcwl_items} AS i LEFT JOIN {$wpdb->yith_wcwl_wishlists} AS l ON i.wishlist_id = l.ID"; if ( ! empty( $search ) ) { $sql .= " LEFT JOIN `{$wpdb->users}` AS u ON l.`user_id` = u.ID"; $sql .= " LEFT JOIN `{$wpdb->usermeta}` AS umn ON umn.`user_id` = u.`ID`"; $sql .= " LEFT JOIN `{$wpdb->usermeta}` AS ums ON ums.`user_id` = u.`ID`"; } $sql .= ' WHERE l.wishlist_privacy = %d'; $sql_args = array( 0 ); if ( ! empty( $search ) ) { $sql .= ' AND ( umn.`meta_key` = %s AND ums.`meta_key` = %s AND ( u.`user_email` LIKE %s OR u.`user_login` LIKE %s OR umn.`meta_value` LIKE %s OR ums.`meta_value` LIKE %s ) )'; $search_string = '%' . esc_sql( $search ) . '%'; $sql_args[] = 'first_name'; $sql_args[] = 'last_name'; $sql_args[] = $search_string; $sql_args[] = $search_string; $sql_args[] = $search_string; $sql_args[] = $search_string; } if ( ! empty( $limit ) && isset( $offset ) ) { $sql .= " LIMIT {$offset}, {$limit}"; } $res = $wpdb->get_col( $wpdb->prepare( $sql, $sql_args ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared return $res; } /** * Raw update method; useful when it is needed to update a bunch of wishlists * * @param array $columns Array of columns to update, in the following format: 'column_id' => 'column_type'. * @param array $column_values Array of values to apply to the query; must have same number of elements of columns, and they must respect defined tpe. * @param array $conditions Array of where conditions, in the following format: 'column_id' => 'columns_type'. * @param array $conditions_values Array of values to apply to where condition; must have same number of elements of columns, and they must respect defined tpe. * @param bool $clear_caches Whether to clear stored value before operation or not. * @pram $clear_caches bool Whether system should clear caches (this is optional since other methods may want to run more optimized clear) * * @return void */ public function update_raw( $columns, $column_values, $conditions = array(), $conditions_values = array(), $clear_caches = false ) { global $wpdb; // calculate where statement. $query_where = ''; if ( ! empty( $conditions ) ) { $query_where = array(); foreach ( $conditions as $column => $value ) { $query_where[] = $column . '=' . $value; } $query_where = ' WHERE ' . implode( ' AND ', $query_where ); } // retrieves wishlists that will be affected by the changes. if ( $clear_caches ) { $query = "SELECT ID FROM {$wpdb->yith_wcwl_wishlists} {$query_where}"; $query = $conditions ? $wpdb->prepare( $query, $conditions_values ) : $query; // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared $ids = $wpdb->get_col( $query ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared } // calculate set statement. $query_columns = array(); foreach ( $columns as $column => $value ) { $query_columns[] = $column . '=' . $value; } $query_columns = implode( ', ', $query_columns ); // build query, and execute it. $query = "UPDATE {$wpdb->yith_wcwl_wishlists} SET {$query_columns} {$query_where}"; $values = $conditions ? array_merge( $column_values, $conditions_values ) : $column_values; $wpdb->query( $wpdb->prepare( $query, $values ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared // clear cache for updated items. if ( $clear_caches && $ids ) { foreach ( $ids as $id ) { $this->clear_caches( $id ); } } } /** * Retrieve all items for the wishlist * * @param \YITH_WCWL_Wishlist $wishlist Wishlist object. * @return \YITH_WCWL_Wishlist_Item[] Array or Wishlist items for the wishlist */ public function read_items( $wishlist ) { global $wpdb; // Get from cache if available. $items = 0 < $wishlist->get_id() ? wp_cache_get( 'wishlist-items-' . $wishlist->get_id(), 'wishlists' ) : false; if ( false === $items ) { $query = "SELECT i.* FROM {$wpdb->yith_wcwl_items} as i INNER JOIN {$wpdb->posts} as p on i.prod_id = p.ID WHERE wishlist_id = %d AND p.post_type IN ( %s, %s ) AND p.post_status = %s"; // remove hidden products from result. $hidden_products = yith_wcwl_get_hidden_products(); /** * APPLY_FILTERS: yith_wcwl_remove_hidden_products_via_query * * Filter whether to remove hidden products via query. * * @param bool $bool Remove hidden products or not? * * @return bool */ if ( ! empty( $hidden_products ) && apply_filters( 'yith_wcwl_remove_hidden_products_via_query', true ) ) { $query .= ' AND prod_id NOT IN ( ' . implode( ', ', array_filter( $hidden_products, 'esc_sql' ) ) . ' )'; } // order by statement. /** * APPLY_FILTERS: yith_wcwl_wishlist_items_sorting * * Filter the order arguments for the query. * * @param array $args Array of order arguments * * @return array */ $orders = apply_filters( 'yith_wcwl_wishlist_items_sorting', array( 'position' => 'ASC', 'ID' => 'DESC', ) ); $orderby = implode( ', ', array_map( function ( $column, $sorting ) { return "$column $sorting"; }, array_keys( $orders ), $orders ) ); $query .= ' ORDER BY ' . esc_sql( $orderby ); $items = $wpdb->get_results( $wpdb->prepare( $query, // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared array( $wishlist->get_id(), 'product', 'product_variation', 'publish', ) ) ); /** * This filter was added to allow developer remove hidden products using a foreach loop, instead of the query * It is required when the store contains a huge number of hidden products, and the resulting query would fail * to be submitted to DBMS because of its size * * This code requires reasonable amount of products in the wishlist * A great number of products retrieved from the main query could easily degrade performance of the overall system * * @since 3.0.7 */ if ( ! empty( $hidden_products ) && ! empty( $items ) && ! apply_filters( 'yith_wcwl_remove_hidden_products_via_query', true ) ) { foreach ( $items as $item_id => $item ) { if ( ! in_array( $item->prod_id, $hidden_products, true ) ) { continue; } unset( $items[ $item_id ] ); } } foreach ( $items as $item ) { wp_cache_set( 'item-' . $item->ID, $item, 'wishlist-items' ); } if ( 0 < $wishlist->get_id() ) { wp_cache_set( 'wishlist-items-' . $wishlist->get_id(), $items, 'wishlists' ); } } if ( ! empty( $items ) ) { $items = array_map( array( 'YITH_WCWL_Wishlist_Factory', 'get_wishlist_item' ), array_combine( wp_list_pluck( $items, 'prod_id' ), $items ) ); } else { $items = array(); } /** * APPLY_FILTERS: yith_wcwl_get_products * * Filter the products retrieved from the wishlist. * * @param array $items Array of products * @param array $args Array of arguments * * @return array */ return apply_filters( 'yith_wcwl_get_products', $items, array( 'wishlist_id' => $wishlist->get_id() ) ); } /** * Delete all items from the wishist * * @param \YITH_WCWL_Wishlist $wishlist Wishlist object. * @return void */ public function delete_items( $wishlist ) { global $wpdb; $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->yith_wcwl_items} WHERE wishlist_id = %d", $wishlist->get_id() ) ); $this->clear_caches( $wishlist ); } /** * Generate default token for the wishlist * * @return string Wishlist token */ public function generate_token() { global $wpdb; $sql = "SELECT COUNT(*) FROM `{$wpdb->yith_wcwl_wishlists}` WHERE `wishlist_token` = %s"; do { $dictionary = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; $nchars = 12; $token = ''; for ( $i = 0; $i <= $nchars - 1; $i++ ) { $token .= $dictionary[ wp_rand( 0, strlen( $dictionary ) - 1 ) ]; } $count = $wpdb->get_var( $wpdb->prepare( $sql, $token ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared } while ( $count ); return $token; } /** * When a session is finalized, all session wishlists will be converted to user wishlists * This method takes also care of allowing just one default per time after finalization * * @param string $session_id Session id. * @param int $user_id User id. * * @return void */ public function assign_to_user( $session_id, $user_id ) { global $wpdb; // update any item that is assigned to the list. $items = $wpdb->get_col( $wpdb->prepare( "SELECT i.ID FROM {$wpdb->yith_wcwl_items} AS i LEFT JOIN {$wpdb->yith_wcwl_wishlists} AS l ON l.ID = i.wishlist_id WHERE l.session_id = %s", $session_id ) ); if ( ! empty( $items ) ) { $items_string = implode( ',', array_map( 'esc_sql', $items ) ); $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->yith_wcwl_items} SET user_id = %d WHERE ID IN ({$items_string})", $user_id ) ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared } // set user id for any session wishlist, and remove session data. $this->update_raw( array( 'session_id' => 'NULL', 'expiration' => 'NULL', 'user_id' => '%d', ), array( $user_id ), array( 'session_id' => '%s' ), array( $session_id ) ); // retrieves default wishlist ids. $default_ids = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM {$wpdb->yith_wcwl_wishlists} WHERE is_default = %d AND user_id = %d ORDER BY dateadded ASC", 1, $user_id ) ); // if we find more than one default list, fix data in db. if ( count( $default_ids ) > 1 ) { // search for master default wishlist. $master_default_wishlist = array_shift( $default_ids ); $where_statement = implode( ', ', array_map( 'esc_sql', $default_ids ) ); try { /** * APPLY_FILTERS: yith_wcwl_merge_default_wishlists * * Filter whether merge all default wishlists into the oldest one. * * @param bool $bool Merge all default wishlists or not? * * @return bool */ if ( apply_filters( 'yith_wcwl_merge_default_wishlists', true ) ) { // by default we merge all default wishlists into oldest one (master default wishlist). // change wishlist id to master default id. $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->yith_wcwl_items} SET wishlist_id = %d WHERE wishlist_id IN ({$where_statement})", $master_default_wishlist ) ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared // delete slave default wishlists. $wpdb->query( "DELETE FROM {$wpdb->yith_wcwl_wishlists} WHERE ID IN ({$where_statement})" ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared } else { // otherwise, we just leave all the wishlists as they are, but we remove default flag from latest. // remove default flag. $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->yith_wcwl_wishlists} SET is_default = %d WHERE ID IN ({$where_statement})", 0 ) ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared // set name where it is missing. /** * APPLY_FILTERS: yith_wcwl_default_wishlist_formatted_title * * Filter the default wishlist title. * * @param string $title Default wishlist title * * @return string */ $default_title = apply_filters( 'yith_wcwl_default_wishlist_formatted_title', get_option( 'yith_wcwl_wishlist_title', __( 'My wishlist', 'yith-woocommerce-wishlist' ) ) ); $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->yith_wcwl_wishlists} SET wishlist_name = %s WHERE ID IN ({$where_statement}) AND wishlist_name = ''", $default_title ) ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared } } catch ( Exception $e ) { return; } } } /** * Retrieve default wishlist for current user/session; if none is found, generate it * * @param string|int|bool $id Pass this param when you want to retrieve a wishlist for a specific user/session. * @param string $context Context; when on edit context, wishlist will be created, if not exists. * @return \YITH_WCWL_Wishlist|bool Default wishlist for current user/session, or false on failure */ public function get_default_wishlist( $id = false, $context = 'read' ) { global $wpdb; $wishlist_id = false; $cache_key = false; $user_id = get_current_user_id(); $session_id = YITH_WCWL_Session()->maybe_get_session_id(); if ( ! empty( $id ) && is_int( $id ) ) { $cache_key = 'wishlist-default-' . $id; $wishlist_id = wp_cache_get( $cache_key, 'wishlists' ); $wishlist_id = false !== $wishlist_id ? $wishlist_id : $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM {$wpdb->yith_wcwl_wishlists} WHERE user_id = %d AND is_default = 1", $id ) ); } elseif ( ! empty( $id ) && is_string( $id ) ) { $cache_key = 'wishlist-default-' . $id; $wishlist_id = wp_cache_get( $cache_key, 'wishlists' ); $wishlist_id = false !== $wishlist_id ? $wishlist_id : $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM {$wpdb->yith_wcwl_wishlists} WHERE session_id = %s AND expiration > NOW() AND is_default = 1", $id ) ); } elseif ( $user_id ) { $cache_key = 'wishlist-default-' . $user_id; $wishlist_id = wp_cache_get( $cache_key, 'wishlists' ); $wishlist_id = false !== $wishlist_id ? $wishlist_id : $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM {$wpdb->yith_wcwl_wishlists} WHERE user_id = %d AND is_default = 1", $user_id ) ); } elseif ( $session_id ) { $cache_key = 'wishlist-default-' . $session_id; $wishlist_id = wp_cache_get( $cache_key, 'wishlists' ); $wishlist_id = false !== $wishlist_id ? $wishlist_id : $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM {$wpdb->yith_wcwl_wishlists} WHERE session_id = %s AND expiration > NOW() AND is_default = 1", $session_id ) ); } if ( $wishlist_id ) { if ( $cache_key ) { wp_cache_set( $cache_key, $wishlist_id, 'wishlists' ); } return YITH_WCWL_Wishlist_Factory::get_wishlist( $wishlist_id ); } elseif ( 'edit' === $context ) { $wishlist = $this->generate_default_wishlist( $id ); if ( $cache_key ) { wp_cache_set( $cache_key, $wishlist->get_id(), 'wishlists' ); } return $wishlist; } else { /** * If no default wishlist was found, register null as cache value * This will be used until someone tries to edit the list (entering previous elseif), * causing a new default wishlist to be automatically generated and stored in cache, replacing null * * @since 3.0.6 */ if ( $cache_key ) { wp_cache_set( $cache_key, null, 'wishlists' ); } return false; } } /** * Generate a new default wishlist * * @param string|int|bool $id Pass this param when you want to create a wishlist for a specific user/session. * @return YITH_WCWL_Wishlist|bool Brand new default wishlist, or false on failure */ public function generate_default_wishlist( $id ) { try { $default_wishlist = new YITH_WCWL_Wishlist(); if ( ! empty( $id ) && is_int( $id ) ) { $default_wishlist->set_user_id( $id ); } elseif ( ! empty( $id ) && is_string( $id ) ) { $default_wishlist->set_session_id( $id ); } $default_wishlist->save(); /** * Let developers perform processing when default wishlist is created * * @since 3.0.10 */ /** * DO_ACTION: yith_wcwl_generated_default_wishlist * * Allows to fire some action when default wishlist is created. * * @param YITH_WCWL_Wishlist $default_wishlist Default wishlist object * @param int $id Wishlist ID */ do_action( 'yith_wcwl_generated_default_wishlist', $default_wishlist, $id ); } catch ( Exception $e ) { return false; } return $default_wishlist; } /** * Generate unique slug for the wishlisst * * @param string $slug Original slug assigned to the wishlist (it cuold be custom assigned, or generated from the title). * @return string Unique slug, derived from original one adding ordinal number when necessary */ public function generate_slug( $slug ) { if ( empty( $slug ) ) { return ''; } while ( $this->slug_exists( $slug ) ) { $match = array(); if ( ! preg_match( '/([a-z-]+)-([0-9]+)/', $slug, $match ) ) { $i = 2; } else { $i = intval( $match[2] ) + 1; $slug = $match[1]; } $suffix = '-' . $i; $slug = substr( $slug, 0, 200 - strlen( $suffix ) ) . $suffix; } return $slug; } /** * Checks if a slug already exists * * @param string $slug Slug to check on db. * * @return bool Whether slug already exists for current session or not */ public function slug_exists( $slug ) { global $wpdb; $res = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(ID) FROM {$wpdb->yith_wcwl_wishlists} WHERE wishlist_slug = %s", $slug ) ); return (bool) $res; } /** * Check if we're registering first wishlist for the user/session * * @return bool Whether current wishlist should be default */ protected function should_be_default() { global $wpdb; $user_id = get_current_user_id(); $customer_id = YITH_WCWL_Session()->maybe_get_session_id(); if ( $user_id ) { $wishlists = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT( ID ) FROM {$wpdb->yith_wcwl_wishlists} WHERE user_id = %d AND is_default = %d", $user_id, 1 ) ); return ! (bool) $wishlists; } if ( $customer_id ) { $wishlists = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT( ID ) FROM {$wpdb->yith_wcwl_wishlists} WHERE session_id = %s AND expiration > NOW() AND is_default = %d", $customer_id, 1 ) ); return ! (bool) $wishlists; } return true; } /** * Clear wishlist related caches * * @param \YITH_WCWL_Wishlist|int|string $wishlist Wishlist object. * @return void */ protected function clear_caches( &$wishlist ) { if ( $wishlist instanceof YITH_WCWL_Wishlist ) { $id = $wishlist->get_id(); $token = $wishlist->get_token(); } elseif ( intval( $wishlist ) ) { $id = $wishlist; $wishlist = yith_wcwl_get_wishlist( $wishlist ); $token = $wishlist ? $wishlist->get_token() : false; } else { $token = $wishlist; $wishlist = yith_wcwl_get_wishlist( $wishlist ); $id = $wishlist ? $wishlist->get_id() : false; } $user_id = $wishlist ? $wishlist->get_user_id() : false; $session_id = $wishlist ? $wishlist->get_session_id() : false; wp_cache_delete( 'wishlist-items-' . $id, 'wishlists' ); wp_cache_delete( 'wishlist-id-' . $id, 'wishlists' ); wp_cache_delete( 'wishlist-token-' . $token, 'wishlists' ); if ( $user_id ) { wp_cache_delete( 'user-wishlists-' . $user_id, 'wishlists' ); } if ( $session_id ) { wp_cache_delete( 'user-wishlists-' . $session_id, 'wishlists' ); } } } } // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching includes/data-stores/class-yith-wcwl-wishlist-item-data-store.php 0000777 00000064453 15251156646 0021242 0 ustar 00 <?php /** * Wishlist data store * * @package YITH\Wishlist\Classes\DataStores * @author YITH <plugins@yithemes.com> * @version 3.0.0 */ if ( ! defined( 'YITH_WCWL' ) ) { exit; } // Exit if accessed directly // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching if ( ! class_exists( 'YITH_WCWL_Wishlist_Item_Data_Store' ) ) { /** * This class implements CRUD methods for wishlists' items * * @since 3.0.0 */ class YITH_WCWL_Wishlist_Item_Data_Store extends WC_Data_Store_WP { protected $meta_type = 'yith_wcwl_item'; /** * Create a new wishlist item in the database. * * @param \YITH_WCWL_Wishlist_Item $item Wishlist item object. * @since 3.0.0 */ public function create( &$item ) { global $wpdb; $product_id = $item->get_original_product_id(); $wishlist_id = $item->get_wishlist_id(); if ( ! $product_id || ! $wishlist_id ) { return; } $item_id = YITH_WCWL_Wishlist_Factory::get_wishlist_item_by_product_id( $wishlist_id, $product_id ); if ( $item_id ) { $item->set_id( $item_id ); $this->update( $item ); return; } $columns = array( 'prod_id' => '%d', 'quantity' => '%d', 'wishlist_id' => '%d', 'position' => '%d', 'original_price' => '%f', 'original_currency' => '%s', 'on_sale' => '%d', ); $values = array( /** * APPLY_FILTERS: yith_wcwl_adding_to_wishlist_product_id * * Filter the ID of the product added to the wishlist. * * @param int $product_id Product ID * * @return int */ apply_filters( 'yith_wcwl_adding_to_wishlist_product_id', $product_id ), /** * APPLY_FILTERS: yith_wcwl_adding_to_wishlist_quantity * * Filter the quantity of the product added to the wishlist. * * @param int $quantity Product quantity * @param int $product_id Product ID * * @return int */ apply_filters( 'yith_wcwl_adding_to_wishlist_quantity', $item->get_quantity(), $product_id ), /** * APPLY_FILTERS: yith_wcwl_adding_to_wishlist_wishlist_id * * Filter the wishlist ID where the products are added to. * * @param int $wishlist_id Wishlist ID * * @return int */ apply_filters( 'yith_wcwl_adding_to_wishlist_wishlist_id', $wishlist_id ), /** * APPLY_FILTERS: yith_wcwl_adding_to_wishlist_position * * Filter the position where the product will be added to the wishlist. * * @param int $item_position Item position in the wishlist * * @return int */ apply_filters( 'yith_wcwl_adding_to_wishlist_position', $item->get_position() ), /** * APPLY_FILTERS: yith_wcwl_adding_to_wishlist_original_price * * Filter the price of the product added to the wishlist. * * @param int $product_price Product price * * @return int */ apply_filters( 'yith_wcwl_adding_to_wishlist_original_price', $item->get_product_price() ), /** * APPLY_FILTERS: yith_wcwl_adding_to_wishlist_original_currency * * Filter the currency of the product added to the wishlist. * * @param string $currency Currency * * @return string */ apply_filters( 'yith_wcwl_adding_to_wishlist_original_currency', $item->get_original_currency() ), /** * APPLY_FILTERS: yith_wcwl_adding_to_wishlist_on_sale * * Filter whether the product added to the wishlist is on sale. * * @param bool $bool Is the product on sale or not? * * @return bool */ apply_filters( 'yith_wcwl_adding_to_wishlist_on_sale', $item->is_on_sale() ), ); $user_id = $item->get_user_id(); if ( $user_id ) { $columns['user_id'] = '%d'; /** * APPLY_FILTERS: yith_wcwl_adding_to_wishlist_user_id * * Filter the user ID saved in the wishlist. * * @param int $user_id User ID * * @return int */ $values[] = apply_filters( 'yith_wcwl_adding_to_wishlist_user_id', $user_id ); } $date_added = $item->get_date_added( 'edit' ); if ( $date_added ) { $columns['dateadded'] = 'FROM_UNIXTIME( %d )'; /** * APPLY_FILTERS: yith_wcwl_adding_to_wishlist_date_added * * Filter the date when the wishlist was created. * * @param int $date_added Date when the wishlist was created (timestamp) * * @return int */ $values[] = apply_filters( 'yith_wcwl_adding_to_wishlist_date_added', $date_added->getTimestamp() ); } $query_columns = implode( ', ', array_map( 'esc_sql', array_keys( $columns ) ) ); $query_values = implode( ', ', array_values( $columns ) ); $query = "INSERT INTO {$wpdb->yith_wcwl_items} ( {$query_columns} ) VALUES ( {$query_values} ) "; $res = $wpdb->query( $wpdb->prepare( $query, $values ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared if ( $res ) { $item->set_id( $wpdb->insert_id ); $item->apply_changes(); $this->clear_cache( $item ); /** * DO_ACTION: yith_wcwl_new_wishlist_item * * Allows to fire some action when a new item is added to the wishlist. * * @param int $item_id Wishlist item ID * @param YITH_WCWL_Wishlist_Item $item Wishlist item object * @param int $wishlist_id Wishlist ID */ do_action( 'yith_wcwl_new_wishlist_item', $item->get_id(), $item, $item->get_wishlist_id() ); } } /** * Read/populate data properties specific to this order item. * * @param WC_Order_Item_Product $item Product order item object. * * @throws Exception When wishlist item is not found. * @since 3.0.0 */ public function read( &$item ) { global $wpdb; $item->set_defaults(); // Get from cache if available. $data = wp_cache_get( 'item-' . $item->get_id(), 'wishlist-items' ); if ( false === $data ) { $data = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->yith_wcwl_items} WHERE ID = %d LIMIT 1;", $item->get_id() ) ); wp_cache_set( 'item-' . $item->get_id(), $data, 'wishlist-items' ); } if ( ! $data ) { throw new Exception( esc_html__( 'Invalid wishlist item.', 'yith-woocommerce-wishlist' ) ); } $item->set_props( array( 'wishlist_id' => $data->wishlist_id, 'product_id' => $data->prod_id, 'user_id' => $data->user_id, 'quantity' => $data->quantity, 'date_added' => $data->dateadded, 'position' => $data->position, 'original_price' => $data->original_price, 'original_currency' => $data->original_currency, 'on_sale' => $data->on_sale, ) ); $item->set_object_read( true ); } /** * Update a wishlist item in the database. * * @param YITH_WCWL_Wishlist_Item $item Wishlist item object. * @since 3.0.0 */ public function update( &$item ) { if ( ! $item->get_id() ) { return; } $changes = $item->get_changes(); if ( array_intersect( array( 'quantity', 'wishlist_id', 'product_id', 'user_id', 'position', 'on_sale', 'date_added' ), array_keys( $changes ) ) ) { $columns = array( 'quantity' => '%d', 'wishlist_id' => '%d', 'prod_id' => '%d', 'position' => '%d', 'on_sale' => '%d', 'dateadded' => 'FROM_UNIXTIME( %d )', 'user_id' => $item->get_user_id() ? '%d' : 'NULL', ); $values = array( $item->get_quantity(), $item->get_wishlist_id(), $item->get_original_product_id(), $item->get_position(), $item->is_on_sale(), $item->get_date_added( 'edit' ) ? $item->get_date_added( 'edit' )->getTimestamp() : time(), ); $user_id = $item->get_user_id(); if ( $user_id ) { $values[] = $user_id; } $this->update_raw( $columns, $values, array( 'ID' => '%d' ), array( $item->get_id() ) ); } $item->apply_changes(); $this->clear_cache( $item ); /** * DO_ACTION: yith_wcwl_update_wishlist_item * * Allows to fire some action when an item is updated in the wishlist. * * @param int $item_id Wishlist item ID * @param YITH_WCWL_Wishlist_Item $item Wishlist item object * @param int $wishlist_id Wishlist ID */ do_action( 'yith_wcwl_update_wishlist_item', $item->get_id(), $item, $item->get_wishlist_id() ); } /** * Remove a wishlist item from the database. * * @param \YITH_WCWL_Wishlist_Item $item Wishlist item object. * @since 3.0.0 */ public function delete( &$item ) { global $wpdb; $id = $item->get_id(); if ( ! $id ) { return; } /** * DO_ACTION: yith_wcwl_before_delete_wishlist_item * * Allows to fire some action before an item is deleted from the wishlist. * * @param int $item_id Wishlist item ID */ do_action( 'yith_wcwl_before_delete_wishlist_item', $item->get_id() ); $wpdb->delete( $wpdb->yith_wcwl_items, array( 'ID' => $item->get_id() ) ); /** * DO_ACTION: yith_wcwl_delete_wishlist_item * * Allows to fire some action when an item is deleted from the wishlist. * * @param int $item_id Wishlist item ID */ do_action( 'yith_wcwl_delete_wishlist_item', $item->get_id() ); $item->set_id( 0 ); $this->clear_cache( $item ); } /** * Retrieves wishlist items that match a set of conditions * * @param array $args Arguments array; it may contains any of the following:<br/> * [<br/> * 'user_id' // Owner of the wishlist; default to current user logged in (if any), or false for cookie wishlist<br/> * 'product_id' // Product to search in the wishlist<br/> * 'wishlist_id' // wishlist_id for a specific wishlist, false for default, or all for any wishlist<br/> * 'wishlist_token' // wishlist token, or false as default<br/> * 'wishlist_visibility' // all, visible, public, shared, private<br/> * 'is_default' => // whether searched wishlist should be default one <br/> * 'id' => false, // only for table select<br/> * 'limit' => false, // pagination param; number of items per page. 0 to get all items<br/> * 'offset' => 0 // pagination param; offset for the current set. 0 to start from the first item<br/> * ]. * * @return YITH_WCWL_Wishlist_Item[] */ public function query( $args = array() ) { global $wpdb; $default = array( 'user_id' => ( is_user_logged_in() ) ? get_current_user_id() : false, 'session_id' => ( ! is_user_logged_in() ) ? YITH_WCWL_Session()->maybe_get_session_id() : false, 'product_id' => false, 'wishlist_id' => false, // wishlist_id for a specific wishlist, false for default, or all for any wishlist. 'wishlist_token' => false, /** * APPLY_FILTERS: yith_wcwl_wishlist_visibility_string_value * * Filter the wishlist visibility value. * * @param string $wishlist_visibility Wishlist visibility. Possible values are: all | visible | public | shared | private * * @return string */ 'wishlist_visibility' => apply_filters( 'yith_wcwl_wishlist_visibility_string_value', 'all' ), // all | visible | public | shared | private. 'is_default' => false, 'on_sale' => false, 'id' => false, // only for table select.. 'limit' => false, 'offset' => 0, 'orderby' => '', 'order' => 'DESC', ); // if there is no current wishlist, and user was asking for current one, short-circuit query, as pointless. if ( ! is_user_logged_in() && ! YITH_WCWL_Session()->has_session() && ! isset( $args['user_id'] ) && ! isset( $args['session_id'] ) ) { return array(); } $args = wp_parse_args( $args, $default ); extract( $args ); // phpcs:ignore WordPress.PHP.DontExtract $sql = "SELECT SQL_CALC_FOUND_ROWS i.* FROM `{$wpdb->yith_wcwl_items}` AS i LEFT JOIN {$wpdb->yith_wcwl_wishlists} AS l ON l.`ID` = i.`wishlist_id` INNER JOIN {$wpdb->posts} AS p ON p.ID = i.prod_id WHERE 1 AND p.post_type IN ( %s, %s ) AND p.post_status = %s"; // remove hidden products from result. $hidden_products = yith_wcwl_get_hidden_products(); /** * APPLY_FILTERS: yith_wcwl_remove_hidden_products_via_query * * Filter whether to remove hidden products via query. * * @param bool $bool Remove hidden products or not? * * @return bool */ if ( ! empty( $hidden_products ) && apply_filters( 'yith_wcwl_remove_hidden_products_via_query', true ) ) { $sql .= ' AND p.ID NOT IN ( ' . implode( ', ', array_filter( $hidden_products, 'esc_sql' ) ) . ' )'; } $sql_args = array( 'product', 'product_variation', 'publish', ); if ( ! empty( $user_id ) ) { $sql .= ' AND i.`user_id` = %d'; $sql_args[] = $user_id; } if ( ! empty( $session_id ) ) { $sql .= ' AND l.`session_id` = %s AND l.`expiration` > NOW()'; $sql_args[] = $session_id; } if ( ! empty( $product_id ) ) { $product_id = yith_wcwl_object_id( $product_id, 'product', true, 'default' ); $sql .= ' AND i.`prod_id` = %d'; $sql_args[] = $product_id; } if ( ! empty( $wishlist_id ) && 'all' !== $wishlist_id ) { $sql .= ' AND i.`wishlist_id` = %d'; $sql_args[] = $wishlist_id; } elseif ( ( empty( $wishlist_id ) ) && empty( $wishlist_token ) && empty( $is_default ) ) { $sql .= ' AND i.`wishlist_id` IS NULL'; } if ( ! empty( $wishlist_token ) ) { $sql .= ' AND l.`wishlist_token` = %s'; $sql_args[] = $wishlist_token; } if ( ! empty( $wishlist_visibility ) && 'all' !== $wishlist_visibility ) { switch ( $wishlist_visibility ) { case 'visible': $sql .= ' AND ( l.`wishlist_privacy` = %d OR l.`wishlist_privacy` = %d )'; $sql_args[] = 0; $sql_args[] = 1; break; case 'shared': $sql .= ' AND l.`wishlist_privacy` = %d'; $sql_args[] = 1; break; case 'private': $sql .= ' AND l.`wishlist_privacy` = %d'; $sql_args[] = 2; break; case 'public': default: $sql .= ' AND l.`wishlist_privacy` = %d'; $sql_args[] = 0; break; } } if ( ! empty( $is_default ) ) { YITH_WCWL_Wishlist_Factory::generate_default_wishlist(); $sql .= ' AND l.`is_default` = %d'; $sql_args[] = $is_default; } if ( isset( $on_sale ) && false !== $on_sale ) { $sql .= ' AND i.`on_sale` = %d'; $sql_args[] = $on_sale; } if ( ! empty( $id ) ) { $sql .= ' AND `i.ID` = %d'; $sql_args[] = $id; } $sql .= ' GROUP BY i.prod_id, l.ID'; if ( ! empty( $orderby ) ) { $order = ! empty( $order ) ? $order : 'DESC'; $sql .= ' ORDER BY i.' . esc_sql( $orderby ) . ' ' . esc_sql( $order ) . ', i.position ASC'; } else { $sql .= ' ORDER BY i.position ASC, i.ID DESC'; } if ( ! empty( $limit ) && isset( $offset ) ) { $sql .= ' LIMIT %d, %d'; $sql_args[] = $offset; $sql_args[] = $limit; } $items = $wpdb->get_results( $wpdb->prepare( $sql, $sql_args ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared /** * This filter was added to allow developer remove hidden products using a foreach loop, instead of the query * It is required when the store contains a huge number of hidden products, and the resulting query would fail * to be submitted to DBMS because of its size * * This code requires reasonable amount of products in the wishlist * A great number of products retrieved from the main query could easily degrade performance of the overall system * * @since 3.0.7 */ if ( ! empty( $hidden_products ) && ! empty( $items ) && ! apply_filters( 'yith_wcwl_remove_hidden_products_via_query', true ) ) { foreach ( $items as $item_id => $item ) { if ( ! in_array( $item->prod_id, $hidden_products, true ) ) { continue; } unset( $items[ $item_id ] ); } } if ( ! empty( $items ) ) { $items = array_map( array( 'YITH_WCWL_Wishlist_Factory', 'get_wishlist_item' ), $items ); } else { $items = array(); } /** * APPLY_FILTERS: yith_wcwl_get_products * * Filter the products retrieved from the wishlist. * * @param array $items Array of products * @param array $args Array of arguments * * @return array */ return apply_filters( 'yith_wcwl_get_products', $items, $args ); } /** * Counts items that matches * * @param array $args Same parameters allowed for {@see query} method. * @return int Count of items */ public function count( $args = array() ) { return count( $this->query( $args ) ); } /** * Query items table to retrieve distinct products added to wishlist, with count of occurrences * * @param array $args Arguments array; it may contains any of the following:<br/> * [<br/> * 'product_id' // Product to search in the wishlist<br/> * 'search' => '', // search string; will be matched against product name<br/> * 'interval' => '', // Interval of dates; this should be an associative array, that may contain start_date or end_date<br/> * 'orderby' => 'ID', // order param; a valid column in the result set<br/> * 'order' => 'desc', // order param; asc or desc<br/> * 'limit' => false, // pagination param; number of items per page. 0 to get all items<br/> * 'offset' => 0 // pagination param; offset for the current set. 0 to start from the first item<br/> * ]. * @return mixed Result set */ public function query_products( $args ) { global $wpdb; $default = array( 'product_id' => '', 'search' => '', 'interval' => array(), 'limit' => false, 'offset' => 0, 'orderby' => 'ID', 'order' => 'DESC', ); $args = wp_parse_args( $args, $default ); extract( $args ); // phpcs:ignore WordPress.PHP.DontExtract $sql = "SELECT DISTINCT i.prod_id AS id, p.post_title AS post_title, i2.wishlist_count AS wishlist_count FROM {$wpdb->yith_wcwl_items} AS i INNER JOIN {$wpdb->posts} AS p ON p.ID = i.prod_id LEFT JOIN ( SELECT COUNT( DISTINCT ID ) AS wishlist_count, prod_id FROM {$wpdb->yith_wcwl_items} GROUP BY prod_id ) AS i2 ON p.ID = i2.prod_id WHERE 1=1 AND p.post_status = %s"; $sql_args = array( 'publish' ); if ( ! empty( $product_id ) ) { $sql .= ' AND i.prod_id = %d'; $sql_args[] = $product_id; } if ( ! empty( $search ) ) { $sql .= ' AND p.post_title LIKE %s'; $sql_args[] = '%' . $search . '%'; } if ( ! empty( $args['interval'] ) && is_array( $args['interval'] ) && ( isset( $args['interval']['start_date'] ) || isset( $args['interval']['end_date'] ) ) ) { if ( ! empty( $args['interval']['start_date'] ) ) { $sql .= ' AND i.dateadded >= %s'; $sql_args[] = $args['interval']['start_date']; } if ( ! empty( $args['interval']['end_date'] ) ) { $sql .= ' AND i.dateadded <= %s'; $sql_args[] = $args['interval']['end_date']; } } if ( ! empty( $orderby ) ) { $order = ! empty( $order ) ? $order : 'DESC'; $sql .= ' ORDER BY ' . esc_sql( $orderby ) . ' ' . esc_sql( $order ); } if ( ! empty( $limit ) && isset( $offset ) ) { $sql .= ' LIMIT %d, %d'; $sql_args[] = $offset; $sql_args[] = $limit; } $items = $wpdb->get_results( $wpdb->prepare( $sql, $sql_args ), ARRAY_A ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared return $items; } /** * Counts total number of distinct products added to wishlist * * @param array $args Same parameters allowed for {@see query_products} method. * @return int Count of items */ public function count_products( $args ) { return count( $this->query_products( $args ) ); } /** * Counts how many distinct users added a product in wishlist * * @param int $product_id Product id. * @param string|int $user User to use in query; it could be a user id, a session id or 'current' (for current user/session). * @return int Count of times product was added to wishlist */ public function count_times_added( $product_id, $user = false ) { global $wpdb; $query_args = array(); $user_condition = ''; if ( $user ) { if ( 'current' === $user ) { if ( is_user_logged_in() ) { $user_condition = ' AND l.`user_id` = %d'; $query_args[] = get_current_user_id(); } elseif ( YITH_WCWL_Session()->has_session() ) { $user_condition = ' AND l.`session_id` = %s'; $query_args[] = YITH_WCWL_Session()->get_session_id(); } else { return 0; } } elseif ( is_int( $user ) ) { $user_condition = ' AND l.`user_id` = %d'; $query_args[] = $user; } elseif ( is_string( $user ) ) { $user_condition = ' AND l.`session_id` = %s'; $query_args[] = $user; } } $query = "SELECT COUNT( DISTINCT( v.`u_id` ) ) FROM ( SELECT ( CASE WHEN l.`user_id` IS NULL THEN l.`session_id` ELSE l.`user_id` END) AS u_id, l.`ID` as wishlist_id FROM {$wpdb->yith_wcwl_wishlists} AS l WHERE ( l.`expiration` > NOW() OR l.`expiration` IS NULL ) {$user_condition} ) as v LEFT JOIN {$wpdb->yith_wcwl_items} AS i USING( wishlist_id ) WHERE i.`prod_id` = %d"; $query_args[] = $product_id; $res = $wpdb->get_var( $wpdb->prepare( $query, $query_args ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared return (int) $res; } /** * Raw update method; useful when it is needed to update a bunch of items * * @param array $columns Array of columns to update, in the following format: 'column_id' => 'column_type'. * @param array $column_values Array of values to apply to the query; must have same number of elements of columns, and they must respect defined tpe. * @param array $conditions Array of where conditions, in the following format: 'column_id' => 'columns_type'. * @param array $conditions_values Array of values to apply to where condition; must have same number of elements of columns, and they must respect defined type. * @param bool $clear_caches Whether system should clear caches (this is optional since other methods may want to run more optimized clear). * * @return void */ public function update_raw( $columns, $column_values, $conditions = array(), $conditions_values = array(), $clear_caches = false ) { global $wpdb; // calculate where statement. $query_where = ''; if ( ! empty( $conditions ) ) { $query_where = array(); foreach ( $conditions as $column => $value ) { $query_where[] = $column . '=' . $value; } $query_where = ' WHERE ' . implode( ' AND ', $query_where ); } // retrieves wishlists that will be affected by the changes. if ( $clear_caches ) { $query = "SELECT ID FROM {$wpdb->yith_wcwl_items} {$query_where}"; $query = $conditions ? $wpdb->prepare( $query, $conditions_values ) : $query; // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared $ids = $wpdb->get_col( $query ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared } // calculate set statement. $query_columns = array(); foreach ( $columns as $column => $value ) { $query_columns[] = $column . '=' . $value; } $query_columns = implode( ', ', $query_columns ); // build query, and execute it. $query = "UPDATE {$wpdb->yith_wcwl_items} SET {$query_columns} {$query_where}"; $values = $conditions ? array_merge( $column_values, $conditions_values ) : $column_values; $wpdb->query( $wpdb->prepare( $query, $values ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared // clear cache for updated items. if ( $clear_caches && $ids ) { foreach ( $ids as $id ) { $this->clear_cache( $id ); } } } /** * Clear meta cache. * * @param YITH_WCWL_Wishlist_Item|int $item Wishlist item object, or id of the item. */ public function clear_cache( &$item ) { if ( ! $item instanceof YITH_WCWL_Wishlist_Item ) { $item = YITH_WCWL_Wishlist_Factory::get_wishlist_item( $item ); } wp_cache_delete( 'item-' . $item->get_id(), 'wishlist-items' ); wp_cache_delete( 'wishlist-items-' . $item->get_wishlist_id(), 'wishlists' ); wp_cache_delete( 'wishlist-items-' . $item->get_origin_wishlist_id(), 'wishlists' ); } /* === MISC === */ /** * Here we collected all methods related to db implementation of the items * They can be used without creating an instance of the Data Store, and are * listed here just for */ /** * Alter join section of the query, for ordering purpose * * @param string $join Join statement of the query. * @return string * @since 2.0.0 */ public static function filter_join_for_wishlist_count( $join ) { global $wpdb; $join .= " LEFT JOIN ( SELECT COUNT(*) AS wishlist_count, prod_id FROM {$wpdb->yith_wcwl_items} GROUP BY prod_id ) AS i ON ID = i.prod_id"; return $join; } /** * Alter orderby section of the query, for ordering purpose * * @param string $orderby Orderby statement of the query. * @return string * @since 2.0.0 */ public static function filter_orderby_for_wishlist_count( $orderby ) { $order = isset( $_REQUEST['order'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['order'] ) ) : 'ASC'; // phpcs:ignore WordPress.Security.NonceVerification.Recommended $orderby = 'i.wishlist_count ' . $order; return $orderby; } protected function get_db_info() { global $wpdb; $db_info = parent::get_db_info(); $db_info['table'] = $wpdb->yith_wcwl_itemmeta; return $db_info; } } } // phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching includes/rest-api/class-yith-wcwl-rest-server.php 0000777 00000003142 15251156646 0016142 0 ustar 00 <?php /** * Initialize this version of the REST API. * * @package YITH\Wishlist\RestApi */ defined( 'ABSPATH' ) || exit; if ( ! class_exists( 'YITH_WCWL_Rest_Server' ) ) { /** * Class responsible for loading the REST API and all REST API namespaces. */ class YITH_WCWL_Rest_Server { use YITH_WCWL_Singleton_Trait; /** * REST API namespaces and endpoints. * * @var array */ protected $controllers = array(); /** * Construct */ protected function __construct() { add_action( 'rest_api_init', array( $this, 'register_rest_routes' ), 10 ); } /** * Instance the controller classes that will register the Rest Routes */ public function register_rest_routes() { foreach ( $this->get_rest_namespaces() as $namespace => $controllers ) { foreach ( $controllers as $controller_name => $controller_class ) { if ( class_exists( $controller_class ) ) { $this->controllers[ $namespace ][ $controller_name ] = new $controller_class(); $this->controllers[ $namespace ][ $controller_name ]->register_routes(); } } } } /** * Get the namespace that needs to be registered * * @return array[] */ protected function get_rest_namespaces() { return array( 'yith-wishlist' => $this->get_v1_controllers(), ); } /** * List of controllers in the v1 namespace. * * @return array */ protected function get_v1_controllers() { return array( 'products' => 'YITH_WCWL_Rest_V1_Products_Controller', 'lists' => 'YITH_WCWL_Rest_V1_Lists_Controller', 'items' => 'YITH_WCWL_Rest_V1_Items_Controller', ); } } } includes/rest-api/controllers/v1/class-yith-wcwl-rest-v1-controller.php 0000777 00000005566 15251156646 0022253 0 ustar 00 <?php /** * Rest controller abstract class */ defined( 'ABSPATH' ) || exit; // Exit if accessed directly. if ( ! class_exists( 'YITH_WCWL_Rest_V1_Controller' ) ) { abstract class YITH_WCWL_Rest_V1_Controller extends WP_REST_Controller { /** * Get item permission * * TODO: implement this method * * @param WP_REST_Request $request * @return true|WP_Error */ public function get_item_permissions_check( $request ) { return true; } /** * Get item permission * * TODO: implement this method * * @param $request * @return true|WP_Error */ public function get_items_permissions_check( $request ) { return true; } /** * @param YITH_WCWL_Wishlist[] $wishlists The wishlist objects. * * @return array */ protected function prepare_wishlists_for_rest( $wishlists ) { $wishlists_for_rest = array(); foreach ( $wishlists as $wishlist ) { $wishlists_for_rest[ $wishlist->get_id() ] = $this->prepare_wishlist_for_rest( $wishlist ); } return $wishlists_for_rest; } /** * Prepare wishlist object for Rest response * * @param int|YITH_WCWL_Wishlist $wishlist The wishlist object or its id. * * @return array|false */ protected function prepare_wishlist_for_rest( $wishlist ) { $wishlist = $wishlist instanceof YITH_WCWL_Wishlist ? $wishlist : YITH_WCWL_Wishlist_Factory::get_wishlist( $wishlist ); if ( ! $wishlist ) { return false; } return array_merge( $wishlist->get_data(), array( 'name' => $wishlist->get_formatted_name(), 'token' => $wishlist->get_token(), 'session_id' => $wishlist->get_session_id(), ) ); } /** * @param YITH_WCWL_Wishlist[] $wishlists The wishlist objects. * * @return array */ protected function prepare_products_for_rest( $products ) { $products_for_rest = array(); foreach ( $products as $product ) { $products_for_rest[ $product instanceof WC_Product ? $product->get_id() : absint( $product ) ] = $this->prepare_product_for_rest( $product ); } return $products_for_rest; } /** * Prepare wishlist object for Rest response * * @param int|WC_Product $product The product object or its id. * * @return array|false */ protected function prepare_product_for_rest( $product, $additional_data = array() ) { $product = $product instanceof WC_Product ? $product : wc_get_product( $product ); if ( ! $product ) { return false; } $product_id = $product->get_id(); $product_lists = yith_wcwl_wishlists()->get_wishlists_for_product( $product_id ); return array_merge( array( 'name' => $product->get_name(), 'isAdded' => ! ! $product_lists, 'count' => yith_wcwl_wishlists()->count_add_to_wishlist( $product_id ), 'wishlists' => $product_lists, ), is_array( $additional_data ) ? $additional_data : array() ); } } } includes/rest-api/controllers/v1/class-yith-wcwl-rest-v1-items-controller.php 0000777 00000022036 15251156646 0023361 0 ustar 00 <?php /** * REST API Wishlist Items controller class. * * @package YITH\Wishlist\RestApi */ defined( 'ABSPATH' ) || exit; if ( ! class_exists( 'YITH_WCWL_Rest_V1_Items_Controller' ) ) { /** * REST API Wishlist Items controller class. * * @package YITH\Wishlist\RestApi */ class YITH_WCWL_Rest_V1_Items_Controller extends YITH_WCWL_Rest_V1_Controller { /** * Endpoint namespace. * * @var string */ protected $namespace = 'yith/wishlist/v1'; /** * Route base. * * @var string */ protected $rest_base = 'items'; /** * Register the routes. */ public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base, array( array( 'methods' => WP_REST_Server::CREATABLE, 'callback' => array( $this, 'add_item' ), 'permission_callback' => array( $this, 'create_item_permissions_check' ), 'args' => array( 'product_id' => array( 'description' => _x( 'The product ID', '[REST-API] The schema field description', 'yith-woocommerce-wishlist' ), 'type' => 'integer', 'required' => true, ), 'wishlist_id' => array( 'description' => _x( 'The Wishlist ID', '[REST-API] The schema field description', 'yith-woocommerce-wishlist' ), 'type' => array( 'integer', 'string' ), ), 'quantity' => array( 'description' => _x( 'The quantity to add in wishlist', '[REST-API] The schema field description', 'yith-woocommerce-wishlist' ), 'type' => 'integer', ), 'user_id' => array( 'description' => _x( 'The User ID', '[REST-API] The schema field description', 'yith-woocommerce-wishlist' ), 'type' => 'integer', ), 'dateadded' => array( 'description' => _x( 'The timestamp to use as added date.', '[REST-API] The schema field description', 'yith-woocommerce-wishlist' ), 'type' => 'integer', ), 'wishlist_name' => array( 'description' => _x( 'The wishlist name.', '[REST-API] The schema field description', 'yith-woocommerce-wishlist' ), 'type' => 'string', ), 'wishlist_visibility' => array( 'description' => _x( 'The wishlist visibility value.', '[REST-API] The schema field description', 'yith-woocommerce-wishlist' ), 'type' => 'integer', ), ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, '/' . $this->rest_base, array( array( 'methods' => WP_REST_Server::DELETABLE, 'callback' => array( $this, 'remove_item' ), 'permission_callback' => array( $this, 'delete_item_permissions_check' ), 'args' => array( 'product_id' => array( 'description' => _x( 'The product ID', '[REST-API] The schema field description', 'yith-woocommerce-wishlist' ), 'type' => 'integer', 'required' => true, ), 'wishlist_id' => array( 'description' => _x( 'The Wishlist ID', '[REST-API] The schema field description', 'yith-woocommerce-wishlist' ), 'type' => array( 'integer', 'string' ), ), 'user_id' => array( 'description' => _x( 'The User ID', '[REST-API] The schema field description', 'yith-woocommerce-wishlist' ), 'type' => 'integer', ), ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, '/' . $this->rest_base . '/move', array( array( 'methods' => WP_REST_Server::CREATABLE, 'callback' => array( $this, 'move_item' ), 'permission_callback' => '__return_true', 'args' => array( 'product_id' => array( 'description' => _x( 'The product ID', '[REST-API] The schema field description', 'yith-woocommerce-wishlist' ), 'type' => 'integer', 'required' => true, ), 'destination_wishlist' => array( 'description' => _x( 'The destination wishlist ID', '[REST-API] The schema field description', 'yith-woocommerce-wishlist' ), 'type' => array( 'integer', 'string' ), 'required' => true, ), 'origin_wishlist' => array( 'description' => _x( 'The origin wishlist ID', '[REST-API] The schema field description', 'yith-woocommerce-wishlist' ), 'type' => 'integer', ), 'wishlist_name' => array( 'description' => _x( 'The wishlist name.', '[REST-API] The schema field description', 'yith-woocommerce-wishlist' ), 'type' => 'string', ), 'wishlist_visibility' => array( 'description' => _x( 'The wishlist visibility value.', '[REST-API] The schema field description', 'yith-woocommerce-wishlist' ), 'type' => 'integer', ), ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } /** * Add item to a wishlist * * @param WP_REST_Request $request The rest request. * * @return WP_Error|WP_HTTP_Response|WP_REST_Response */ public function add_item( $request ) { $args = $request->get_params(); $response = array( 'success' => true ); $creating_default = false; if ( ! empty( $args[ 'wishlist_id' ] ) && 'default' === $args[ 'wishlist_id' ] ) { $creating_default = true; unset( $args[ 'wishlist_id' ] ); } try { $data = YITH_WCWL_Wishlists::get_instance()->add_item( $args ); $product_id = $args[ 'product_id' ]; $response = array( 'product_data' => array_merge( $this->prepare_product_for_rest( $product_id ), array( 'added_to' => $data[ 'wishlist_id' ], ) ), ); if ( $creating_default ) { $response[ 'wishlist_data' ] = $this->prepare_wishlist_for_rest( $data[ 'wishlist_id' ] ); } } catch ( \Exception $e ) { $response = array( 'success' => false, 'message' => $e->getMessage() ); } return rest_ensure_response( $response ); } /** * Remove an item from a wishlist * * @param WP_REST_Request $request The rest request. * * @return WP_Error|WP_HTTP_Response|WP_REST_Response */ public function remove_item( $request ) { $args = $request->get_params(); $response = array( 'success' => true ); try { $data = YITH_WCWL_Wishlists::get_instance()->remove_item( $args ); $product_id = $args[ 'product_id' ]; $response = array( 'product_data' => array_merge( array( 'removed_from' => $data[ 'wishlist_id' ] ), $this->prepare_product_for_rest( $product_id ) ), ); } catch ( \Exception $e ) { $response = array( 'success' => false, 'message' => $e->getMessage() ); } return rest_ensure_response( $response ); } /** * Remove an item from a wishlist * * @param WP_REST_Request $request The rest request. * * @return WP_Error|WP_HTTP_Response|WP_REST_Response */ public function move_item( $request ) { $args = $request->get_params(); try { $result = YITH_WCWL_Wishlists::get_instance()->move( $args ); $response = array( 'moved' => $result[ 'moved' ], 'product_data' => $this->prepare_product_for_rest( $args[ 'product_id' ], array( 'moved_from' => $args[ 'origin_wishlist' ], 'moved_to' => 'new' === $args[ 'destination_wishlist' ] ? $result[ 'destination_wishlist' ]->get_id() : $args[ 'destination_wishlist' ], ) ), ); if ( $result[ 'destination_wishlist' ] instanceof YITH_WCWL_Wishlist ) { $response[ 'destination_wishlist' ] = $this->prepare_wishlist_for_rest( $result[ 'destination_wishlist' ] ); } } catch ( \Exception $e ) { $response = array( 'success' => false, 'message' => $e->getMessage() ); } return rest_ensure_response( $response ); } /** * Create item permission checks * * @param WP_REST_Request $request * @return true|WP_Error */ public function create_item_permissions_check( $request ) { $wishlist = $this->get_wishlist_from_request( $request ); return ! $wishlist || $wishlist->current_user_can( 'add_to_wishlist' ); } /** * Delete item permission checks * * @param WP_REST_Request $request * @return true|WP_Error */ public function delete_item_permissions_check( $request ) { $wishlist = $this->get_wishlist_from_request( $request ); return ! $wishlist || $wishlist->current_user_can( 'remove_from_wishlist' ); } /** * Get wishlist object from request * * @param WP_REST_Request $request The request. * * @return YITH_WCWL_Wishlist|false */ protected function get_wishlist_from_request( $request ) { $wishlist_id = $request->get_param( 'wishlist_id' ); $wishlist = false; if ( $wishlist_id ) { try { $wishlist = new YITH_WCWL_Wishlist( $wishlist_id ); } catch ( Exception $exception ) { } } return $wishlist; } } } includes/rest-api/controllers/v1/class-yith-wcwl-rest-v1-lists-controller.php 0000777 00000006137 15251156646 0023402 0 ustar 00 <?php /** * REST API Wishlist Lists controller class. * * @package YITH\Wishlist\RestApi */ defined( 'ABSPATH' ) || exit; if ( ! class_exists( 'YITH_WCWL_Rest_V1_Lists_Controller' ) ) { /** * REST API Wishlist Lists controller class. * * @package YITH\Wishlist\RestApi */ class YITH_WCWL_Rest_V1_Lists_Controller extends YITH_WCWL_Rest_V1_Controller { /** * Endpoint namespace. * * @var string */ protected $namespace = 'yith/wishlist/v1'; /** * Route base. * * @var string */ protected $rest_base = 'lists'; /** * Register the routes. */ public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base, array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_lists' ), 'permission_callback' => '__return_true', 'args' => $this->get_endpoint_args_for_item_schema(), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, '/' . $this->rest_base, array( array( 'methods' => WP_REST_Server::CREATABLE, 'callback' => array( $this, 'create_list' ), 'permission_callback' => '__return_true', 'args' => array( 'wishlist_name' => array( 'description' => _x( 'The wishlist name.', '[REST-API] The schema field description', 'yith-woocommerce-wishlist' ), 'type' => 'string', 'required' => true, ), 'wishlist_visibility' => array( 'description' => _x( 'The wishlist visibility value.', '[REST-API] The schema field description', 'yith-woocommerce-wishlist' ), 'type' => 'integer', 'required' => true, ), 'user_id' => array( 'description' => _x( 'The unique identifier for the user.', '[REST-API] The schema field description', 'yith-woocommerce-wishlist' ), 'type' => 'integer', ), 'session_id' => array( 'description' => _x( 'The unique identifier for the session.', '[REST-API] The schema field description', 'yith-woocommerce-wishlist' ), 'type' => 'string', ), ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } /** * Get lists * * @return WP_Error|WP_HTTP_Response|WP_REST_Response */ public function get_lists() { $response = array( 'lists' => $this->prepare_wishlists_for_rest( YITH_WCWL_Wishlists::get_instance()->get_current_user_wishlists() ), ); return rest_ensure_response( $response ); } public function create_list( $request ) { $args = $request->get_params(); try { $wishlist = YITH_WCWL_Wishlists::get_instance()->create( $args ); $response = array( 'wishlist_data' => $this->prepare_wishlist_for_rest( $wishlist ), ); } catch ( YITH_WCWL_Exception $e ) { $response = array( 'success' => false, 'message' => $e->getMessage(), ); } return rest_ensure_response( $response ); } } } includes/rest-api/controllers/v1/class-yith-wcwl-rest-v1-products-controller.php 0000777 00000005647 15251156646 0024114 0 ustar 00 <?php /** * REST API Wishlist Products controller class. * * @package YITH\Wishlist\RestApi */ defined( 'ABSPATH' ) || exit; if ( ! class_exists( 'YITH_WCWL_REST_V1_Products_Controller' ) ) { /** * REST API Wishlist Products controller class. * * @package YITH\Wishlist\RestApi */ class YITH_WCWL_Rest_V1_Products_Controller extends YITH_WCWL_Rest_V1_Controller { /** * Endpoint namespace. * * @var string */ protected $namespace = 'yith/wishlist/v1'; /** * Route base. * * @var string */ protected $rest_base = 'products'; /** * Register the routes. */ public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base, array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_products_data' ), 'permission_callback' => '__return_true', // TODO: implement checks for permissions. 'args' => array( 'product_ids' => array( 'description' => _x( 'The list of product ids for which data is being requested.', '[REST-API] The schema field description', 'yith-woocommerce-wishlist' ), 'type' => 'array', 'required' => true, ), ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<product_id>[\d]+)', array( 'args' => array( 'product_id' => array( 'description' => _x( 'The unique identifier for the product.', '[REST-API] The schema field description', 'yith-woocommerce-wishlist' ), 'type' => 'integer', 'required' => true, ), ), array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_product_data' ), 'permission_callback' => '__return_true', 'args' => $this->get_endpoint_args_for_item_schema(), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } /** * Get wishlist data related to multiple products * * @param WP_REST_Request $request The rest request. * * @return WP_Error|WP_HTTP_Response|WP_REST_Response */ public function get_products_data( $request ) { $args = $request->get_params(); $products_data = array(); if ( ! empty( $args[ 'product_ids' ] ) ) { $products_data = $this->prepare_products_for_rest( $args[ 'product_ids' ] ); } return rest_ensure_response( $products_data ); } /** * Get wishlist data related to a single products * * @param WP_REST_Request $request The rest request. * * @return WP_Error|WP_HTTP_Response|WP_REST_Response */ public function get_product_data( $request ) { $args = $request->get_params(); $product_id = $args[ 'product_id' ]; $response = $this->prepare_product_for_rest($product_id); return rest_ensure_response( $response ); } } } includes/abstracts/abstract-yith-wcwl-block-object.php 0000777 00000013351 15251156646 0017162 0 ustar 00 <?php /** * Class to handle the base behaviour of a Block object */ defined( 'YITH_WCWL' ) || exit; // Exit if accessed directly. if ( ! class_exists( 'Abstract_YITH_WCWL_Block_Object' ) ) { class Abstract_YITH_WCWL_Block_Object { use YITH_WCWL_Rendering_Method_Access_Trait; /** * The options array * * @var array */ static protected $options = array(); /** * The object type * * @var string */ static protected $object_type = ''; /** * The object data * * @var array */ protected $data = array(); protected function __construct() { static::maybe_register_scripts(); } /** * Register scripts and style */ public static function maybe_register_scripts() { } /** * Register scripts and style */ public static function enqueue_style() { } /** * Set property * * @param string $prop The property name. * @param mixed $value The property value. */ protected function set_prop( $prop, $value ) { $this->data[ $prop ] = $value; } /** * Gets a prop for a getter method. * * @param string $prop Name of prop to get. * @param string $context What the value is for. Valid values are view and edit. * @return mixed * @since 3.0.0 */ protected function get_prop( $prop, $context = 'view' ) { $value = null; if ( array_key_exists( $prop, $this->data ) ) { $value = $this->data[ $prop ]; if ( 'view' === $context ) { $value = apply_filters( static::get_hook_prefix() . 'get_' . $prop, $value, $this ); } } return $value; } /** * Populate the object using an array of data * * @param array $data The data to populate the object */ protected function populate( $data ) { foreach ( $data as $prop => $value ) { $setter = "set_$prop"; if ( method_exists( $this, $setter ) ) { $this->{$setter}( $value ); } } } static public function get_hook_prefix() { return 'yith_wcwl_' . static::$object_type . '_'; } /** * Maybe initialize options with a static value that needs function calling * such as localized strings */ static protected function maybe_init_static_options() { } /** * Get Add To Wishlist button option * * @param string $option The option name. * @param mixed $default The default value to return if the option does not exist. * @return mixed */ static public function get_option( $option, $default = false ) { static::$options = array_merge( self::get_extended_options(), static::$options ); static::maybe_init_static_options(); if ( ! isset( static::$options[ $option ][ 'value' ] ) ) { if ( ! array_key_exists( $option, static::$options ) ) { static::$options[ $option ] = array(); } $value = $default; if ( ! empty( static::$options[ $option ][ 'name' ] ) ) { $option_value = get_option( static::$options[ $option ][ 'name' ], null ); if ( ! is_null( $option_value ) ) { $value = $option_value; static::$options[ $option ][ 'value' ] = $value; } elseif(isset(static::$options[ $option ][ 'default' ])){ $value = static::$options[ $option ][ 'default' ]; } } elseif ( isset( $static_options[ $option ] ) ) { $value = $static_options[ $option ]; static::$options[ $option ][ 'value' ] = $value; } } else { $value = static::$options[ $option ][ 'value' ]; } $value = apply_filters( static::get_hook_prefix() . $option . '_option', $value, $default ); return $value; } /** * Get the array of options * * TODO: handle the behavior when different classes extends this abstract class * * @return array */ protected static function get_extended_options() { static $extended_options = array(); if ( ! $extended_options ) { foreach ( get_declared_classes() as $class_name ) { if ( is_subclass_of( $class_name, __CLASS__ ) ) { $extended_options = array_merge( $extended_options, $class_name::$options ); } } } return $extended_options; } /** * Get the instance of the most extended version available * * @param array $data The instance Data * @return YITH_WCWL_Add_To_Wishlist_Button|YITH_WCWL_Add_To_Wishlist_Button_Premium */ public static function get( $data = array() ) { $class = self::get_class(); return new $class( $data ); } /** * Get the classname of the most extended class available * * @return self */ public static function get_class() { $extensions = array_keys( array_filter( array( '_Premium' => defined( 'YITH_WCWL_PREMIUM' ) && YITH_WCWL_PREMIUM, '_Extended' => defined( 'YITH_WCWL_EXTENDED' ) && YITH_WCWL_EXTENDED, ) ) ); $called_class = get_called_class(); $class = $called_class; $extensions_regex = array_map( function ( $extension ) { return '/' . preg_quote( $extension, '/' ) . '$/'; }, $extensions ); $base_class = preg_replace( $extensions_regex, '', $called_class ); foreach ( $extensions as $extension ) { $extension_class = $base_class . $extension; if ( class_exists( $extension_class ) ) { $class = $extension_class; break; } } return $class; } /** * Get global options * * @return array */ public static function get_global_options() { static $global_options = null; if ( is_null( $global_options ) ) { static::$options = array_merge( self::get_extended_options(), static::$options ); static::maybe_init_static_options(); foreach ( static::$options as $name => $option ) { $global_options[ $name ] = $option[ 'value' ] ?? get_option( $option[ 'name' ], $option[ 'default' ] ?? false ); } } return $global_options; } } } includes/widgets/elementor/class-yith-wcwl-elementor-wishlist.php 0000777 00000007222 15251156646 0021436 0 ustar 00 <?php /** * Wishlist widget for Elementor * * @author YITH <plugins@yithemes.com> * @package YITH\Wishlist\Classes\Elementor * @version 3.0.7 */ if ( ! defined( 'YITH_WCWL' ) ) { exit; } // Exit if accessed directly if ( ! class_exists( 'YITH_WCWL_Elementor_Wishlist' ) ) { /** * Wishlist Elementor block * * @since 3.0.0 */ class YITH_WCWL_Elementor_Wishlist extends \Elementor\Widget_Base { /** * Get widget name. * * Retrieve YITH_WCWL_Elementor_Wishlist widget name. * * @return string Widget name. * @since 1.0.0 * @access public */ public function get_name() { return 'yith_wcwl_wishlist'; } /** * Get widget title. * * Retrieve YITH_WCWL_Elementor_Wishlist widget title. * * @return string Widget title. * @since 1.0.0 * @access public */ public function get_title() { return _x( 'YITH Wishlist', 'Elementor widget name', 'yith-woocommerce-wishlist' ); } /** * Get widget icon. * * Retrieve YITH_WCWL_Elementor_Wishlist widget icon. * * @return string Widget icon. * @since 1.0.0 * @access public */ public function get_icon() { return 'eicon-table'; } /** * Get widget categories. * * Retrieve the list of categories the YITH_WCWL_Elementor_Wishlist widget belongs to. * * @return array Widget categories. * @since 1.0.0 * @access public */ public function get_categories() { return array( 'general', 'yith' ); } /** * Register YITH_WCWL_Elementor_Wishlist widget controls. * * Adds different input fields to allow the user to change and customize the widget settings. * * @since 1.0.0 * @access protected */ protected function register_controls() { $this->start_controls_section( 'product_section', array( 'label' => _x( 'Wishlist', 'Elementor section title', 'yith-woocommerce-wishlist' ), 'tab' => \Elementor\Controls_Manager::TAB_CONTENT, ) ); $this->add_control( 'wishlist_id', array( 'label' => _x( 'Wishlist ID', 'Elementor control label', 'yith-woocommerce-wishlist' ), 'type' => \Elementor\Controls_Manager::TEXT, 'input_type' => 'text', 'placeholder' => 'K6EOWXB888ZD', ) ); $this->end_controls_section(); $this->start_controls_section( 'labels_section', array( 'label' => _x( 'Pagination', 'Elementor section title', 'yith-woocommerce-wishlist' ), 'tab' => \Elementor\Controls_Manager::TAB_CONTENT, ) ); $this->add_control( 'pagination', array( 'label' => _x( 'Paginate items', 'Elementor control label', 'yith-woocommerce-wishlist' ), 'type' => \Elementor\Controls_Manager::SELECT, 'options' => array( 'yes' => __( 'Paginate', 'yith-woocommerce-wishlist' ), 'no' => __( 'Do not paginate', 'yith-woocommerce-wishlist' ), ), 'default' => 'no', ) ); $this->add_control( 'per_page', array( 'label' => _x( 'Items per page', 'yith-woocommerce-wishlist' ), 'type' => \Elementor\Controls_Manager::NUMBER, 'input_type' => 'number', 'placeholder' => 5, ) ); $this->end_controls_section(); } /** * Render YITH_WCWL_Elementor_Wishlist widget output on the frontend. * * @since 1.0.0 * @access protected */ protected function render() { $attribute_string = ''; $settings = $this->get_settings_for_display(); foreach ( $settings as $key => $value ) { if ( empty( $value ) || ! is_scalar( $value ) ) { continue; } $attribute_string .= " {$key}=\"{$value}\""; } echo do_shortcode( "[yith_wcwl_wishlist {$attribute_string}]" ); } } } includes/widgets/elementor/class-yith-wcwl-elementor-add-to-wishlist.php 0000777 00000013115 15251156646 0022602 0 ustar 00 <?php /** * Add to Wishlist widget for Elementor * * @author YITH <plugins@yithemes.com> * @package YITH\Wishlist\Classes\Elementor * @version 3.0.7 */ if ( ! defined( 'YITH_WCWL' ) ) { exit; } // Exit if accessed directly if ( ! class_exists( 'YITH_WCWL_Elementor_Add_To_Wishlist' ) ) { /** * Add to Wishlist Elementor block * * @since 3.0.0 */ class YITH_WCWL_Elementor_Add_To_Wishlist extends \Elementor\Widget_Base { /** * Get widget name. * * Retrieve YITH_WCWL_Elementor_Add_to_Wishlist widget name. * * @return string Widget name. * @since 1.0.0 * @access public */ public function get_name() { return 'yith_wcwl_add_to_wishlist'; } /** * Get widget title. * * Retrieve YITH_WCWL_Elementor_Add_to_Wishlist widget title. * * @return string Widget title. * @since 1.0.0 * @access public */ public function get_title() { return _x( 'YITH Wishlist Add button', 'Elementor widget name', 'yith-woocommerce-wishlist' ); } /** * Get widget icon. * * Retrieve YITH_WCWL_Elementor_Add_to_Wishlist widget icon. * * @return string Widget icon. * @since 1.0.0 * @access public */ public function get_icon() { return 'eicon-button'; } /** * Get widget categories. * * Retrieve the list of categories the YITH_WCWL_Elementor_Add_to_Wishlist widget belongs to. * * @return array Widget categories. * @since 1.0.0 * @access public */ public function get_categories() { return array( 'general', 'yith' ); } /** * Register YITH_WCWL_Elementor_Add_to_Wishlist widget controls. * * Adds different input fields to allow the user to change and customize the widget settings. * * @since 1.0.0 * @access protected */ protected function register_controls() { $this->start_controls_section( 'product_section', array( 'label' => _x( 'Product', 'Elementor section title', 'yith-woocommerce-wishlist' ), 'tab' => \Elementor\Controls_Manager::TAB_CONTENT, ) ); $this->add_control( 'product_id', array( 'label' => _x( 'Product ID', 'Elementor control label', 'yith-woocommerce-wishlist' ), 'type' => \Elementor\Controls_Manager::NUMBER, 'input_type' => 'text', 'placeholder' => '123', ) ); $this->end_controls_section(); $this->start_controls_section( 'labels_section', array( 'label' => _x( 'Labels', 'Elementor section title', 'yith-woocommerce-wishlist' ), 'tab' => \Elementor\Controls_Manager::TAB_CONTENT, ) ); $this->add_control( 'label', array( 'label' => _x( 'Button label', 'Elementor control label', 'yith-woocommerce-wishlist' ), 'type' => \Elementor\Controls_Manager::TEXT, 'input_type' => 'text', 'placeholder' => __( 'Add to wishlist', 'yith-woocommerce-wishlist' ), ) ); $this->add_control( 'browse_wishlist_text', array( 'label' => _x( '"Browse wishlist" label', 'Elementor control label', 'yith-woocommerce-wishlist' ), 'type' => \Elementor\Controls_Manager::TEXT, 'input_type' => 'text', 'placeholder' => __( 'Browse wishlist', 'yith-woocommerce-wishlist' ), ) ); $this->add_control( 'already_in_wishslist_text', array( 'label' => _x( '"Product already in wishlist" label', 'Elementor control label', 'yith-woocommerce-wishlist' ), 'type' => \Elementor\Controls_Manager::TEXT, 'input_type' => 'text', 'placeholder' => __( 'Product already in wishlist', 'yith-woocommerce-wishlist' ), ) ); $this->add_control( 'product_added_text', array( 'label' => _x( '"Product added to wishlist" label', 'Elementor control label', 'yith-woocommerce-wishlist' ), 'type' => \Elementor\Controls_Manager::TEXT, 'input_type' => 'text', 'placeholder' => __( 'Product added to wishlist', 'yith-woocommerce-wishlist' ), ) ); $this->end_controls_section(); $this->start_controls_section( 'advanced_section', array( 'label' => _x( 'Advanced', 'Elementor section title', 'yith-woocommerce-wishlist' ), 'tab' => \Elementor\Controls_Manager::TAB_CONTENT, ) ); $this->add_control( 'wishlist_url', array( 'label' => _x( 'URL of the wishlist page', 'Elementor control label', 'yith-woocommerce-wishlist' ), 'type' => \Elementor\Controls_Manager::TEXT, 'input_type' => 'url', 'placeholder' => '', ) ); $this->add_control( 'icon', array( 'label' => _x( 'Icon for the button', 'Elementor control label', 'yith-woocommerce-wishlist' ), 'type' => \Elementor\Controls_Manager::TEXT, 'input_type' => 'text', 'placeholder' => '', ) ); $this->add_control( 'link_classes', array( 'label' => _x( 'Additional CSS classes for the button', 'Elementor control label', 'yith-woocommerce-wishlist' ), 'type' => \Elementor\Controls_Manager::TEXT, 'input_type' => 'text', 'placeholder' => '', ) ); $this->end_controls_section(); } /** * Render YITH_WCWL_Elementor_Add_to_Wishlist widget output on the frontend. * * @since 1.0.0 * @access protected */ protected function render() { $attribute_string = ''; $settings = $this->get_settings_for_display(); foreach ( $settings as $key => $value ) { if ( empty( $value ) || ! is_scalar( $value ) ) { continue; } $attribute_string .= " {$key}=\"{$value}\""; } echo do_shortcode( "[yith_wcwl_add_to_wishlist {$attribute_string}]" ); } } } includes/class-yith-wcwl-ajax-handler.php 0000777 00000036746 15251156646 0014513 0 ustar 00 <?php /** * Static class that will handle all ajax calls for the list * * @author YITH <plugins@yithemes.com> * @package YITH\Wishlist\Classes * @version 3.0.0 */ defined( 'YITH_WCWL' ) || exit; // Exit if accessed directly. if ( ! class_exists( 'YITH_WCWL_Ajax_Handler' ) ) { /** * WooCommerce Wishlist Ajax Handler * * @since 3.0.0 */ class YITH_WCWL_Ajax_Handler { /** * Performs all required add_actions to handle forms * * @return void */ public static function init() { // add to wishlist. add_action( 'wp_ajax_add_to_wishlist', array( 'YITH_WCWL_Ajax_Handler', 'add_to_wishlist' ) ); add_action( 'wp_ajax_nopriv_add_to_wishlist', array( 'YITH_WCWL_Ajax_Handler', 'add_to_wishlist' ) ); // remove from wishlist. add_action( 'wp_ajax_remove_from_wishlist', array( 'YITH_WCWL_Ajax_Handler', 'remove_from_wishlist' ) ); add_action( 'wp_ajax_nopriv_remove_from_wishlist', array( 'YITH_WCWL_Ajax_Handler', 'remove_from_wishlist' ) ); // remove from wishlist (button). add_action( 'wp_ajax_delete_item', array( 'YITH_WCWL_Ajax_Handler', 'delete_item' ) ); add_action( 'wp_ajax_nopriv_delete_item', array( 'YITH_WCWL_Ajax_Handler', 'delete_item' ) ); // save title. add_action( 'wp_ajax_save_title', array( 'YITH_WCWL_Ajax_Handler', 'save_title' ) ); add_action( 'wp_ajax_nopriv_save_title', array( 'YITH_WCWL_Ajax_Handler', 'save_title' ) ); // load mobile templates. add_action( 'wp_ajax_load_mobile', array( 'YITH_WCWL_Ajax_Handler', 'load_mobile' ) ); add_action( 'wp_ajax_nopriv_load_mobile', array( 'YITH_WCWL_Ajax_Handler', 'load_mobile' ) ); // add to wishlist and reload. add_action( 'wp_ajax_reload_wishlist_and_adding_elem', array( 'YITH_WCWL_Ajax_Handler', 'reload_wishlist_and_adding_elem' ) ); add_action( 'wp_ajax_nopriv_reload_wishlist_and_adding_elem', array( 'YITH_WCWL_Ajax_Handler', 'reload_wishlist_and_adding_elem' ) ); // load fragments. add_action( 'wp_ajax_load_fragments', array( 'YITH_WCWL_Ajax_Handler', 'load_fragments' ) ); add_action( 'wp_ajax_nopriv_load_fragments', array( 'YITH_WCWL_Ajax_Handler', 'load_fragments' ) ); } /** * Add to wishlist from ajax call * * @return void */ public static function add_to_wishlist() { if ( ! isset( $_REQUEST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_REQUEST['nonce'] ) ), 'add_to_wishlist' ) ) { wp_send_json( array( 'result' => false ) ); } try { yith_wcwl_wishlists()->add_item( yith_wcwl()->get_details() ); $return = 'true'; /** * APPLY_FILTERS: yith_wcwl_product_added_to_wishlist_message * * Filter the message shown when an item has been added to the wishlist. * * @param string $message Message * * @return string */ $message = apply_filters( 'yith_wcwl_product_added_to_wishlist_message', get_option( 'yith_wcwl_product_added_text' ) ); // append view and close links. /** * APPLY_FILTERS: yith_wcwl_show_popup_links * * Filter whether to show the links in the popup after an item has been added to the wishlist. * * @param bool $show_links Whether to show links or not in the popup * * @return bool */ if ( apply_filters( 'yith_wcwl_show_popup_links', yith_wcwl_wishlists()->is_multi_wishlist_enabled() ) ) { $message .= '<p class="after-links"> <a href="' . YITH_WCWL()->get_last_operation_url() . '">' . __( 'View ›', 'yith-woocommerce-wishlist' ) . '</a> <span class="separator">' . __( 'or', 'yith-woocommerce-wishlist' ) . '</span> <a href="#" class="close-popup">' . __( 'Close', 'yith-woocommerce-wishlist' ) . '</a> </p>'; } } catch ( YITH_WCWL_Exception $e ) { $return = $e->getTextualCode(); /** * APPLY_FILTERS: yith_wcwl_error_adding_to_wishlist_message * * Filter the error message shown when adding an item to the wishlist. * * @param string $message Message * * @return string */ $message = apply_filters( 'yith_wcwl_error_adding_to_wishlist_message', $e->getMessage() ); } catch ( Exception $e ) { $return = 'error'; $message = apply_filters( 'yith_wcwl_error_adding_to_wishlist_message', $e->getMessage() ); } $product_id = isset( $_REQUEST['add_to_wishlist'] ) ? intval( $_REQUEST['add_to_wishlist'] ) : false; $fragments = isset( $_REQUEST['fragments'] ) ? wc_clean( $_REQUEST['fragments'] ) : false; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput $wishlist_url = YITH_WCWL()->get_last_operation_url(); $wishlists = YITH_WCWL_Wishlist_Factory::get_wishlists(); $wishlists_to_prompt = array(); foreach ( $wishlists as $wishlist ) { $wishlists_to_prompt[] = array( 'id' => $wishlist->get_id(), 'wishlist_name' => $wishlist->get_formatted_name(), 'default' => $wishlist->is_default(), 'add_to_this_wishlist_url' => $product_id ? wp_nonce_url( add_query_arg( array( 'add_to_wishlist' => $product_id, 'wishlist_id' => $wishlist->get_id(), ), $wishlist->get_url() ), 'add_to_wishlist' ) : '', ); } if ( in_array( $return, array( 'exists', 'true' ), true ) ) { // search for related fragments. if ( ! empty( $fragments ) && ! empty( $product_id ) ) { foreach ( $fragments as $id => $options ) { if ( strpos( $id, 'add-to-wishlist-' . $product_id ) ) { $fragments[ $id ]['wishlist_url'] = $wishlist_url; $fragments[ $id ]['added_to_wishlist'] = 'true' === $return; } } } } /** * APPLY_FILTERS: yith_wcwl_ajax_add_return_params * * Filter the parameters sent in the Ajax response. * * @param array $params Array of parameters sent in the response * * @return array */ wp_send_json( apply_filters( 'yith_wcwl_ajax_add_return_params', array( 'prod_id' => $product_id, 'result' => $return, 'message' => $message, 'fragments' => self::refresh_fragments( $fragments ), 'user_wishlists' => $wishlists_to_prompt, 'wishlist_url' => $wishlist_url, ) ) ); } /** * Remove from wishlist from ajax call * * @return void */ public static function remove_from_wishlist() { if ( ! isset( $_REQUEST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_REQUEST['nonce'] ) ), 'remove_from_wishlist' ) ) { wp_send_json( array( 'fragments' => array() ) ); } $fragments = isset( $_REQUEST['fragments'] ) ? wc_clean( $_REQUEST['fragments'] ) : false; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput $wishlist_token = isset( $_REQUEST['wishlist_token'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['wishlist_token'] ) ) : false; $wishlist = YITH_WCWL_Wishlist_Factory::get_wishlist( $wishlist_token ); try { if ( $wishlist && ! $wishlist->current_user_can( 'remove_from_wishlist' ) ) { wp_send_json( array( 'fragments' => array() ) ); } yith_wcwl_wishlists()->remove_item( yith_wcwl()->get_details() ); /** * APPLY_FILTERS: yith_wcwl_product_removed_text * * Filter the message when an item has been removed from the wishlist. * * @param string $message Message * * @return string */ $message = apply_filters( 'yith_wcwl_product_removed_text', __( 'Product successfully removed.', 'yith-woocommerce-wishlist' ) ); } catch ( Exception $e ) { $message = $e->getMessage(); } yith_wcwl_add_notice( $message ); wp_send_json( array( 'fragments' => self::refresh_fragments( $fragments ), ) ); } /** * Remove item from a wishlist * Differs from remove from wishlist, since this accepts item id instead of product id * * @return void * @since 3.0.0 */ public static function delete_item() { if ( ! isset( $_REQUEST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_REQUEST['nonce'] ) ), 'delete_item' ) ) { wp_send_json( array( 'result' => false ) ); } $item_id = isset( $_POST['item_id'] ) ? intval( $_POST['item_id'] ) : false; $fragments = isset( $_REQUEST['fragments'] ) ? wc_clean( $_REQUEST['fragments'] ) : false; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput $return = array( 'result' => false, ); if ( $item_id ) { $item = YITH_WCWL_Wishlist_Factory::get_wishlist_item( $item_id ); if ( $item ) { $wishlist = YITH_WCWL_Wishlist_Factory::get_wishlist( $item->get_wishlist_id() ); if ( $wishlist && ! $wishlist->current_user_can( 'remove_from_wishlist' ) ) { wp_send_json( array( 'fragments' => array() ) ); } $item->delete(); /** * APPLY_FILTERS: yith_wcwl_product_removed_text * * Filter the message when an item has been removed from the wishlist. * * @param string $message Message * * @return string */ $return = array( 'result' => true, 'message' => apply_filters( 'yith_wcwl_product_removed_text', __( 'Product successfully removed.', 'yith-woocommerce-wishlist' ) ), 'fragments' => self::refresh_fragments( $fragments ), ); } } wp_send_json( $return ); } /** * Save new wishlist privacy * * @return void * @since 3.0.7 */ public static function save_title() { if ( ! isset( $_REQUEST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_REQUEST['nonce'] ) ), 'save_title' ) ) { wp_send_json( array( 'result' => false ) ); } $wishlist_id = isset( $_POST['wishlist_id'] ) ? sanitize_text_field( wp_unslash( $_POST['wishlist_id'] ) ) : false; $wishlist_name = isset( $_POST['title'] ) ? sanitize_text_field( wp_unslash( $_POST['title'] ) ) : false; $fragments = isset( $_REQUEST['fragments'] ) ? wc_clean( $_REQUEST['fragments'] ) : false; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput $wishlist = $wishlist_id ? yith_wcwl_get_wishlist( $wishlist_id ) : false; if ( ! $wishlist_id || ! $wishlist ) { wp_send_json( array( 'result' => false, ) ); } if ( ! $wishlist_name || strlen( $wishlist_name ) >= 65535 ) { wp_send_json( array( 'result' => false, ) ); } if ( ! empty( $fragments ) ) { foreach ( $fragments as $id => $options ) { if ( isset( $options['is_user_owner'] ) && ! $options['is_user_owner'] ) { wp_send_json( array( 'result' => false, ) ); } } } $wishlist->set_name( $wishlist_name ); $wishlist->save(); /** * DO_ACTION: yith_wcwl_after_rename_wishlist * * Allows to fire some action when the wishlist has been renamed. * * @param YITH_WCWL_Wishlist $wishlist Wishlist object */ do_action( 'yith_wcwl_after_rename_wishlist', $wishlist ); $return = array( 'result' => true, 'fragments' => self::refresh_fragments( $fragments ), ); wp_send_json( $return ); } /** * Generated fragments to replace in the the page * * @return void * @since 3.0.0 */ public static function load_fragments() { if ( ! isset( $_REQUEST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_REQUEST['nonce'] ) ), 'load_fragments' ) ) { wp_send_json( array( 'result' => false ) ); } $fragments = isset( $_POST['fragments'] ) ? wc_clean( $_POST['fragments'] ) : false; // phpcs:ignore WordPress.Security wp_send_json( array( 'fragments' => self::refresh_fragments( $fragments ), ) ); } /** * Reload wishlist and adding elem action * * @return void * @since 1.0.0 */ public static function reload_wishlist_and_adding_elem() { if ( ! isset( $_REQUEST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_REQUEST['nonce'] ) ), 'reload_wishlist_and_adding_elem' ) ) { wp_send_json( array( 'result' => false ) ); } $type_msg = 'success'; try { yith_wcwl_wishlists()->add_item( yith_wcwl()->get_details() ); /** * APPLY_FILTERS: yith_wcwl_product_added_to_wishlist_message * * Filter the message shown when an item has been added to the wishlist. * * @param string $message Message * * @return string */ $message = apply_filters( 'yith_wcwl_product_added_to_wishlist_message', get_option( 'yith_wcwl_product_added_text' ) ); } catch ( YITH_WCWL_Exception $e ) { $message = $e->getMessage(); $type_msg = $e->getTextualCode(); } catch ( Exception $e ) { $message = $e->getMessage(); $type_msg = 'error'; } $wishlist_token = isset( $_REQUEST['wishlist_token'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['wishlist_token'] ) ) : false; $atts = array( 'wishlist_id' => $wishlist_token ); if ( isset( $_REQUEST['pagination'] ) ) { $atts['pagination'] = sanitize_text_field( wp_unslash( $_REQUEST['pagination'] ) ); } if ( isset( $_REQUEST['per_page'] ) ) { $atts['per_page'] = intval( $_REQUEST['per_page'] ); } yith_wcwl_add_notice( $message, $type_msg ); ?> <div> <?php echo YITH_WCWL_Shortcode::wishlist( $atts ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> </div> <?php die(); } /** * Reloads fragments, returning mobile version when available * * @return void * @since 3.0.0 */ public static function load_mobile() { global $yith_wcwl_is_mobile; if ( ! isset( $_REQUEST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_REQUEST['nonce'] ) ), 'load_mobile' ) ) { wp_send_json( array( 'fragments' => array() ) ); } $fragments = isset( $_POST['fragments'] ) ? wc_clean( $_POST['fragments'] ) : false; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput $result = array(); if ( ! empty( $fragments ) ) { foreach ( $fragments as $id => $options ) { $yith_wcwl_is_mobile = isset( $options['is_mobile'] ) ? 'yes' === $options['is_mobile'] : false; $result = array_merge( $result, self::refresh_fragments( array( $id => $options ) ) ); } } wp_send_json( array( 'fragments' => $result, ) ); } /** * Generate fragments for the templates that needs to be refreshed after ajax * * @param array $fragments Array of fragments to refresh. * @return array Array of templates to be replaced on the page */ public static function refresh_fragments( $fragments ) { $result = array(); if ( ! empty( $fragments ) ) { foreach ( $fragments as $id => $options ) { $id = sanitize_text_field( $id ); $options = YITH_WCWL_Frontend()->decode_fragment_options( $options ); $item = isset( $options['item'] ) ? $options['item'] : false; if ( ! $item ) { continue; } switch ( $item ) { case 'add_to_wishlist': case 'wishlist': $result[ $id ] = YITH_WCWL_Shortcode::$item( $options ); break; case 'YITH_WCWL_Widget': case 'YITH_WCWL_Items_Widget': ob_start(); the_widget( $item, $options ); $result[ $id ] = ob_get_clean(); break; default: /** * APPLY_FILTERS: yith_wcwl_fragment_output * * Filter the output when reloading fragments. * * @param string $output Fragment output * @param int $id Fragment ID * @param array $options Fragment options * * @return string */ $result[ $id ] = apply_filters( 'yith_wcwl_fragment_output', '', $id, $options ); break; } } } return $result; } } } YITH_WCWL_Ajax_Handler::init(); includes/class-yith-wcwl-autoloader.php 0000777 00000007616 15251156646 0014306 0 ustar 00 <?php /** * Autoloader class * * @class YITH_WCWL_Autoloader * @package YITH/Wishlist * @author YITH <plugins@yithemes.com> * @since 4.0.0 */ defined( 'YITH_WCWL' ) || exit; if ( ! class_exists( 'YITH_WCWL_Autoloader' ) ) { /** * The autoloader class * * @class YITH_WCWL_Autoloader * @since 4.0.0 */ class YITH_WCWL_Autoloader { /** * Constructor */ public function __construct() { if ( function_exists( '__autoload' ) ) { spl_autoload_register( '__autoload' ); } spl_autoload_register( array( $this, 'autoload' ) ); } /** * Get mapped file. Array of class => file to use on autoload. * * @return array * @since 1.0.0 */ protected function get_mapped_files() { /** * APPLY_FILTERS: yith_wcwl_autoload_mapped_files * * The filter allow to add remove the class to autoload. * * @param array $mapped_files The mapped files array. * * @return array */ $mapped_class = array( 'yith-wcwl-db' => 'abstract-yith-wcwl-db', ); return apply_filters( 'yith_wcwl_autoload_mapped_files', $mapped_class ); } /** * Autoload callback * * @param string $class The class to load. * * @since 1.0.0 */ public function autoload( $class ) { $class = strtolower( $class ); $class = str_replace( '_', '-', $class ); if ( false === strpos( $class, 'yith-wcwl' ) ) { return; // Pass over. } $base_path = YITH_WCWL_INC; // Check first for mapped files. $mapped = $this->get_mapped_files(); if ( isset( $mapped[ $class ] ) ) { $file = $base_path . $mapped[ $class ] . '.php'; } else { if ( false !== strpos( $class, 'trait' ) ) { $file = $base_path . 'traits/trait-' . $class . '.php'; } elseif ( false !== strpos( $class, 'privacy' ) ) { $file = $base_path . 'privacy/class-' . $class . '.php'; } elseif ( false !== strpos( $class, 'abstract' ) ) { $file = $base_path . 'abstracts/' . $class . '.php'; } elseif ( false !== strpos( $class, 'gutenberg' ) ) { $file = $base_path . 'builders/gutenberg/class-' . $class . '.php'; } elseif ( false !== strpos( $class, 'data-index' ) ) { $file = $base_path . 'data-index/class-' . $class . '.php'; } elseif ( false !== strpos( $class, 'data-search' ) ) { $file = $base_path . 'data-search/class-' . $class . '.php'; } elseif ( false !== strpos( $class, 'gutenberg' ) ) { $file = $base_path . 'builders/gutenberg/class-' . $class . '.php'; } elseif ( false !== strpos( $class, 'data-store' ) ) { $file = $base_path . 'data-stores/class-' . $class . '.php'; } elseif ( false !== strpos( $class, 'gb' ) ) { $file = $base_path . 'builders/gutenberg/blocks/class-' . $class . '.php'; } elseif ( false !== strpos( $class, 'elementor' ) ) { $file = $base_path . 'legacy/elementor/class-' . $class . '.php'; } elseif ( false !== strpos( $class, 'legacy' ) ) { $file = $base_path . 'legacy/class-' . $class . '.php'; } elseif ( false !== strpos( $class, 'widget' ) ) { $file = $base_path . 'widgets/class-' . $class . '.php'; } elseif ( false !== strpos( $class, 'elementor' ) ) { $file = $base_path . 'widgets/elementor/class-' . $class . '.php'; } elseif ( false !== strpos( $class, 'table' ) ) { $file = $base_path . 'tables/class-' . $class . '.php'; } elseif ( false !== strpos( $class, 'admin' ) ) { $file = $base_path . 'admin/class-' . $class . '.php'; } elseif ( false !== strpos( $class, 'rest' ) ) { $base_path .= 'rest-api/'; if ( strpos( $class, 'controller' ) ) { $base_path .= 'controllers/'; if ( strpos( $class, 'v1' ) ) { $base_path .= 'v1/'; } } $file = $base_path . 'class-' . $class . '.php'; } else { $file = $base_path . 'class-' . $class . '.php'; } } if ( is_readable( $file ) ) { require_once $file; } } } } new YITH_WCWL_Autoloader(); includes/class-yith-wcwl-add-to-wishlist-button.php 0000777 00000071247 15251156646 0016475 0 ustar 00 <?php /** * Add to wishlist button handler * * @package YITH\Wishlist\Classes * @author YITH <plugins@yithemes.com> * @since 4.0 */ defined( 'YITH_WCWL' ) || exit; // Exit if accessed directly if ( ! class_exists( 'YITH_WCWL_Add_To_Wishlist_Button' ) ) { /** * @class YITH_WCWL_Add_To_Wishlist_Button */ class YITH_WCWL_Add_To_Wishlist_Button extends Abstract_YITH_WCWL_Block_Object { static protected $object_type = 'add_to_wishlist_button'; /** * @var array */ protected static $options = array( 'wishlist_disabled_for_unauthenticated_users' => array( 'name' => 'yith_wcwl_disable_wishlist_for_unauthenticated_users', 'default' => 'no', ), 'loop_position' => array( 'name' => 'yith_wcwl_loop_position', ), 'ajax_loading' => array( 'name' => 'yith_wcwl_ajax_enable', ), 'icon_type' => array( 'name' => 'yith_wcwl_add_to_wishlist_icon_type', 'default' => 'default', ), 'icon' => array( 'name' => 'yith_wcwl_add_to_wishlist_icon', 'default' => 'heart-outline', ), 'custom_icon' => array( 'name' => 'yith_wcwl_add_to_wishlist_custom_icon', ), 'added_icon_type' => array( 'name' => 'yith_wcwl_added_to_wishlist_icon_type', 'default' => 'default', ), 'added_icon' => array( 'name' => 'yith_wcwl_added_to_wishlist_icon', 'default' => 'heart', ), 'custom_added_icon' => array( 'name' => 'yith_wcwl_added_to_wishlist_custom_icon', ), 'custom_icon_alt' => array( 'value' => '', ), 'custom_icon_width' => array( 'value' => '25', ), 'behaviour' => array( 'name' => 'yith_wcwl_after_add_to_wishlist_behaviour', ), 'style' => array( 'name' => 'yith_wcwl_add_to_wishlist_style', ), ); /** * the object data * * @var array */ protected $data = array( 'product_id' => false, 'parent_product_id' => false, 'icon_type' => '', 'icon' => '', 'added_icon_type' => '', 'added_icon' => '', 'custom_icon' => '', 'custom_added_icon' => '', 'wishlist' => false, 'label' => '', 'added_label' => '', 'browse_label' => '', 'already_in_label' => '', 'is_single' => null, 'ajax_loading' => null, ); /** * The YITH_WCWL_Add_To_Wishlist_Button construct. * * @param array $data The button data. */ public function __construct( $data = array() ) { parent::__construct(); if ( is_array( $data ) ) { $this->populate( $data ); } } /* === SETTERS === */ /** * Setter for 'icon' property * * @param string $icon The icon. */ public function set_icon( $icon ) { if ( in_array( $icon, array( 'fa-heart-o', 'fa-heart', 'custom', 'none' ) ) ) { $this->set_prop( 'icon', $icon ); } } /** * Setter for 'added_icon' property * * @param string $icon The added_icon. */ public function set_added_icon( $icon ) { if ( in_array( $icon, array( 'fa-heart-o', 'fa-heart', 'custom', 'none' ) ) ) { $this->set_prop( 'added_icon', $icon ); } } /** * Setter for 'custom_icon' property * * @param string $custom_icon The custom_icon. */ public function set_custom_icon( $custom_icon ) { $this->set_prop( 'custom_icon', $custom_icon ); } /** * Setter for 'custom_added_icon' property * * @param string $custom_icon The custom_added_icon. */ public function set_custom_added_icon( $custom_icon ) { $this->set_prop( 'custom_added_icon', $custom_icon ); } /** * Setter for 'product_id' property * * @param int $product_id The product_id. */ public function set_product_id( $product_id ) { if ( $product_id instanceof WC_Product ) { $product_id = $product_id->get_id(); } elseif ( $product_id instanceof WP_Post ) { $product_id = $product_id->ID; } $product_id = absint( $product_id ); $this->set_prop( 'product_id', $product_id ); } /** * Setter for 'label' property * * @param string $label The label. */ public function set_label( $label ) { if ( is_string( $label ) ) { $this->set_prop( 'add_label', $label ); } } /** * Setter for 'added_label' property * * @param string $label The added_label. */ public function set_added_label( $label ) { if ( is_string( $label ) ) { $this->set_prop( 'added_label', $label ); } } /** * Setter for 'browse_label' property * * @param string $label The browse_label. */ public function set_browse_label( $label ) { if ( is_string( $label ) ) { $this->set_prop( 'browse_label', $label ); } } /** * Setter for 'already_in_label' property * * @param string $label The already_in_label. */ public function set_already_in_label( $label ) { if ( is_string( $label ) ) { $this->set_prop( 'already_in_label', $label ); } } /** * Setter for 'is_single' property * * @param string $is_single Whether it's single page or loop. */ public function set_is_single( $is_single ) { $this->set_prop( 'is_single', ! ! $is_single ); } /** * Setter for 'ajax_loading' property * * @param string $ajax_loading Whether load the content in ajax or not. */ public function set_ajax_loading( $ajax_loading ) { $this->set_prop( 'ajax_loading', wc_string_to_bool( $ajax_loading ) ); } /* === GETTERS === */ /** * Getter for 'icon' property * * @param string $context What the value is for. Valid values are view and edit. * * @return string */ public function get_icon( $context = 'view' ) { $icon = 'custom'; if ( 'custom' !== self::get_option( 'icon_type' ) ) { $icon = $this->get_prop( 'icon', $context ); } return $icon ?: self::get_option( 'icon' ); } /** * Getter for 'added_icon' property * * @param string $context What the value is for. Valid values are view and edit. * * @return string */ public function get_added_icon_type( $context = 'view' ) { $icon_type = $this->get_prop( 'added_icon_type', $context ); return $icon_type ?: self::get_option( 'added_icon_type' ); } /** * Getter for 'added_icon' property * * @param string $context What the value is for. Valid values are view and edit. * * @return string */ public function get_added_icon( $context = 'view' ) { $icon_type = $this->get_added_icon_type( $context ); switch ( $icon_type ) { case 'same': case 'custom': $icon = $icon_type; break; default: $icon = $this->get_prop( 'added_icon', $context ); break; } return $icon ?: self::get_option( 'added_icon' ); } /** * Getter for 'custom_icon' property * * @param string $context What the value is for. Valid values are view and edit. * * @return string */ public function get_custom_icon( $context = 'view' ) { $custom_icon = $this->get_prop( 'custom_icon', $context ); return $custom_icon ?: self::get_option( 'custom_icon' ); } /** * Getter for 'custom_added_icon' property * * @param string $context What the value is for. Valid values are view and edit. * * @return string */ public function get_custom_added_icon( $context = 'view' ) { $added_icon = $this->get_added_icon( $context ); if ( 'same' === $added_icon ) { $custom_icon = $this->get_custom_icon( $context ); } else { $custom_icon = $this->get_prop( 'custom_added_icon', $context ); } return $custom_icon ?: self::get_option( 'custom_added_icon' ); } /** * Getter for 'product_id' property * * @param string $context What the value is for. Valid values are view and edit. * * @return int */ public function get_product_id( $context = 'view' ) { $product_id = $this->get_prop( 'product_id', $context ); if ( ! $product_id ) { $product = wc_get_product(); $product_id = $product ? $product->get_id() : false; if ( $product_id ) { $this->set_product_id( $product_id ); } } return $product_id; } /** * Return the product object * * @return false|WC_Product|null */ public function get_product() { return wc_get_product( $this->get_product_id() ); } /** * Getter for 'parent_product_id' property * * @param string $context What the value is for. Valid values are view and edit. * * @return int */ public function get_parent_product_id( $context = 'view' ) { $product = $this->get_product(); return $product ? $product->get_parent_id() : false; } /** * Getter for 'label' property * * @param string $context What the value is for. Valid values are view and edit. * * @return string */ public function get_add_label( $context = 'view' ) { $label = $this->get_prop( 'add_label', $context ); return $label ?: self::get_option( 'add_label' ); } /** * Getter for 'added_label' property * * @param string $context What the value is for. Valid values are view and edit. * * @return string */ public function get_added_label( $context = 'view' ) { $label = $this->get_prop( 'added_label', $context ); return $label ?: self::get_option( 'added_label' ); } /** * Getter for 'browse_label' property * * @param string $context What the value is for. Valid values are view and edit. * * @return string */ public function get_browse_label( $context = 'view' ) { $label = $this->get_prop( 'browse_label', $context ); return $label ?: self::get_option( 'browse_label' ); } /** * Getter for 'already_in_label' property * * @param string $context What the value is for. Valid values are view and edit. * * @return string */ public function get_already_in_label( $context = 'view' ) { $label = $this->get_prop( 'already_in_label', $context ); return $label ?: self::get_option( 'already_in_label' ); } /** * Getter for 'is_single' property * * @param string $context What the value is for. Valid values are view and edit. * * @return bool */ public function get_is_single( $context = 'view' ) { $is_single = $this->get_prop( 'is_single', $context ); return ! ! ( is_null( $is_single ) ? yith_wcwl_is_single() : $is_single ); } /** * Getter for 'is_single' property * * @param string $context What the value is for. Valid values are view and edit. * * @return bool */ public function get_ajax_loading( $context = 'view' ) { $ajax_loading = $this->get_prop( 'ajax_loading', $context ); return ! ! ( is_bool( $ajax_loading ) ? $ajax_loading : 'yes' === self::get_option( 'ajax_loading' ) ); } /* === CONDITIONALS === */ /** * Check if the product is already in the wishlist * * @return bool */ public function is_in_a_wishlist() { $product_id = $this->get_product_id(); if ( ! $product_id ) { return false; } return ! ! yith_wcwl_wishlists()->get_wishlist_for_product( $product_id ); } /** * Check if the product is already in the wishlist * * @return bool */ public function is_in_default_wishlist() { $product_id = $this->get_product_id(); if ( ! $product_id ) { return false; } return yith_wcwl_wishlists()->is_product_in_wishlist( $product_id ); } /** * Get the wishlist * * @return false|YITH_WCWL_Wishlist */ public function get_wishlist() { return $this->is_in_a_wishlist() ? yith_wcwl_get_wishlist() : false; } /** * Get the wishlist item * * @return false|YITH_WCWL_Wishlist */ public function get_wishlist_item() { $wishlist = $this->get_wishlist(); return $wishlist ? $wishlist->get_product( $this->get_product_id() ) : false; } /** * Get template kind * * @return string */ public function get_template_kind() { $behaviour = self::get_option( 'behaviour', 'view' ); $is_in_wishlist = $this->is_in_default_wishlist(); $template_part = $is_in_wishlist && 'add' !== $behaviour ? 'browse' : 'button'; $template_part = $is_in_wishlist ? 'added' : $template_part; if ( $is_in_wishlist && in_array( $template_part, array( 'browse', 'added' ), true ) && 'remove' === $behaviour ) { $template_part = 'remove'; } return $template_part; } /** * Get label for display * TODO: check if the behaviour is correct (maybe it just need to change the one for display only when on 'remove') * * @param string|null $template_kind The kind of template you want the label for * * @return string */ public function get_label_for_display( $template_kind = null ) { $template_kind = $this->get_template_kind(); switch ( $template_kind ) { case 'browse': $label = $this->get_browse_label(); break; case 'added': $label = $this->get_added_label(); break; case 'remove': $label = $this->get_option( 'remove_label' ); break; default: $label = $this->get_add_label(); } return $label; } /* === OTHER METHODS === */ /** * Return the array of data used to render the button or false if there is no product recoverable * * @return array|false */ protected function get_render_data() { $product = $this->get_product(); if ( ! $product ) { return array(); } // get wishlist url. $wishlist_url = YITH_WCWL()->get_wishlist_url(); $exists = $this->is_in_a_wishlist(); // get product type. $data = array( 'add_label' => $this->get_add_label(), 'added_label' => $this->get_added_label(), 'is_single' => $this->get_is_single(), 'exists' => $exists, 'kind' => $this->get_template_kind(), 'show_view' => yith_wcwl_is_single(), 'browse_label' => $this->get_browse_label(), 'already_in_label' => $this->get_already_in_label(), 'icon' => $this->get_prop( 'icon' ), 'added_icon' => $this->get_prop( 'added_icon' ), 'loop_position' => self::get_option( 'loop_position' ), ); // TODO: Add filter return array_filter( $data ); } /** * Return the array of data used to render the button or false if there is no product recoverable * * @return array|false */ protected function get_legacy_php_template_render_data() { $product = $this->get_product(); if ( ! $product ) { return false; } // get wishlist url. $wishlist_url = YITH_WCWL()->get_wishlist_url(); $data = array( 'label' => $this->get_label_for_display(), 'base_url' => yith_wcwl_get_current_url(), 'wishlist_url' => $wishlist_url, 'container_classes' => $this->get_container_classes(), 'product_id' => $product->get_id(), 'parent_product_id' => $product->get_parent_id(), 'product_type' => $product->get_type(), // TODO: check if needed. 'link_classes' => $this->get_button_classes(), 'is_single' => $this->get_is_single(), 'in_default_wishlist' => $this->is_in_default_wishlist(), // Always true if it exists in the free version 'exists' => $this->is_in_a_wishlist(), 'found_in_list' => $this->get_wishlist(), 'found_item' => $this->get_wishlist_item(), 'template_part' => $this->get_template_kind(), 'show_view' => yith_wcwl_is_single(), 'browse_wishlist_text' => $this->get_browse_label(), 'already_in_wishslist_text' => $this->get_already_in_label(), 'product_added_text' => $this->get_added_label(), 'icon' => $this->get_icon_to_display(), 'available_multi_wishlist' => false, 'disable_wishlist' => false, 'show_count' => false, // Always false in free version 'ajax_loading' => $this->get_ajax_loading(), 'loop_position' => self::get_option( 'loop_position' ), ); /** * APPLY_FILTERS: yith_wcwl_add_to_wishlist_params * * Filter the array with the parameters for the 'Add to wishlist' action. * * @param array $additional_params Wishlist parameters * @param array $data Array of attributes * * @return array */ $data = apply_filters( 'yith_wcwl_add_to_wishlist_params', $data, $data ); // set fragment options. $data[ 'fragment_options' ] = YITH_WCWL_Frontend()->format_fragment_options( $data, 'add_to_wishlist' ); // Updating icon and heading icon HTML $data = array_merge( $data, $this->get_icons_html() ); return $data; } /** * Render the button * * @param bool $return_html Whether you want to return HTML as string or just print it * * @return string|null */ public function render( $return_html = false ) { if ( 'php-templates' === self::get_rendering_method() ) { return $this->legacy_php_template_render( $return_html ); } $global_options = static::get_global_options(); $attributes = array_filter( $this->get_render_data(), function ( $value, $name ) use ( $global_options ) { return $value !== ( $global_options[ $name ] ?? null ); }, ARRAY_FILTER_USE_BOTH ); $button_html = '<div class="' . $this->get_component_container_classes() . '" data-product-id="' . absint( $this->get_product_id() ) . '" data-attributes="' . esc_attr( wp_json_encode( $attributes ) ) . '"></div>'; if ( ! $return_html ) { echo $button_html; } return $button_html; } /** * Get php template for "Add to wishlist" button * * @param bool $return_html Whether to print or return the button HTML. * @return string|null */ protected function legacy_php_template_render( $return_html = false ) { $data = $this->get_legacy_php_template_render_data(); if ( ! $data ) { return ''; } $template = yith_wcwl_get_template( 'add-to-wishlist.php', $data, $return_html ); // enqueue scripts. YITH_WCWL_Frontend()->register_styles(); YITH_WCWL_Frontend()->register_scripts(); YITH_WCWL_Frontend()->enqueue_scripts(); YITH_WCWL_Frontend()->enqueue_styles_and_stuffs(); /** * APPLY_FILTERS: yith_wcwl_add_to_wishlist_button_html * * Filter the HTML of the 'Add to wishlist' button. * * @param string $template Button HTML * @param string $wishlist_url Wishlist URL * @param string $product_type Product type * @param bool $exists Whether the product is already in the wishlist * @param array $data Array of attributes * * @return string */ return apply_filters( 'yith_wcwl_add_to_wishlist_button_html', $template, $data[ 'wishlist_url' ], $data[ 'product_type' ], $data[ 'exists' ], $data ); } /** * Get button icon * * @param array $data The button data. * @return string */ protected function get_icon_to_display() { $icon = $this->get_icon(); $added_icon = $this->get_added_icon(); $icon = 'none' !== $icon ? $icon : ''; $added_icon = 'none' !== $added_icon ? $added_icon : ''; $custom_icon = 'custom' === $icon ? $this->get_custom_icon() : ''; $custom_added_icon = 'custom' === $added_icon || ( 'same' === $added_icon && $custom_icon ) ? $this->get_custom_added_icon() : ''; $is_single = $this->get_is_single(); $is_on_top_of_the_image = 'before_image' === $this->get_option( 'loop_position' ); if ( ! $is_single && $is_on_top_of_the_image && ( ! $icon || ( 'custom' === $icon && ! $custom_icon && ! $custom_added_icon ) ) ) { $icon = 'heart-outline'; } // Change icon when item exists in wishlist. if ( $this->is_in_a_wishlist() ) { if ( $added_icon && 'same' !== $added_icon && ( 'custom' !== $added_icon || $custom_added_icon || $custom_icon ) ) { $icon = $added_icon; } elseif ( strpos( $icon, '-outline' ) !== false ) { $icon = str_replace( '-outline', '', $icon ); } } return $icon; } /** * Get button icons HTML * * @return string[] */ protected function get_icons_html() { $icon = $this->get_icon_to_display(); if ( 'custom' === $icon ) { $custom_icon = $this->get_custom_icon(); $custom_added_icon = $this->get_custom_added_icon(); $custom_icon_alt = self::get_option( 'custom_icon_alt' ); $custom_icon_width = self::get_option( 'custom_icon_width' ); if ( $this->is_in_a_wishlist() && $custom_added_icon ) { $icon_html = '<img class="yith-wcwl-icon" src="' . esc_url( $custom_added_icon ) . '" alt="' . esc_attr( $custom_icon_alt ) . '" width="' . esc_attr( $custom_icon_width ) . '" />'; $heading_icon_html = ! empty( $custom_icon ) ? '<img class="yith-wcwl-icon" src="' . esc_url( $custom_icon ) . '" alt="' . esc_attr( $custom_icon_alt ) . '" width="' . esc_attr( $custom_icon_width ) . '" />' : ''; } elseif ( $custom_icon ) { $icon_html = '<img class="yith-wcwl-icon" src="' . esc_url( $custom_icon ) . '" alt="' . esc_attr( $custom_icon_alt ) . '" width="' . esc_attr( $custom_icon_width ) . '" />'; $heading_icon_html = $icon_html; } } else { $icon_html = ! empty( $icon ) ? yith_wcwl_get_icon( $icon ) : ''; $heading_icon_html = $icon_html; } /** * APPLY_FILTERS: yith_wcwl_add_to_wishlist_icon_html * * Filter the HTML of the icon for the 'Add to wishlist'. * * @param string $icon_html HTML icon * @param array $data Array of attributes * * @return string */ $icon_html = apply_filters( 'yith_wcwl_add_to_wishlist_icon_html', $icon_html, $this->data ); /** * APPLY_FILTERS: yith_wcwl_add_to_wishlist_heading_icon_html * * Filter the HTML of the heading icon for the 'Add to wishlist'. * * @param string $icon_html HTML icon * @param array $data Array of attributes * * @return string */ $heading_icon_html = apply_filters( 'yith_wcwl_add_to_wishlist_heading_icon_html', $heading_icon_html, $this->data ); return array( 'icon' => $icon_html, 'heading_icon' => $heading_icon_html, ); } /** * Get button HTML classes * * @return string */ public function get_button_classes() { $classes = array(); $template_part = $this->get_template_kind(); $style = self::get_option( 'style' ); $loop_position = self::get_option( 'loop_position' ); $is_single = $this->get_is_single(); if ( 'remove' !== $template_part ) { $classes = array( 'add_to_wishlist', 'single_add_to_wishlist', ); } if ( in_array( $style, array( 'button_custom', 'button_default' ), true ) ) { $classes[] = 'alt'; // Prevent button appearance when we're in loop, over image. if ( $is_single || 'before_image' !== $loop_position ) { $classes[] = 'button'; } } if ( 'button_default' === $style ) { $classes[] = 'theme-button-style'; $classes[] = wc_wp_theme_get_element_class_name( 'button' ); } return apply_filters( 'yith_wcwl_add_to_wishlist_button_classes', implode( ' ', $classes ) ); } public function get_component_container_classes() { $classes = array( 'yith-add-to-wishlist-button-block', ); if ( $this->get_is_single() ) { $classes[] = 'yith-add-to-wishlist-button-block--single'; } return implode( ' ', $classes ); } /** * Get container HTML classes * * @return string */ public function get_container_classes() { $classes = array( 'yith-wcwl-add-to-wishlist--' . self::get_option( 'style' ) . '-style', ); if ( $this->is_in_a_wishlist() ) { $classes[] = 'exists'; } if ( $this->get_is_single() ) { $classes[] = 'yith-wcwl-add-to-wishlist--single'; } if ( $this->get_is_single() && ! $this->get_icon() ) { // TODO: check when this happen (no-icon displayed) $classes[] = 'no-icon'; } return implode( ' ', $classes ); } /** * Initialize static options */ static protected function maybe_init_static_options() { static $initialized = false; if ( ! $initialized ) { static::$options = array_merge( static::$options, array( 'popup_title' => array( 'value' => __( 'Select a wishlist', 'yith-woocommerce-wishlist' ) ), 'move_popup_title' => array( 'value' => __( 'Move to another wishlist', 'yith-woocommerce-wishlist' ) ), 'add_label' => array( 'name' => 'yith_wcwl_add_to_wishlist_text', 'default' => __( 'Add to wishlist', 'yith-woocommerce-wishlist' ), ), 'added_label' => array( 'name' => 'yith_wcwl_product_added_text', 'default' => __( 'Product added!', 'yith-woocommerce-wishlist' ), ), 'remove_label' => array( 'name' => 'yith_wcwl_remove_from_wishlist_text', 'default' => __( 'Remove from list', 'yith-woocommerce-wishlist' ), ), 'browse_label' => array( 'name' => 'yith_wcwl_browse_wishlist_text', 'default' => __( 'Remove from list', 'yith-woocommerce-wishlist' ), ), 'already_in_label' => array( 'name' => 'yith_wcwl_already_in_wishlist_text', 'default' => __( 'The product is already in your wishlist!', 'yith-woocommerce-wishlist' ), ), 'default_wishlist_name' => array( 'name' => 'yith_wcwl_wishlist_title', 'default' => __( 'My wishlist', 'yith-woocommerce-wishlist' ), ), ) ); $initialized = true; } parent::maybe_init_static_options(); } /** * Register scripts and style and localize scripts */ public static function maybe_register_scripts() { if ( ! self::is_php_templates_mode() ) { static $registered = false; if ( ! $registered ) { $asset_file = include YITH_WCWL_ASSETS . 'js/dist/components/add-to-wishlist/index.asset.php'; wp_register_style( 'yith-wcwl-add-to-wishlist', YITH_WCWL_ASSETS_CSS_URL . 'frontend/add-to-wishlist.css', array(), YITH_WCWL_VERSION ); wp_register_script( 'yith-wcwl-add-to-wishlist', YITH_WCWL_ASSETS_JS_URL . 'dist/components/add-to-wishlist/index.js', $asset_file[ 'dependencies' ], $asset_file[ 'version' ], true ); // TODO: minify the script and enqueue the in .min.js when not in debug mode wp_localize_script( 'yith-wcwl-add-to-wishlist', 'yithWcwlAddToWishlist', static::get_data_to_localize() ); $registered = true; } } } /** * Get object to localize in class script * * @return array */ protected static function get_data_to_localize() { return array( 'isUserLoggedIn' => is_user_logged_in(), 'globalOptions' => static::get_global_options(), 'buttonClasses' => wc_wp_theme_get_element_class_name( 'button' ), 'feedback_duration' => yith_wcwl_get_feedback_duration(), 'wishlist_url' => YITH_WCWL()->get_wishlist_url(), 'containerSelectors' => array( 'productContainer' => apply_filters( 'yith_wcwl_product_container_selectors', array( '.wc-block-grid__product', '.wp-block-post.product', '.wc-block-product', '.add-to-wishlist-before_image', ) ), 'thumbnailContainer' => apply_filters( 'yith_wcwl_product_thumbnail_container_selectors', array( 'div[data-block-name="woocommerce/product-image"]', 'div.wc-block-grid__product-image', '.woocommerce-loop-product__link [class*="image"]', '.astra-shop-thumbnail-wrap', '.product-inner .image-wrap', 'a.woocommerce-loop-product__link', 'div.t-entry-visual', 'div.box-image', 'div.product-image', 'a.product-image-link', ) ), ), 'login_wishlist_url' => add_query_arg( array( 'wishlist_notice' => 'true', 'add_to_wishlist' => '%product_id%', ), get_permalink( wc_get_page_id( 'myaccount' ) ) ), 'i18n' => array( 'feedbacks' => array( 'added' => __( '{{product_name}} has been added to your {{wishlist_name}} list!', 'yith-woocommerce-wishlist' ), 'removed' => __( '{{product_name}} has been removed from your {{wishlist_name}} list!', 'yith-woocommerce-wishlist' ), ), ), ); } /** * Enqueue style and scripts fot the add to wishlist. */ public static function enqueue_style() { static $enqueued = false; if ( ! $enqueued ) { wp_enqueue_script( 'yith-wcwl-add-to-wishlist' ); wp_enqueue_style( 'yith-wcwl-add-to-wishlist' ); wp_set_script_translations( 'yith-wcwl-add-to-wishlist', 'yith-woocommerce-wishlist', YITH_WCWL_DIR . 'languages/js' ); YITH_WCWL_Frontend::get_instance()->enqueue_custom_style( 'yith-wcwl-add-to-wishlist' ); $enqueued = true; } } } } includes/class-yith-wcwl-wishlists.php 0000777 00000052376 15251156646 0014203 0 ustar 00 <?php /** * Wishlists handler class * * @package YITH\Wishlist\Classes * @author YITH <plugins@yithemes.com> * @since 4.0.0 */ defined( 'YITH_WCWL' ) || exit; // Exit if accessed directly. if ( ! class_exists( 'YITH_WCWL_Wishlists' ) ) { /** * YITH_WCWL_Wishlist class */ class YITH_WCWL_Wishlists { use YITH_WCWL_Extensible_Singleton_Trait; /** * Store the last used wishlist token. * * @var string */ protected $last_operation_token = ''; /** * YITH_WCWL_Wishlist constructor */ protected function __construct() { } /* === WISHLISTS METHODS === */ /** * Add a new wishlist for the user. * * @param array $args Array of params for wishlist creation. * @return int|false The id of the wishlist created or false if something goes wrong * * @throws YITH_WCWL_Exception When trying to create wishlist. */ public function create( $args = array() ) { // phpcs:disable WordPress.Security.NonceVerification.Recommended $user_id = $args['user_id'] ?? false; if ( $user_id && get_current_user_id() !== $user_id && ! current_user_can( 'manage_woocommerce' ) ) { // phpcs:ignore WordPress.WP.Capabilities.Unknown throw new YITH_WCWL_Exception( esc_html__( 'There was an error while processing your request; please, try later', 'yith-woocommerce-wishlist' ), 0 ); } $wishlist = YITH_WCWL_Wishlist_Factory::generate_default_wishlist( $user_id ); return $wishlist ? $wishlist->get_id() : false; // phpcs:enable } /** * Update wishlist with arguments passed as second parameter * * @param int $wishlist_id The wishlist id. * @param array $args The array of parameters to use for update query. * * @return void */ public function update( $wishlist_id, $args = array() ) { } /** * Delete indicated wishlist * * @param int $wishlist_id The wishlist ID. * @return void */ public function remove( $wishlist_id ) { } /** * Move an item from a wishlist to another * * @param array $args The arguments. */ public function move( $args ) { } /** * Retrieve first list of current user where a specific product occurs; if no wishlist is found, returns false * * @param WC_Product|int $product The product or its id. * @return \YITH_WCWL_Wishlist|false First wishlist found where the product occurs (system will privilege default lists) */ public function get_wishlist_for_product( $product ) { $product_id = $product instanceof WC_Product ? $product->get_id() : absint( $product ); $items = YITH_WCWL_Wishlist_Factory::get_wishlist_items( array( 'product_id' => $product_id, 'wishlist_id' => 'all', 'limit' => 1, 'orderby' => 'dateadded', 'order' => 'DESC', ) ); if ( ! $items ) { return false; } $item = array_shift( $items ); /** * APPLY_FILTERS: yith_wcwl_wishlist_for_product * * Filter the first wishlist of current user where a specific product is found. * * @param YITH_WCWL_Wishlist $wishlist Wishlist object * @param int $product_id Product ID * * @return YITH_WCWL_Wishlist */ return apply_filters( 'yith_wcwl_wishlist_for_product', $item->get_wishlist(), $product_id ); } /** * Get wishlist of current user where a specific product is found. * * @param int $product_id Product ID. * @param bool|int $limit Query limit. * * @return array */ public function get_wishlists_for_product( $product_id, $limit = false ) { $args = array( 'product_id' => $product_id, 'wishlist_id' => 'all', 'orderby' => 'dateadded', 'order' => 'DESC', ); if ( $limit ) { $args['limit'] = $limit; } $items = YITH_WCWL_Wishlist_Factory::get_wishlist_items( $args ); $wishlist_ids = array_map( function ( $item ) { return $item->get_wishlist_id(); }, $items ); /** * APPLY_FILTERS: yith_wcwl_wishlist_for_product * * Filter the first wishlist of current user where a specific product is found. * * @param YITH_WCWL_Wishlist $wishlist Wishlist object * @param int $product_id Product ID * * @return YITH_WCWL_Wishlist */ return apply_filters( 'yith_wcwl_wishlists_for_product', $wishlist_ids, $product_id, $limit ); } /** * Retrieve all the wishlist matching specified arguments * * @param array $args Array of valid arguments<br/> * [<br/> * 'id' // Wishlist id to search, if any<br/> * 'user_id' // User owner<br/> * 'wishlist_slug' // Slug of the wishlist to search<br/> * 'wishlist_name' // Name of the wishlist to search<br/> * 'wishlist_token' // Token of the wishlist to search<br/> * 'wishlist_visibility' // Wishlist visibility: all, visible, public, shared, private<br/> * 'user_search' // String to match against first name / last name or email of the wishlist owner<br/> * 'is_default' // Whether wishlist should be default or not<br/> * 'orderby' // Column used to sort final result (could be any wishlist lists column)<br/> * 'order' // Sorting order<br/> * 'limit' // Pagination param: maximum number of elements in the set. 0 to retrieve all elements<br/> * 'offset' // Pagination param: offset for the current set. 0 to start from the first item<br/> * 'show_empty' // Whether to show empty lists os not<br/> * ]. * * @return YITH_WCWL_Wishlist[] * @since 2.0.0 */ public function get_wishlists( $args = array() ) { return YITH_WCWL_Wishlist_Factory::get_wishlists( $args ); } /** * Wrapper for \YITH_WCWL::get_wishlists, will return wishlists for current user * * @return YITH_WCWL_Wishlist[] */ public function get_current_user_wishlists() { $id = is_user_logged_in() ? get_current_user_id() : YITH_WCWL_Session()->maybe_get_session_id(); if ( ! $id ) { return array(); } $lists = wp_cache_get( 'user-wishlists-' . $id, 'wishlists' ); if ( ! $lists ) { $lists = YITH_WCWL_Wishlist_Factory::get_wishlists( array( 'orderby' => 'dateadded', 'order' => 'ASC', ) ); wp_cache_set( 'user-wishlists-' . $id, $lists, 'wishlists' ); } return $lists; } /** * Generate default wishlist for current user or session * * @param int|bool $id User or session id; false if you want to use current user/session. * * @return int Default wishlist id */ public function generate_default_wishlist( $id = false ) { $wishlist = YITH_WCWL_Wishlist_Factory::generate_default_wishlist( $id ); if ( $wishlist ) { return $wishlist->get_id(); } return false; } /** * Count users that have public wishlists * * @param string $search Search string. * * @return int */ public function count_users_with_wishlists( $search ) { return count( YITH_WCWL_Wishlist_Factory::get_wishlist_users( array( 'search' => $search ) ) ); } /* === WISHLIST ITEMS METHODS === */ /** * Add a product in the wishlist. * * @param array $args Array of parameters. * @throws YITH_WCWL_Exception When an error occurs with Add to Wishlist operation. * * @return array */ public function add_item( $args = array() ) { $defaults = array( 'product_id' => 0, 'wishlist_id' => 0, 'quantity' => 1, 'user_id' => false, 'dateadded' => time(), 'wishlist_name' => '', 'wishlist_visibility' => 0, ); $args = apply_filters( 'yith_wcwl_adding_to_wishlist_args', wp_parse_args( $args, $defaults ) ); /** * DO_ACTION: yith_wcwl_adding_to_wishlist * * Allows to fire some action when a product is added to a wishlist. * * @param int $product_id Product ID * @param int $wishlist_id Wishlist ID * @param int $user_id User ID */ do_action( 'yith_wcwl_adding_to_wishlist', $args['product_id'], $args['wishlist_id'], $args['user_id'] ); if ( ! $this->can_user_add_to_wishlist() ) { /** * APPLY_FILTERS: yith_wcwl_user_cannot_add_to_wishlist_message * * Filter the message shown when the product can't be added to the wishlist. * * @param string $message Message * * @return string */ throw new YITH_WCWL_Exception( esc_html( apply_filters( 'yith_wcwl_user_cannot_add_to_wishlist_message', __( 'The item cannot be added to this wishlist', 'yith-woocommerce-wishlist' ) ) ), 0 ); } if ( ! $args['product_id'] ) { throw new YITH_WCWL_Exception( esc_html__( 'An error occurred while adding the products to the wishlist.', 'yith-woocommerce-wishlist' ), 0 ); } $wishlist = 'new' === $args['wishlist_id'] ? $this->create( $args ) : YITH_WCWL_Wishlist_Factory::get_wishlist( $args['wishlist_id'], 'edit' ); if ( ! $wishlist instanceof YITH_WCWL_Wishlist || ! $wishlist->current_user_can( 'add_to_wishlist' ) ) { throw new YITH_WCWL_Exception( esc_html__( 'An error occurred while adding the products to the wishlist.', 'yith-woocommerce-wishlist' ), 0 ); } $this->last_operation_token = $wishlist->get_token(); if ( $wishlist->has_product( $args['product_id'] ) ) { /** * APPLY_FILTERS: yith_wcwl_product_already_in_wishlist_message * * Filter the message shown when the product is already in the wishlist. * * @param string $message Message * * @return string */ throw new YITH_WCWL_Exception( esc_html( apply_filters( 'yith_wcwl_product_already_in_wishlist_message', get_option( 'yith_wcwl_already_in_wishlist_text' ) ) ), 1 ); } $item = new YITH_WCWL_Wishlist_Item(); $item->set_product_id( $args['product_id'] ); $item->set_quantity( $args['quantity'] ); $item->set_wishlist_id( $wishlist->get_id() ); $item->set_user_id( $wishlist->get_user_id() ); if ( $args['dateadded'] ) { $item->set_date_added( $args['dateadded'] ); } $wishlist->add_item( $item ); $wishlist->save(); wp_cache_delete( 'wishlist-count-' . $wishlist->get_token(), 'wishlists' ); $user_id = $wishlist->get_user_id(); if ( $user_id ) { wp_cache_delete( 'wishlist-user-total-count-' . $user_id, 'wishlists' ); } /** * DO_ACTION: yith_wcwl_added_to_wishlist * * Allows to fire some action when a product has been added to a wishlist. * * @param int $prod_id Product ID * @param int $wishlist_id Wishlist ID * @param int $user_id User ID */ do_action( 'yith_wcwl_added_to_wishlist', $args['product_id'], $item->get_wishlist_id(), $item->get_user_id() ); return array( 'product_id' => $args['product_id'], 'wishlist_id' => $item->get_wishlist_id(), 'user_id' => $item->get_user_id(), ); } /** * Remove an entry from the wishlist. * * @param array $args Array of parameters. * * @throws YITH_WCWL_Exception When something was wrong with removal. * @return array */ public function remove_item( $args ) { $defaults = array( 'product_id' => 0, 'wishlist_id' => 0, 'user_id' => false, ); $args = wp_parse_args( $args, $defaults ); $product_id = intval( $args['product_id'] ); $wishlist_id = intval( $args['wishlist_id'] ); $user_id = intval( $args['user_id'] ); /** * DO_ACTION: yith_wcwl_removing_from_wishlist * * Allows to fire some action when removing a product from a wishlist. * * @param int $product_id Product ID * @param int $wishlist_id Wishlist ID * @param int $user_id User ID */ do_action( 'yith_wcwl_removing_from_wishlist', $product_id, $wishlist_id, $user_id ); if ( ! $product_id ) { /** * APPLY_FILTERS: yith_wcwl_unable_to_remove_product_message * * Filter the message shown when the product can't be removed the wishlist. * * @param string $message Message * * @return string */ throw new YITH_WCWL_Exception( esc_html( apply_filters( 'yith_wcwl_unable_to_remove_product_message', __( 'Error. Unable to remove the product from the wishlist.', 'yith-woocommerce-wishlist' ) ) ), 0 ); } /** * APPLY_FILTERS: yith_wcwl_get_wishlist_on_remove * * Filter the wishlist from which products will be removed. * * @param YITH_WCWL_Wishlist $wishlist Wishlist object * @param array $atts Array of parameters * * @return YITH_WCWL_Wishlist */ $wishlist = apply_filters( 'yith_wcwl_get_wishlist_on_remove', YITH_WCWL_Wishlist_Factory::get_wishlist( $wishlist_id ), $args ); /** * APPLY_FILTERS: yith_wcwl_allow_remove_after_add_to_cart * * Filter whether the product will be removed from the wishlist after it has been added to the cart. * * @param bool $remove_after_add_to_cart Whether the item will be removed from the wishlist after added to cart or not * @param YITH_WCWL_Wishlist $wishlist Wishlist object * * @return bool */ if ( apply_filters( 'yith_wcwl_allow_remove_after_add_to_cart', ! $wishlist instanceof YITH_WCWL_Wishlist || ! $wishlist->current_user_can( 'remove_from_wishlist' ), $wishlist ) ) { throw new YITH_WCWL_Exception( esc_html( apply_filters( 'yith_wcwl_unable_to_remove_product_message', __( 'Error. Unable to remove the product from the wishlist.', 'yith-woocommerce-wishlist' ) ) ), 0 ); } $wishlist->remove_product( $product_id ); $wishlist->save(); wp_cache_delete( 'wishlist-count-' . $wishlist->get_token(), 'wishlists' ); $user_id = $wishlist->get_user_id(); if ( $user_id ) { wp_cache_delete( 'wishlist-user-total-count-' . $user_id ); } /** * DO_ACTION: yith_wcwl_removed_from_wishlist * * Allows to fire some action when a product has been removed from a wishlist. * * @param int $product_id Product ID * @param int $wishlist_id Wishlist ID * @param int $user_id User ID */ do_action( 'yith_wcwl_removed_from_wishlist', $product_id, $wishlist->get_id(), $wishlist->get_user_id() ); return array( 'product_id' => $product_id, 'wishlist_id' => $wishlist->get_id(), 'user_id' => $wishlist->get_user_id(), ); } /** * Retrieve items of the wishlist for a specific user * * @param array $args Arguments array; it may contain any of the following:<br/> * [<br/> * 'user_id' // Owner of the wishlist; default to current user logged in (if any), or false for cookie wishlist<br/> * 'product_id' // Product to search in the wishlist<br/> * 'wishlist_id' // wishlist_id for a specific wishlist, false for default, or all for any wishlist<br/> * 'wishlist_token' // wishlist token, or false as default<br/> * 'wishlist_visibility' // all, visible, public, shared, private<br/> * 'is_default' => // whether searched wishlist should be default one <br/> * 'id' => false, // only for table select<br/> * 'limit' => false, // pagination param; number of items per page. 0 to get all items<br/> * 'offset' => 0 // pagination param; offset for the current set. 0 to start from the first item<br/> * ]. * * @return YITH_WCWL_Wishlist_Item[]|bool */ public function get_items( $args = array() ) { return YITH_WCWL_Wishlist_Factory::get_wishlist_items( $args ); } /** * Retrieve details of a product in the wishlist. * * @param WC_Product|int $product Product object or product id. * @param int|bool $wishlist_id Wishlist id, or false when default should be applied. * @return YITH_WCWL_Wishlist_Item|bool */ public function get_product_item( $product, $wishlist_id = false ) { $items = $this->get_items( array( 'product_id' => $product instanceof WC_Product ? $product->get_id() : $product, 'wishlist_id' => $wishlist_id, ) ); if ( empty( $items ) ) { return false; } return array_shift( $items ); } /** * Retrieve the number of products in the wishlist. * * @param string|bool $wishlist_token Wishlist token if any; false for default wishlist. * * @return int * @since 1.0.0 */ public function count_items_in_wishlist( $wishlist_token = false ) { $wishlist = YITH_WCWL_Wishlist_Factory::get_wishlist( $wishlist_token ); if ( ! $wishlist ) { return 0; } $count = wp_cache_get( 'wishlist-count-' . $wishlist->get_token(), 'wishlists' ); if ( false === $count ) { $count = $wishlist->count_items(); wp_cache_set( 'wishlist-count-' . $wishlist->get_token(), $count, 'wishlists' ); } return $count; } /** * Count all user items in wishlists * * @return int Count of items added all over wishlist from current user */ public function count_all_items() { $args = array( 'wishlist_id' => 'all', ); if ( is_user_logged_in() ) { $id = get_current_user_id(); $args['user_id'] = $id; } elseif ( YITH_WCWL_Session::get_instance()->has_session() ) { $id = YITH_WCWL_Session::get_instance()->get_session_id(); $args['session_id'] = $id; } if ( ! isset( $id ) ) { return 0; } $count = wp_cache_get( 'wishlist-user-total-count-' . $id, 'wishlists' ); if ( false === $count ) { $count = YITH_WCWL_Wishlist_Factory::get_wishlist_items_count( $args ); wp_cache_set( 'wishlist-user-total-count-' . $id, $count, 'wishlists' ); } return $count; } /** * Count number of times a product was added to users wishlists * * @param int|bool $product_id Product id; false will force method to use global product. * * @return int Number of times the product was added to wishlist * @since 2.0.13 */ public function count_add_to_wishlist( $product_id = false ) { global $product; $product_id = ! ( $product_id ) && $product ? $product->get_id() : $product_id; if ( ! $product_id ) { return 0; } return YITH_WCWL_Wishlist_Factory::get_times_added_count( $product_id ); } /** * Count product occurrences in users wishlists * * @param int|bool $product_id Product id; false will force method to use global product. * * @return int * @since 2.0.0 */ public function count_product_occurrences( $product_id = false ) { global $product; $product_id = ! ( $product_id ) ? yit_get_product_id( $product ) : $product_id; if ( ! $product_id ) { return 0; } $count = YITH_WCWL_Wishlist_Factory::get_wishlist_items_count( array( 'product_id' => $product_id, 'user_id' => false, 'session_id' => false, 'wishlist_id' => 'all', ) ); return $count; } /** * Check if the product exists in the wishlist. * * @param int $product_id Product id to check. * @param int|bool $wishlist_id Wishlist where to search (use false to search in default wishlist). * @return bool */ public function is_product_in_wishlist( $product_id, $wishlist_id = false ) { $wishlist = YITH_WCWL_Wishlist_Factory::get_wishlist( $wishlist_id ); if ( ! $wishlist ) { return false; } /** * APPLY_FILTERS: yith_wcwl_is_product_in_wishlist * * Filter whether the product is already in the wishlist. * * @param bool $is_in_wishlist Whether the product is already in the wishlist * @param int $product_id Product ID * @param int $wishlist_id Wishlist ID * * @return bool */ return apply_filters( 'yith_wcwl_is_product_in_wishlist', $wishlist->has_product( $product_id ), $product_id, $wishlist_id ); } /* === GENERAL METHODS === */ /** * Checks whether current user can add to the wishlist * * TODO: merge this into \YITH_WCWL_Wishlist::current_user_can * * @param int|bool $user_id User id to test; false to use current user id. * @return bool Whether current user can add to wishlist * @since 3.0.0 */ public function can_user_add_to_wishlist( $user_id = false ) { $user_id = $user_id ?: get_current_user_id(); // phpcs:ignore Universal.Operators.DisallowShortTernary.Found $disable_wishlist_for_unauthenticated_users = get_option( 'yith_wcwl_disable_wishlist_for_unauthenticated_users' ); $return = true; if ( 'yes' === $disable_wishlist_for_unauthenticated_users && ! $user_id ) { $return = false; } /** * APPLY_FILTERS: yith_wcwl_can_user_add_to_wishlist * * Filter whether the current user can add products to the wishlist. * * @param bool $can_add_to_wishlist Whether the product is already in the wishlist * @param int $user_id User ID * * @return bool */ return apply_filters( 'yith_wcwl_can_user_add_to_wishlist', $return, $user_id ); } /** * Checks whether multi-wishlist feature is enabled for current user * * @return bool Whether feature is enabled or not */ public function is_multi_wishlist_enabled() { return false; } } } includes/class-yith-wcwl-shortcode.php 0000777 00000057337 15251156646 0014146 0 ustar 00 <?php /** * Shortcodes class * * @package YITH\Wishlist\Classes * @author YITH <plugins@yithemes.com> * @version 3.0.0 */ if ( ! defined( 'YITH_WCWL' ) ) { exit; } // Exit if accessed directly if ( ! class_exists( 'YITH_WCWL_Shortcode' ) ) { /** * YITH WCWL Shortcodes * * @since 1.0.0 */ class YITH_WCWL_Shortcode { use YITH_WCWL_Rendering_Method_Access_Trait; /** * Init shortcodes available for the plugin * * @return void */ public static function init() { // register shortcodes. add_shortcode( 'yith_wcwl_wishlist', array( 'YITH_WCWL_Shortcode', 'wishlist' ) ); add_shortcode( 'yith_wcwl_add_to_wishlist', array( 'YITH_WCWL_Shortcode', 'add_to_wishlist' ) ); // register gutenberg blocks. add_action( 'init', array( 'YITH_WCWL_Shortcode', 'register_gutenberg_blocks' ) ); add_action( 'yith_plugin_fw_gutenberg_before_do_shortcode', array( 'YITH_WCWL_Shortcode', 'fix_for_gutenberg_blocks' ), 10, 1 ); // register elementor widgets. add_action( 'init', array( 'YITH_WCWL_Shortcode', 'init_elementor_widgets' ) ); } /* === GUTENBERG BLOCKS === */ /** * Register available gutenberg blocks * * @return void */ public static function register_gutenberg_blocks() { self::register_gutenberg_scripts(); YITH_WCWL_Add_To_Wishlist_Button::get_class()::maybe_register_scripts(); $blocks = array( 'yith-wcwl-add-to-wishlist' => array( 'style' => self::is_php_templates_mode() ? 'yith-wcwl-main' : 'yith-wcwl-add-to-wishlist', 'script' => self::is_php_templates_mode() ? 'jquery-yith-wcwl' : array( 'yith-wcwl-add-to-wishlist', 'yith-wcwl-add-to-wishlist-gutenberg' ), 'title' => _x( 'YITH Add to wishlist', '[gutenberg]: block name', 'yith-woocommerce-wishlist' ), 'description' => _x( 'Shows Add to wishlist button', '[gutenberg]: block description', 'yith-woocommerce-wishlist' ), 'shortcode_name' => 'yith_wcwl_add_to_wishlist', 'attributes' => array( 'product_id' => array( 'type' => 'text', 'label' => __( 'ID of the product to add to the wishlist (leave empty to use the global product)', 'yith-woocommerce-wishlist' ), 'default' => '', ), 'wishlist_url' => array( 'type' => 'text', 'label' => __( 'URL of the wishlist page (leave empty to use the default settings)', 'yith-woocommerce-wishlist' ), 'default' => '', ), 'label' => array( 'type' => 'text', 'label' => __( 'Button label (leave empty to use the default settings)', 'yith-woocommerce-wishlist' ), 'default' => '', ), 'browse_wishlist_text' => array( 'type' => 'text', 'label' => __( '"Browse wishlist" label (leave empty to use the default settings)', 'yith-woocommerce-wishlist' ), 'default' => '', ), 'already_in_wishslist_text' => array( 'type' => 'text', 'label' => __( '"Product already in wishlist" label (leave empty to use the default settings)', 'yith-woocommerce-wishlist' ), 'default' => '', ), 'product_added_text' => array( 'type' => 'text', 'label' => __( '"Product added to wishlist" label (leave empty to use the default settings)', 'yith-woocommerce-wishlist' ), 'default' => '', ), 'icon' => array( 'type' => 'text', 'label' => __( 'Icon for the button (use any FontAwesome valid class, or leave empty to use the default settings)', 'yith-woocommerce-wishlist' ), 'default' => '', ), 'link_classes' => array( 'type' => 'text', 'label' => __( 'Additional CSS classes for the button (leave empty to use the default settings)', 'yith-woocommerce-wishlist' ), 'default' => '', ), ), ), 'yith-wcwl-wishlist' => array( 'style' => 'yith-wcwl-main', 'script' => 'jquery-yith-wcwl', 'title' => _x( 'YITH Wishlist', '[gutenberg]: block name', 'yith-woocommerce-wishlist' ), 'description' => _x( 'Shows a list of products in wishlist', '[gutenberg]: block description', 'yith-woocommerce-wishlist' ), 'shortcode_name' => 'yith_wcwl_wishlist', 'attributes' => array( 'pagination' => array( 'type' => 'select', 'label' => __( 'Choose whether to paginate items in the wishlist or show them all', 'yith-woocommerce-wishlist' ), 'default' => 'no', 'options' => array( 'yes' => __( 'Paginate', 'yith-woocommerce-wishlist' ), 'no' => __( 'Do not paginate', 'yith-woocommerce-wishlist' ), ), ), 'per_page' => array( 'type' => 'number', 'label' => __( 'Number of items to show per page', 'yith-woocommerce-wishlist' ), 'default' => '5', ), 'wishlist_id' => array( 'type' => 'text', 'label' => __( 'ID of the wishlist to show (e.g. K6EOWXB888ZD)', 'yith-woocommerce-wishlist' ), 'default' => '', ), ), ), ); yith_plugin_fw_gutenberg_add_blocks( $blocks ); } /** * Register gutenberg scripts */ public static function register_gutenberg_scripts() { $prefix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? 'unminified/' : ''; $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min'; wp_register_script( 'yith-wcwl-add-to-wishlist-gutenberg', YITH_WCWL_ASSETS_JS_URL . $prefix . 'add-to-wishlist-gutenberg' . $suffix . '.js', 'jquery', YITH_WCWL_VERSION, true ); } /** * Fix preview of Gutenberg blocks at backend * * @param string $shortcode Shortcode to render. * @return void */ public static function fix_for_gutenberg_blocks( $shortcode ) { if ( strpos( $shortcode, '[yith_wcwl_add_to_wishlist' ) !== false ) { if ( strpos( $shortcode, 'product_id=""' ) !== false ) { $products = wc_get_products( array( 'type' => 'simple', 'limit' => 1, ) ); if ( ! empty( $products ) ) { global $product; $product = array_shift( $products ); } } } } /* === ELEMENTOR WIDGETS === */ /** * Register custom widgets for Elementor * * @return void */ public static function init_elementor_widgets() { // check if elementor is active. if ( ! defined( 'ELEMENTOR_VERSION' ) ) { return; } // include widgets. include_once YITH_WCWL_INC . 'widgets/elementor/class-yith-wcwl-elementor-add-to-wishlist.php'; include_once YITH_WCWL_INC . 'widgets/elementor/class-yith-wcwl-elementor-wishlist.php'; $register_widget_hook = version_compare( ELEMENTOR_VERSION, '3.5.0', '>=' ) ? 'elementor/widgets/register' : 'elementor/widgets/widgets_registered'; // register widgets. add_action( $register_widget_hook, array( 'YITH_WCWL_Shortcode', 'register_elementor_widgets' ) ); } /** * Register Elementor Widgets * * @return void */ public static function register_elementor_widgets() { $widgets_manager = \Elementor\Plugin::instance()->widgets_manager; if ( is_callable( array( $widgets_manager, 'register' ) ) ) { $widgets_manager->register( new YITH_WCWL_Elementor_Add_To_Wishlist() ); $widgets_manager->register( new YITH_WCWL_Elementor_Wishlist() ); } else { $widgets_manager->register_widget_type( new YITH_WCWL_Elementor_Add_To_Wishlist() ); $widgets_manager->register_widget_type( new YITH_WCWL_Elementor_Wishlist() ); } } /* === SHORTCODES == */ /** * Print the wishlist HTML. * * @param array $atts Array of attributes for the shortcode. * @param string $content Shortcode content (none expected). * @return string Rendered shortcode * * @since 1.0.0 */ public static function wishlist( $atts, $content = null ) { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter global $yith_wcwl_is_wishlist, $yith_wcwl_wishlist_token; $atts = shortcode_atts( array( 'per_page' => 5, 'current_page' => 1, 'pagination' => 'no', 'wishlist_id' => get_query_var( 'wishlist_id', false ), 'action_params' => get_query_var( YITH_WCWL()->wishlist_param, false ), 'no_interactions' => 'no', 'layout' => '', ), $atts ); /** * Extracted variables: * * @var $per_page int * @var $current_page int * @var $pagination string * @var $wishlist_id int * @var $action_params array * @var $no_interactions string * @var $layout string */ extract( $atts ); // phpcs:ignore // retrieve options from query string. /** * APPLY_FILTERS: yith_wcwl_current_wishlist_view_params * * Filter the array of parameters to see the current wishlist. * * @param array $params Array of parameters * * @return array */ $action_params = explode( '/', apply_filters( 'yith_wcwl_current_wishlist_view_params', $action_params ) ); $action = ( isset( $action_params[ 0 ] ) ) ? $action_params[ 0 ] : 'view'; // retrieve options from db. $default_wishlist_title = get_option( 'yith_wcwl_wishlist_title', __( 'My wishlist', 'yith-woocommerce-wishlist' ) ); $show_price = 'yes' === get_option( 'yith_wcwl_price_show' ); $show_stock = 'yes' === get_option( 'yith_wcwl_stock_show' ); $show_date_added = 'yes' === get_option( 'yith_wcwl_show_dateadded' ); $show_add_to_cart = 'yes' === get_option( 'yith_wcwl_add_to_cart_show' ); $show_remove_product = 'yes' === get_option( 'yith_wcwl_show_remove', 'yes' ); $show_variation = 'yes' === get_option( 'yith_wcwl_variation_show' ); $repeat_remove_button = 'yes' === get_option( 'yith_wcwl_repeat_remove_button' ); $add_to_cart_label = get_option( 'yith_wcwl_add_to_cart_text', __( 'Add to cart', 'yith-woocommerce-wishlist' ) ); $price_excluding_tax = 'excl' === get_option( 'woocommerce_tax_display_cart' ); $ajax_loading = 'yes' === get_option( 'yith_wcwl_ajax_enable', 'no' ); // icons. $icon = get_option( 'yith_wcwl_add_to_wishlist_icon' ); if ( 'custom' === $icon ) { $custom_icon = get_option( 'yith_wcwl_add_to_wishlist_custom_icon' ); /** * APPLY_FILTERS: yith_wcwl_custom_icon_alt * * Filter the alternative text for the heading icon in the widget. * * @param string $text Alternative text * * @return string */ $custom_icon_alt = apply_filters( 'yith_wcwl_custom_icon_alt', '' ); /** * APPLY_FILTERS: yith_wcwl_custom_width * * Filter the width for the heading icon in the widget. * * @param string $width Icon width * * @return string */ $custom_icon_width = apply_filters( 'yith_wcwl_custom_width', '32' ); $heading_icon = '<img src="' . esc_url( $custom_icon ) . '" alt="' . esc_attr( $custom_icon_alt ) . '" width="' . esc_attr( $custom_icon_width ) . '" />'; } else { $heading_icon = ! empty( $icon ) ? '<i class="fa ' . esc_attr( $icon ) . '"></i>' : ''; } // init params needed to load correct template. $template_part = 'view'; $no_interactions = 'yes' === $no_interactions; $additional_params = array( // wishlist data. 'wishlist' => false, 'is_default' => true, // @deprecated since 3.0.7 'is_custom_list' => false, 'wishlist_token' => '', 'wishlist_id' => false, 'is_private' => false, // wishlist items. 'count' => 0, 'wishlist_items' => array(), // page data. 'page_title' => $default_wishlist_title, 'default_wishlsit_title' => $default_wishlist_title, 'current_page' => $current_page, 'page_links' => false, 'layout' => $layout, // user data. 'is_user_logged_in' => is_user_logged_in(), 'is_user_owner' => true, 'can_user_edit_title' => false, // view data. 'no_interactions' => $no_interactions, 'show_price' => $show_price, 'show_dateadded' => $show_date_added, 'show_stock_status' => $show_stock, 'show_add_to_cart' => $show_add_to_cart && ! $no_interactions, 'show_remove_product' => $show_remove_product && ! $no_interactions, 'add_to_cart_text' => $add_to_cart_label, 'show_ask_estimate_button' => false, 'ask_estimate_url' => '', 'price_excl_tax' => $price_excluding_tax, 'show_cb' => false, 'show_quantity' => false, 'show_variation' => $show_variation, 'show_price_variations' => false, 'show_update' => false, 'enable_drag_n_drop' => false, 'enable_add_all_to_cart' => false, 'move_to_another_wishlist' => false, 'repeat_remove_button' => $repeat_remove_button && ! $no_interactions, 'show_last_column' => $show_date_added || ( $show_add_to_cart && ! $no_interactions ) || ( $repeat_remove_button && ! $no_interactions ), // wishlist icon. 'heading_icon' => $heading_icon, // share data. 'share_enabled' => false, // template data. 'template_part' => $template_part, 'additional_info' => false, 'available_multi_wishlist' => false, 'users_wishlists' => array(), 'form_action' => esc_url( YITH_WCWL()->get_wishlist_url( 'view' ) ), ); $wishlist = YITH_WCWL_Wishlist_Factory::get_current_wishlist( $atts ); if ( $wishlist && $wishlist->current_user_can( 'view' ) ) { // set global wishlist token. $yith_wcwl_wishlist_token = $wishlist->get_token(); // retrieve wishlist params. $is_user_owner = $wishlist->is_current_user_owner(); $count = $wishlist->count_items(); $offset = 0; // sets current page, number of pages and element offset. $queried_page = get_query_var( 'paged' ); $current_page = max( 1, $queried_page ? $queried_page : $current_page ); // sets variables for pagination, if shortcode atts is set to yes. if ( 'yes' === $pagination && ! $no_interactions && $count > 1 ) { $pages = ceil( $count / $per_page ); if ( $current_page > $pages ) { $current_page = $pages; } $offset = ( $current_page - 1 ) * $per_page; if ( $pages > 1 ) { $page_links = paginate_links( array( 'base' => esc_url( add_query_arg( array( 'paged' => '%#%' ), $wishlist->get_url() ) ), 'format' => '?paged=%#%', 'current' => $current_page, 'total' => $pages, 'show_all' => true, ) ); } } else { $per_page = 0; } // retrieve items to print. $wishlist_items = $wishlist->get_items( $per_page, $offset ); // retrieve wishlist information. $is_default = $wishlist->get_is_default(); $wishlist_token = $wishlist->get_token(); $wishlist_title = $wishlist->get_formatted_name(); $additional_params = wp_parse_args( array( // wishlist items. 'count' => $count, 'wishlist_items' => $wishlist_items, // wishlist data. 'wishlist' => $wishlist, 'is_default' => $is_default, 'is_custom_list' => $is_user_owner && ! $no_interactions, // @deprecated since 3.0.7 'wishlist_token' => $wishlist_token, 'wishlist_id' => $wishlist->get_id(), 'is_private' => $wishlist->has_privacy( 'private' ), 'ajax_loading' => $ajax_loading, // page data. 'page_title' => $wishlist_title, 'current_page' => $current_page, 'page_links' => isset( $page_links ) && ! $no_interactions ? $page_links : false, // user data. 'is_user_owner' => $is_user_owner, 'can_user_edit_title' => $wishlist->current_user_can( 'update_wishlist' ) && ! $no_interactions, // view data. 'show_remove_product' => $show_remove_product && $wishlist->current_user_can( 'remove_from_wishlist' ) && ! $no_interactions, 'repeat_remove_button' => $repeat_remove_button && $wishlist->current_user_can( 'remove_from_wishlist' ) && ! $no_interactions, // template data. 'form_action' => $wishlist->get_url(), ), $additional_params ); // share options. $enable_share = 'yes' === get_option( 'yith_wcwl_enable_share' ) && ! $wishlist->has_privacy( 'private' ); $share_facebook_enabled = 'yes' === get_option( 'yith_wcwl_share_fb' ); $share_twitter_enabled = 'yes' === get_option( 'yith_wcwl_share_twitter' ); $share_pinterest_enabled = 'yes' === get_option( 'yith_wcwl_share_pinterest' ); $share_email_enabled = 'yes' === get_option( 'yith_wcwl_share_email' ); $share_whatsapp_enabled = 'yes' === get_option( 'yith_wcwl_share_whatsapp' ); $share_url_enabled = 'yes' === get_option( 'yith_wcwl_share_url' ); // we want spaces to be encoded as + instead of %20, so we use urlencode instead of rawurlencode. // phpcs:disable WordPress.PHP.DiscouragedPHPFunctions.urlencode_urlencode if ( ! $no_interactions && $enable_share && ( $share_facebook_enabled || $share_twitter_enabled || $share_pinterest_enabled || $share_email_enabled || $share_whatsapp_enabled || $share_url_enabled ) ) { /** * APPLY_FILTERS: yith_wcwl_socials_share_title * * Filter the title to share the wishlist on the different socials. * * @param string $share_title Share title * * @return string */ $share_title = apply_filters( 'yith_wcwl_socials_share_title', __( 'Share on:', 'yith-woocommerce-wishlist' ) ); /** * APPLY_FILTERS: yith_wcwl_shortcode_share_link_url * * Filter the wishlist URL to share. * * @param string $share_link_url Share link URL * @param YITH_WCWL_Wishlist $wishlist Wishlist object * * @return string */ $share_link_url = apply_filters( 'yith_wcwl_shortcode_share_link_url', $wishlist->get_url(), $wishlist ); /** * APPLY_FILTERS: yith_wcwl_share_title * * Filter the title to share the wishlist. * * @param string $share_title Share title * @param YITH_WCWL_Wishlist $wishlist Wishlist object * * @return string */ $share_link_title = apply_filters( 'yith_wcwl_share_title', urlencode( get_option( 'yith_wcwl_socials_title' ) ), $wishlist ); $share_summary = urlencode( str_replace( '%wishlist_url%', $share_link_url, get_option( 'yith_wcwl_socials_text' ) ) ); $share_atts = array( 'share_facebook_enabled' => $share_facebook_enabled, 'share_twitter_enabled' => $share_twitter_enabled, 'share_pinterest_enabled' => $share_pinterest_enabled, 'share_email_enabled' => $share_email_enabled, 'share_whatsapp_enabled' => $share_whatsapp_enabled, 'share_url_enabled' => $share_url_enabled, 'share_title' => $share_title, 'share_link_url' => $share_link_url, 'share_link_title' => $share_link_title, ); $social_buttons = array( 'fb' => array( 'name' => 'facebook', 'alt_text' => __( 'Share on Facebook', 'yith-woocommerce-wishlist' ), 'enabled' => $share_facebook_enabled, ), 'tw' => array( 'name' => 'twitter', 'alt_text' => __( 'Tweet on Twitter (X)', 'yith-woocommerce-wishlist' ), 'icon' => 'x-twitter', 'enabled' => $share_twitter_enabled, ), 'pr' => array( 'name' => 'pinterest', 'alt_text' => __( 'Pin on Pinterest', 'yith-woocommerce-wishlist' ), 'enabled' => $share_pinterest_enabled, ), 'em' => array( 'name' => 'email', 'alt_text' => __( 'Share via email', 'yith-woocommerce-wishlist' ), 'icon' => 'envelope', 'enabled' => $share_email_enabled, ), 'wa' => array( 'name' => 'whatsapp', 'alt_text' => __( 'Share on WhatsApp', 'yith-woocommerce-wishlist' ), 'enabled' => $share_whatsapp_enabled, ), ); foreach ( $social_buttons as $social_id => $social_button ) { if ( $social_button[ 'enabled' ] ) { $share_button_icon = get_option( 'yith_wcwl_' . $social_id . '_button_icon', 'default' ); if ('none' === $share_button_icon) { $share_atts[ 'share_' . $social_button[ 'name' ] . '_icon' ] = ''; }else{ $share_button_custom_icon = get_option( 'yith_wcwl_' . $social_id . '_button_custom_icon' ); if ( 'custom' === $share_button_icon && $share_button_custom_icon ) { $share_atts[ 'share_' . $social_button[ 'name' ] . '_icon' ] = "<img src='$share_button_custom_icon' alt='{$social_button[ 'alt_text' ]}'/>"; } else { $share_atts[ 'share_' . $social_button[ 'name' ] . '_icon' ] = yith_wcwl_get_icon( $social_button[ 'icon' ] ?? $social_button[ 'name' ] ); } } } } if ( $share_twitter_enabled ) { $share_atts[ 'share_twitter_summary' ] = urlencode( str_replace( '%wishlist_url%', '', get_option( 'yith_wcwl_socials_text' ) ) ); } if ( $share_pinterest_enabled ) { $share_atts[ 'share_summary' ] = $share_summary; $share_atts[ 'share_image_url' ] = urlencode( get_option( 'yith_wcwl_socials_image_url' ) ); } if ( $share_whatsapp_enabled ) { if ( wp_is_mobile() ) { $share_atts[ 'share_whatsapp_url' ] = 'whatsapp://send?text=' . $share_link_title . ' - ' . urlencode( $share_link_url ); } else { $share_atts[ 'share_whatsapp_url' ] = 'https://web.whatsapp.com/send?text=' . $share_link_title . ' - ' . urlencode( $share_link_url ); } } $additional_params[ 'share_enabled' ] = true; $additional_params[ 'share_atts' ] = $share_atts; } // phpcs:enable WordPress.PHP.DiscouragedPHPFunctions.urlencode_urlencode } // filter params. /** * APPLY_FILTERS: yith_wcwl_wishlist_params * * Filter the array with the paramters in the wishlist page. * * @param array $additional_params Wishlist parameters * @param string $action Action * @param array $action_params Action parameters * @param string $pagination Use pagination or not * @param int $per_page Number of items per page * @param array $atts Array of attributes * * @return array */ $additional_params = apply_filters( 'yith_wcwl_wishlist_params', $additional_params, $action, $action_params, $pagination, $per_page, $atts ); $atts = array_merge( $atts, $additional_params ); $atts[ 'fragment_options' ] = YITH_WCWL_Frontend()->format_fragment_options( $atts, 'wishlist' ); // apply filters for add to cart buttons. YITH_WCWL_Frontend()->alter_add_to_cart_button(); // sets that we're in the wishlist template. $yith_wcwl_is_wishlist = true; $template = yith_wcwl_get_template( 'wishlist.php', $atts, true ); // we're not in wishlist template anymore. $yith_wcwl_is_wishlist = false; $yith_wcwl_wishlist_token = null; // remove filters for add to cart buttons. YITH_WCWL_Frontend()->restore_add_to_cart_button(); // enqueue scripts. YITH_WCWL_Frontend()->enqueue_scripts(); return apply_filters( 'yith_wcwl_wishlisth_html', $template, array(), true ); } /** * Return "Add to Wishlist" button. * * @param array $atts Array of parameters for the shortcode. * * @return string Template of the shortcode. * * @since 1.0.0 */ public static function add_to_wishlist( $atts ) { $button = YITH_WCWL_Add_To_Wishlist_Button::get( $atts ); return $button->render( true ); } } } YITH_WCWL_Shortcode::init(); includes/admin/class-yith-wcwl-rendering-method-admin-handler.php 0000777 00000011605 15251156646 0021164 0 ustar 00 <?php /** * Class that manage the admin handling rendering methods * * @since 4.0.0 * @package YITH\Wishlist\Admin\ * @author YITH <plugins@yithemes.com> */ defined( 'YITH_WCWL' ) || exit; if ( ! class_exists( 'YITH_WCWL_Rendering_Method_Admin_Handler' ) ) { /** * Class that manage the admin handling rendering methods */ class YITH_WCWL_Rendering_Method_Admin_Handler { use YITH_WCWL_Singleton_Trait; use YITH_WCWL_Rendering_Method_Access_Trait; /** * Class constructor */ protected function __construct() { $this->maybe_update_rendering_method(); add_action( 'admin_notices', array( $this, 'add_notices' ) ); add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) ); } protected function maybe_update_rendering_method() { if ( ! empty( $_REQUEST[ self::$exit_from_preview_mode_param ] ) ) { self::update_preview_options( false ); } if ( ! empty( $_REQUEST[ self::$convert_to_react_rendering_param ] ) ) { self::update_preview_options( false ); self::$updated_rendering_method = self::update_rendering_method( 'react-components' ); } } /** * Add notices used to update the rendering method */ public function add_notices() { $rendering_method = self::get_rendering_method_option(); $args = array(); if ( 'php-templates' === $rendering_method && YITH_WCWL_Admin_Panel::get_instance()->is_panel() ) { $args[ 'message' ] = sprintf( // translators: %1$s is the opening tag to hyperlink the text; %2$s id the closing tag to hyperlink the text; __( 'YITH Wishlist 4.0 includes the new React Components. %1$s Read how to convert to them to improve the plugin performance %2$s', 'yith-woocommerce-wishlist' ), '<a id="yith-wcwl-open-rendering-methods-modal" href="#">', '</a>' ); } if ( 'react-components' === $rendering_method && self::$updated_rendering_method ) { $args[ 'message' ] = sprintf( __( 'Successfully switched to the new React Components management!', 'yith-woocommerce-wishlist' ), '<a id="yith-wcwl-open-rendering-methods-modal" href="#">', '</a>' ); $args[ 'notice_type' ] = 'success'; } if ( ! empty( $args[ 'message' ] ) ) { $args = wp_parse_args( $args, array( 'type' => 'notice', 'notice_type' => 'warning', ) ); echo yith_plugin_fw_get_component( $args ); } } /** * Enqueue scripts */ public function enqueue_scripts() { if ( 'react-components' === self::get_rendering_method_option() ) { return; } $prefix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? 'unminified/' : ''; $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min'; wp_register_script( 'yith-wcwl-rendering-methods', YITH_WCWL_ASSETS_JS_URL . $prefix . 'admin/rendering-methods' . $suffix . '.js', array( 'jquery' ), YITH_WCWL_VERSION ); wp_register_style( 'yith-wcwl-rendering-methods', YITH_WCWL_ASSETS_CSS_URL . 'admin/rendering-methods.css', array(), YITH_WCWL_VERSION ); $current_url = ( is_ssl() ? 'https://' : 'http://' ) . $_SERVER[ 'HTTP_HOST' ] . $_SERVER[ 'REQUEST_URI' ]; wp_localize_script( 'yith-wcwl-rendering-methods', 'yithWcwlRenderingMethods', array( 'i18n' => array( 'reactOnlyOptionModalTitle' => __( 'This option is available only in the new React templates. Convert now to unlock all the new features!', 'yith-woocommerce-wishlist' ), ), 'modals' => array( 'updateRenderingMethod' => array( 'title' => __( 'YITH Wishlist 4.0 includes new React Components. Convert now to improve the plugin performance!', 'yith-woocommerce-wishlist' ), 'content' => __( "In this update, we converted our frontend templates using React to improve code readability and plugin performance.<br><br><b>Our PHP templates will be deprecated soon</b> (in the next major update) so we suggest you convert them now to enjoy the new system and check if everything works properly.<br><br>Any doubts? Don't worry! You can click on the button below to see a preview of the new system on your site before you apply the changes!", 'yith-woocommerce-wishlist' ), 'footer' => yith_wcwl_get_view( 'rendering-methods/modal/footer.php', array( 'preview_url' => add_query_arg( array( self::$react_preview_key => true, ), wc_get_page_permalink( 'shop' ) ), 'convert_to_react_url' => add_query_arg( array( self::$convert_to_react_rendering_param => true ), $current_url ), ), true ), ), ), 'templates' => array( 'reactOnlyOptionNotice' => yith_wcwl_get_view( 'rendering-methods/react-only-option-notice.php', array(), true ), ), ) ); if ( YITH_WCWL_Admin_Panel::get_instance()->is_panel() ) { wp_enqueue_script( 'yith-wcwl-rendering-methods' ); wp_enqueue_style( 'yith-wcwl-rendering-methods' ); } } } } includes/admin/class-yith-wcwl-admin-panel.php 0000777 00000022744 15251156646 0015423 0 ustar 00 <?php /** * Admin panel handler class * * @package YITH\Wishlist\Admin\Classes * @author YITH <plugins@yithemes.com> */ defined( 'YITH_WCWL' ) || exit; // Exit if accessed directly. if ( ! class_exists( 'YITH_WCWL_Admin_Panel' ) ) { /** * Initiator class. Create and populate admin views. * * @since 4.0.0 */ class YITH_WCWL_Admin_Panel { use YITH_WCWL_Extensible_Singleton_Trait; /** * Wishlist panel * * @since 2.0.0 * @var string Panel hookname */ protected $panel = null; /** * Wishlist panel page * * @since 2.0.0 * @var string Panel page name */ protected static $panel_page = 'yith_wcwl_panel'; /** * Docs url * * @since 4.0 * @var string Official documentation url */ protected static $doc_url = 'https://docs.yithemes.com/yith-woocommerce-wishlist/'; /** * Constructor of the class * * @since 2.0.0 */ protected function __construct() { // register wishlist panel. add_action( 'admin_menu', array( $this, 'register_panel' ), 5 ); } /** * Retrieve the admin panel tabs. * * @return array */ protected function get_tabs(): array { return array( 'settings' => array( 'title' => _x( 'Settings', 'Settings tab name', 'yith-woocommerce-wishlist' ), 'icon' => 'settings', ), 'customization' => array( 'title' => __( 'Customization', 'yith-woocommerce-wishlist' ), 'icon' => '<svg data-slot="icon" fill="none" stroke-width="1.5" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="m15 11.25 1.5 1.5.75-.75V8.758l2.276-.61a3 3 0 1 0-3.675-3.675l-.61 2.277H12l-.75.75 1.5 1.5M15 11.25l-8.47 8.47c-.34.34-.8.53-1.28.53s-.94.19-1.28.53l-.97.97-.75-.75.97-.97c.34-.34.53-.8.53-1.28s.19-.94.53-1.28L12.75 9M15 11.25 12.75 9"></path></svg>', ), ); } /** * Register plugin panel */ public function register_panel() { if ( ! empty( $this->panel ) ) { return; } $admin_tabs = apply_filters( 'yith_wcwl_admin_panel_tabs', $this->get_tabs() ); $args = array( 'ui_version' => 2, 'create_menu_page' => true, 'parent_slug' => '', 'page_title' => 'YITH WooCommerce Wishlist', 'menu_title' => 'Wishlist', 'plugin_slug' => YITH_WCWL_SLUG, 'plugin_version' => YITH_WCWL_VERSION, 'is_extended' => defined( 'YITH_WCWL_EXTENDED' ), 'is_premium' => defined( 'YITH_WCWL_PREMIUM' ), 'plugin_description' => __( 'Allows your customers to create and share lists of products that they want to purchase on your e-commerce.', 'yith-woocommerce-wishlist' ), /** * APPLY_FILTERS: yith_wcwl_settings_panel_capability * * Filter the capability used to access the plugin panel. * * @param string $capability Capability * * @return string */ 'capability' => apply_filters( 'yith_wcwl_settings_panel_capability', 'manage_options' ), 'parent' => '', 'class' => function_exists( 'yith_set_wrapper_class' ) ? yith_set_wrapper_class() : '', 'parent_page' => 'yith_plugin_panel', 'page' => self::$panel_page, 'admin-tabs' => $admin_tabs, 'options-path' => YITH_WCWL_DIR . 'plugin-options', 'help_tab' => $this->get_help_tab(), 'welcome_modals' => $this->get_welcome_modals(), 'premium_tab' => $this->get_premium_tab(), 'your_store_tools' => $this->get_your_store_tools_tab(), ); if ( empty( $args[ 'premium_tab' ] ) ) { unset( $args[ 'premium_tab' ] ); } if ( empty( $args[ 'your_store_tools' ] ) ) { unset( $args[ 'your_store_tools' ] ); } /* === Fixed: not updated theme === */ if ( ! class_exists( 'YIT_Plugin_Panel_WooCommerce' ) ) { require_once YITH_WCWL_DIR . 'plugin-fw/lib/yit-plugin-panel-wc.php'; } $this->panel = new YIT_Plugin_Panel_WooCommerce( $args ); } /** * Return the help tab options * * @return array */ protected function get_help_tab() { return array( 'main_video' => array( 'desc' => _x( 'Check this video to learn how to <b>configure wishlist and customize options:</b>', '[HELP TAB] Video title', 'yith-woocommerce-wishlist' ), 'url' => array( 'en' => 'https://www.youtube.com/embed/oMnfyHo819M', 'it' => 'https://www.youtube.com/embed/9hM9PgBVNTg', 'es' => 'https://www.youtube.com/embed/5gi8SrEuip8', ), ), 'playlists' => array( 'en' => 'https://www.youtube.com/watch?v=oMnfyHo819M&list=PLDriKG-6905lyNLO9kQ7GCsldGt7u-4Pa', 'it' => 'https://www.youtube.com/watch?v=zpwlE60H6YM&list=PL9c19edGMs09kk40S7FEiXjKKppjS-CAK', 'es' => 'https://www.youtube.com/watch?v=5Ftr4_v0s5I&list=PL9Ka3j92PYJMMYXecDH8FB5cxTfTbF4jJ', ), 'hc_url' => 'https://support.yithemes.com/hc/en-us/categories/360003468437-YITH-WOOCOMMERCE-WISHLIST', ); } /** * Return the premium tab options * * @return array */ protected function get_premium_tab() { return array( 'features' => array( array( 'title' => __( 'Allow users to create multiple wishlists', 'yith-woocommerce-wishlist' ), 'description' => __( 'In the premium version, your customers can create a wishlist for their birthday, Christmas, a graduation party, etc.', 'yith-woocommerce-wishlist' ), ), array( 'title' => __( 'Advanced wishlist management', 'yith-woocommerce-wishlist' ), 'description' => __( 'Allow users to rename wishlists, choose whether to make them public or private, move products from one list to another, and more.', 'yith-woocommerce-wishlist' ), ), array( 'title' => __( 'Different wishlist layouts', 'yith-woocommerce-wishlist' ), 'description' => __( 'Choose which layout you prefer to display products in the wishlist for a more modern and 100% mobile-friendly user experience.', 'yith-woocommerce-wishlist' ), ), array( 'title' => __( 'Insert a wishlist widget in the header of your shop', 'yith-woocommerce-wishlist' ), 'description' => __( 'Give instant access to the wishlist and show a preview of the products added to it by inserting the widget in the site header.', 'yith-woocommerce-wishlist' ), ), array( 'title' => __( 'Analyze your customers\' wishlists and the most popular products in your shop', 'yith-woocommerce-wishlist' ), 'description' => __( 'In the premium version, you can analyze the wishlists of each user in your shop and get a clear overview of the most popular products in your shop.', 'yith-woocommerce-wishlist' ), ), array( 'title' => __( 'Create targeted promotions and take advantage of the wishlists to increase conversions', 'yith-woocommerce-wishlist' ), 'description' => __( 'The premium version of the plugin allows you to structure effective marketing strategies and increase conversions. Some examples? You can send promotional emails and offer a discount to all users who have a specific product on their wishlist, notify customers when a product on their wishlist is on sale, or notify them when an out-of-stock product is available again in your shop.', 'yith-woocommerce-wishlist' ), ), ), ); } /** * Get welcome modals options * * @return array[][] */ protected function get_welcome_modals() { return array( 'show_in' => 'panel', 'modals' => array( 'welcome' => array( 'type' => 'welcome', 'show' => ! isset( $_GET[ 'yith-wcwl-no-welcome-modal' ] ) && false === get_option( 'yith_wcwl_disable_wishlist_for_unauthenticated_users', false ) && 'welcome' === get_option( 'yith-wcwl-welcome-modal', 'welcome' ), // phpcs:ignore WordPress.Security.NonceVerification.Recommended 'on_close' => function () { update_option( 'yith-wcwl-welcome-modal', 'no' ); }, 'items' => array( 'documentation' => array( 'url' => self::$doc_url ), 'watch_first_steps_video' => array( 'title' => __( 'Watch our first steps video', 'yith-woocommerce-wishlist' ), 'description' => __( 'See how it works before you start using it', 'yith-woocommerce-wishlist' ), 'url' => 'https://www.youtube.com/watch?v=oMnfyHo819M', ), 'setup_wishlist' => array( 'title' => __( 'Set up your shop\'s wishlist settings', 'yith-woocommerce-wishlist' ), 'description' => __( 'And embark on this new adventure!', 'yith-woocommerce-wishlist' ), 'url' => add_query_arg( array( 'page' => self::$panel_page, 'yith-wcwl-no-welcome-modal' => '', ), admin_url( 'admin.php' ) ), ), ), ), ), ); } /** * Get 'Your store tools tab' options * * @return array */ protected function get_your_store_tools_tab(){ return array(); } /** * Check if is a panel page */ public function is_panel() { return is_admin() && isset( $_GET[ 'page' ] ) && self::$panel_page === $_GET[ 'page' ]; // phpcs:ignore WordPress.Security.NonceVerification.Recommended } /** * get panel page url * * @param string $tab The panel tab. * * @return string */ public static function get_panel_page_url( $tab = '' ) { $query_args = array( 'page' => self::$panel_page ); if ( ! ! $tab ) { $query_args[ 'tab' ] = $tab; } return add_query_arg( $query_args, admin_url( 'admin.php' ) ); } } } includes/admin/class-yith-wcwl-admin.php 0000777 00000014502 15251156646 0014317 0 ustar 00 <?php /** * Admin init class * * @package YITH\Wishlist\Classes * @author YITH <plugins@yithemes.com> * @version 3.0.0 */ if ( ! defined( 'YITH_WCWL' ) ) { exit; } // Exit if accessed directly if ( ! class_exists( 'YITH_WCWL_Admin' ) ) { /** * Initiator class. Create and populate admin views. * * @since 1.0.0 */ class YITH_WCWL_Admin extends YITH_WCWL_Admin_Legacy { use YITH_WCWL_Extensible_Singleton_Trait; /** * Plugin options * * @since 1.0.0 * @var array */ public $options; /** * Constructor of the class * * @since 2.0.0 */ public function __construct() { YITH_WCWL_Admin_Panel::get_instance(); YITH_WCWL_Rendering_Method_Admin_Handler::get_instance(); // init admin processing. add_action( 'init', array( $this, 'init' ) ); // enqueue scripts. add_action( 'admin_enqueue_scripts', array( $this, 'enqueue' ), 20 ); // plugin panel options. add_filter( 'yith_plugin_fw_panel_wc_extra_row_classes', array( $this, 'mark_options_disabled' ), 10, 23 ); // add plugin links. add_filter( 'plugin_action_links_' . plugin_basename( YITH_WCWL_DIR . 'init.php' ), array( $this, 'action_links' ) ); add_filter( 'yith_show_plugin_row_meta', array( $this, 'add_plugin_meta' ), 10, 5 ); // add a post display state for special WC pages. add_filter( 'display_post_states', array( $this, 'add_display_post_states' ), 10, 2 ); } /* === ADMIN GENERAL === */ /** * Add a post display state for special WC pages in the page list table. * * @param array $post_states An array of post display states. * @param WP_Post $post The current post object. */ public function add_display_post_states( $post_states, $post ) { if ( (int) get_option( 'yith_wcwl_wishlist_page_id' ) === $post->ID ) { $post_states[ 'yith_wcwl_page_for_wishlist' ] = __( 'Wishlist Page', 'yith-woocommerce-wishlist' ); } return $post_states; } /* === INITIALIZATION SECTION === */ /** * Initiator method. Initiate properties. * * @return void * @access private * @since 1.0.0 */ public function init() { $prefix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? 'unminified/' : ''; $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min'; wp_register_style( 'yith-wcwl-material-icons', 'https://fonts.googleapis.com/icon?family=Material+Icons', array(), '3.0.1' ); wp_register_style( 'yith-wcwl-admin', YITH_WCWL_URL . 'assets/css/admin.css', array(), YITH_WCWL_VERSION ); wp_register_script( 'yith-wcwl-admin', YITH_WCWL_URL . 'assets/js/' . $prefix . 'admin/yith-wcwl' . $suffix . '.js', array( 'jquery', \YIT_Assets::wc_script_handle( 'wc-jquery-blockui' ) ), YITH_WCWL_VERSION, true ); $icons = yith_wcwl_get_plugin_icons_list(); wp_localize_script( 'yith-wcwl-admin', 'yith_wcwl_admin', array( 'plugin_icons' => array_combine( array_keys( $icons ), array_column( $icons, 'svg' ) ), 'i18n' => array( 'deleteWishlistConfirmModal' => array( 'title' => _x( 'Confirm delete', '[Admin] Delete wishlist from panel confirmation modal', 'yith-woocommerce-wishlist' ), //translators: %s is the name of the wishlist 'message' => _x( 'Are you sure you want to delete %s?', '[Admin] Delete wishlist from panel confirmation modal', 'yith-woocommerce-wishlist' ), 'confirmButton' => _x( 'Delete', '[Admin] Delete wishlist from panel confirmation modal', 'yith-woocommerce-wishlist' ), ), ), ) ); } /** * Run the installation * * @return void * @since 1.0.0 * @depreacted since 4.0 * @see YITH_WCWL_Install::maybe_install */ public function install() { wc_deprecated_function( 'YITH_WCWL_Admin::install', '4.0.0', 'YITH_WCWL_Install::maybe_install' ); yith_wcwl_install()->maybe_install(); } /** * Adds plugin actions link * * @param mixed $links Available action links. * @return array */ public function action_links( $links ) { $links = yith_add_action_links( $links, 'yith_wcwl_panel', defined( 'YITH_WCWL_PREMIUM' ), YITH_WCWL_SLUG ); return $links; } /** * Adds plugin row meta * * @param array $new_row_meta_args Array of meta for current plugin. * @param array $plugin_meta Not in use. * @param string $plugin_file Current plugin iit file path. * @param array $plugin_data Plugin info. * @param string $status Plugin status. * @param string $init_file Wishlist plugin init file. * @return array * @since 2.0.0 */ public function add_plugin_meta( $new_row_meta_args, $plugin_meta, $plugin_file, $plugin_data, $status, $init_file = 'YITH_WCWL_INIT' ) { if ( ! defined( $init_file ) || constant( $init_file ) !== $plugin_file ) { return $new_row_meta_args; } $new_row_meta_args[ 'slug' ] = 'yith-woocommerce-wishlist'; $new_row_meta_args[ 'is_premium' ] = defined( 'YITH_WCWL_PREMIUM' ); $new_row_meta_args[ 'is_extended' ] = defined( 'YITH_WCWL_EXTENDED' ); return $new_row_meta_args; } /* === WISHLIST SUBPANEL SECTION === */ /** * Adds yith-disabled class * Adds class to fields when required, and when disabled state cannot be achieved any other way (eg. by dependencies) * * @param array $classes Array of field extra classes. * @param array $field Array of field data. * * @return array Filtered array of extra classes */ public function mark_options_disabled( $classes, $field ) { if ( isset( $field[ 'id' ] ) && 'yith_wfbt_enable_integration' === $field[ 'id' ] && ! ( defined( 'YITH_WFBT' ) && YITH_WFBT ) ) { $classes[] = 'yith-disabled'; } return $classes; } /** * Load admin style. * * @return void * @since 1.0.0 */ public function enqueue() { global $woocommerce, $pagenow; if ( 'admin.php' === $pagenow && isset( $_GET[ 'page' ] ) && 'yith_wcwl_panel' === $_GET[ 'page' ] ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended wp_enqueue_style( 'yith-wcwl-admin' ); wp_enqueue_script( 'yith-wcwl-admin' ); if ( isset( $_GET[ 'tab' ], $_GET[ 'sub_tab' ] ) && 'dashboard' === $_GET[ 'tab' ] && 'dashboard-popular' === $_GET[ 'sub_tab' ] ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended wp_enqueue_style( 'yith-wcwl-material-icons' ); wp_enqueue_editor(); } } } } } includes/class-yith-wcwl-privacy.php 0000777 00000026574 15251156646 0013630 0 ustar 00 <?php /** * Privacy class; added to let customer export personal data * * @author YITH <plugins@yithemes.com> * @package YITH\Wishlist\Classes * @version 3.0.0 */ if ( ! defined( 'YITH_WCWL' ) ) { exit; } // Exit if accessed directly if ( ! class_exists( 'YITH_WCWL_Privacy' ) ) { /** * YITH WCWL Exporter * * @since 2.2.2 */ class YITH_WCWL_Privacy extends YITH_Privacy_Plugin_Abstract { /** * Constructor method * * @since 2.2.2 */ public function __construct() { parent::__construct( 'YITH WooCommerce Wishlist' ); // set up wishlist data exporter. add_filter( 'wp_privacy_personal_data_exporters', array( $this, 'register_exporter' ) ); // set up wishlist data eraser. add_filter( 'wp_privacy_personal_data_erasers', array( $this, 'register_eraser' ) ); } /** * Retrieves privacy example text for wishlist plugin * * @param string $section Section of the message to retrieve. * * @return string Privacy message * @since 2.2.2 */ public function get_privacy_message( $section ) { $content = ''; switch ( $section ) { case 'collect_and_store': $content = '<p>' . __( 'While you visit our site, we’ll track:', 'yith-woocommerce-wishlist' ) . '</p>' . '<ul>' . '<li>' . __( 'Products you’ve added to the wishlist: we’ll use this to show you and other users your favourite products, and to create targeted email campaigns.', 'yith-woocommerce-wishlist' ) . '</li>' . '<li>' . __( 'Wishlists you’ve created: we’ll keep track of the wishlists you create, and make them visible to the store staff', 'yith-woocommerce-wishlist' ) . '</li>' . '</ul>' . '<p>' . __( 'We’ll also use cookies to keep track of wishlist contents while you’re browsing our site.', 'yith-woocommerce-wishlist' ) . '</p>'; break; case 'has_access': $content = '<p>' . __( 'Members of our team have access to the information you provide us with. For example, both Administrators and Shop Managers can access:', 'yith-woocommerce-wishlist' ) . '</p>' . '<ul>' . '<li>' . __( 'Wishlist details, such as products added, date of addition, name and privacy settings of your wishlists', 'yith-woocommerce-wishlist' ) . '</li>' . '</ul>' . '<p>' . __( 'Our team members have access to this information to offer you better deals for the products you love.', 'yith-woocommerce-wishlist' ) . '</p>'; break; case 'share': case 'payments': default: break; } /** * APPLY_FILTERS: yith_wcwl_privacy_policy_content * * Filter the content of the privacy policy. * * @param string $content Privacy policy content * @param string $section Privacy policy section * * @return string */ return apply_filters( 'yith_wcwl_privacy_policy_content', $content, $section ); } /** * Register exporters for wishlist plugin * * @param array $exporters Array of currently registered exporters. * @return array Array of filtered exporters * @since 2.2.2 */ public function register_exporter( $exporters ) { $exporters['yith_wcwl_exporter'] = array( 'exporter_friendly_name' => __( 'Customer wishlists', 'yith-woocommerce-wishlist' ), 'callback' => array( $this, 'wishlist_data_exporter' ), ); return $exporters; } /** * Register eraser for wishlist plugin * * @param array $erasers Array of currently registered erasers. * @return array Array of filtered erasers * @since 2.2.2 */ public function register_eraser( $erasers ) { $erasers['yith_wcwl_eraser'] = array( 'eraser_friendly_name' => __( 'Customer wishlists', 'yith-woocommerce-wishlist' ), 'callback' => array( $this, 'wishlist_data_eraser' ), ); return $erasers; } /** * Export user wishlists (only available for authenticated users' wishlist) * * @param string $email_address Email of the users that requested export. * @param int $page Current page processed. * @return array Array of data to export * @since 2.2.2 */ public function wishlist_data_exporter( $email_address, $page ) { $done = true; $page = (int) $page; $offset = 10 * ( $page - 1 ); $user = get_user_by( 'email', $email_address ); // Check if user has an ID in the DB to load stored personal data. $data_to_export = array(); if ( $user instanceof WP_User ) { $wishlists = YITH_WCWL_Wishlist_Factory::get_wishlists( array( 'limit' => 10, 'offset' => $offset, 'user_id' => $user->ID, 'orderby' => 'ID', 'order' => 'ASC', ) ); if ( 0 < count( $wishlists ) ) { foreach ( $wishlists as $wishlist ) { $data_to_export[] = array( 'group_id' => 'yith_wcwl_wishlist', 'group_label' => __( 'Wishlists', 'yith-woocommerce-wishlist' ), 'item_id' => 'wishlist-' . $wishlist->get_id(), 'data' => $this->get_wishlist_personal_data( $wishlist ), ); } $done = 10 > count( $wishlists ); } else { $done = true; } } return array( 'data' => $data_to_export, 'done' => $done, ); } /** * Deletes user wishlists (only available for authenticated users' wishlist) * * @param string $email_address Email of the users that requested export. * @param int $page Current page processed. * @return array Result of the operation * @since 2.2.2 */ public function wishlist_data_eraser( $email_address, $page ) { global $wpdb; $page = (int) $page; $offset = 10 * ( $page - 1 ); $user = get_user_by( 'email', $email_address ); // Check if user has an ID in the DB to load stored personal data. $response = array( 'items_removed' => false, 'items_retained' => false, 'messages' => array(), 'done' => true, ); if ( ! $user instanceof WP_User ) { return $response; } $wishlists = YITH_WCWL_Wishlist_Factory::get_wishlists( array( 'limit' => 10, 'offset' => $offset, 'user_id' => $user->ID, 'orderby' => 'ID', 'order' => 'ASC', ) ); if ( 0 < count( $wishlists ) ) { foreach ( $wishlists as $wishlist ) { /** * APPLY_FILTERS: yith_wcwl_privacy_erase_wishlist_personal_data * * Filter whether to delete the personal data from the wishlist. * * @param bool $condition Whether to delete personal data or not * @param YITH_WCWL_Wishlist $wishlist Wishlist object * * @return bool */ if ( apply_filters( 'yith_wcwl_privacy_erase_wishlist_personal_data', true, $wishlist ) ) { /** * DO_ACTION: yith_wcwl_privacy_before_remove_wishlist_personal_data * * Allows to fire some action before deleting the personal data from the wishlist. * * @param YITH_WCWL_Wishlist $wishlist Wishlist object */ do_action( 'yith_wcwl_privacy_before_remove_wishlist_personal_data', $wishlist ); $wishlist->delete(); /** * DO_ACTION: yith_wcwl_privacy_remove_wishlist_personal_data * * Allows to fire some action when deleting the personal data from the wishlist. * * @param YITH_WCWL_Wishlist $wishlist Wishlist object */ do_action( 'yith_wcwl_privacy_remove_wishlist_personal_data', $wishlist ); /* Translators: %s Order number. */ $response['messages'][] = sprintf( __( 'Removed wishlist %s.', 'yith-woocommerce-wishlist' ), $wishlist->get_token() ); $response['items_removed'] = true; } else { /* Translators: %s Order number. */ $response['messages'][] = sprintf( __( 'Wishlist %s has been retained.', 'yith-woocommerce-wishlist' ), $wishlist->get_token() ); $response['items_retained'] = true; } } $response['done'] = 10 > count( $wishlists ); } else { $response['done'] = true; } return $response; } /** * Retrieves data to export for each user's wishlist * * @param \YITH_WCWL_Wishlist $wishlist Wishlist. * @return array Data to export * @since 2.2.2 */ protected function get_wishlist_personal_data( $wishlist ) { $personal_data = array(); /** * APPLY_FILTERS: yith_wcwl_privacy_export_wishlist_personal_data_props * * Filter the personal data props to export from the wishlist. * * @param array $data_to_export Personal data to export * @param YITH_WCWL_Wishlist $wishlist Wishlist object * * @return array */ $props_to_export = apply_filters( 'yith_wcwl_privacy_export_wishlist_personal_data_props', array( 'wishlist_token' => __( 'Token', 'yith-woocommerce-wishlist' ), 'wishlist_url' => __( 'Wishlist URL', 'yith-woocommerce-wishlist' ), 'wishlist_name' => __( 'Title', 'yith-woocommerce-wishlist' ), 'dateadded' => _x( 'Created on', 'date when wishlist was created', 'yith-woocommerce-wishlist' ), 'wishlist_privacy' => __( 'Visibility', 'yith-woocommerce-wishlist' ), 'items' => __( 'Items added', 'yith-woocommerce-wishlist' ), ), $wishlist ); foreach ( $props_to_export as $prop => $name ) { $value = ''; switch ( $prop ) { case 'items': $item_names = array(); $items = $wishlist->get_items(); foreach ( $items as $item ) { $product = $item->get_product(); if ( ! $product ) { continue; } $item_name = $product->get_name() . ' x ' . $item['quantity']; if ( $item->get_date_added() ) { $item_name .= ' (on: ' . $item->get_date_added() . ')'; } $item_names[] = $item_name; } $value = implode( ', ', $item_names ); break; case 'wishlist_url': $wishlist_url = $wishlist->get_url(); $value = sprintf( '<a href="%1$s">%1$s</a>', $wishlist_url ); break; case 'wishlist_name': $wishlist_name = $wishlist->get_formatted_name(); $value = $wishlist_name ? $wishlist_name : get_option( 'yith_wcwl_wishlist_title', __( 'My wishlist', 'yith-woocommerce-wishlist' ) ); break; case 'dateadded': $value = $wishlist->get_date_added(); break; case 'wishlist_privacy': $value = $wishlist->get_formatted_privacy(); break; default: if ( isset( $wishlist[ $prop ] ) ) { $value = $wishlist[ $prop ]; } break; } /** * APPLY_FILTERS: yith_wcwl_privacy_export_wishlist_personal_data_prop * * Filter the personal data value to export from the wishlist. * * @param string $value Value to export * @param string $prop Prop data to export * @param YITH_WCWL_Wishlist $wishlist Wishlist object * * @return string */ $value = apply_filters( 'yith_wcwl_privacy_export_wishlist_personal_data_prop', $value, $prop, $wishlist ); if ( $value ) { $personal_data[] = array( 'name' => $name, 'value' => $value, ); } } /** * APPLY_FILTERS: yith_wcwl_privacy_export_wishlist_personal_data * * Filter the personal data to export from the wishlist. * * @param array $personal_data Personal data to export * @param YITH_WCWL_Wishlist $wishlist Wishlist object * * @return array */ $personal_data = apply_filters( 'yith_wcwl_privacy_export_wishlist_personal_data', $personal_data, $wishlist ); return $personal_data; } } } includes/functions-yith-wcwl-update.php 0000777 00000013126 15251156646 0014325 0 ustar 00 <?php /** * YITH WishList Updates * * Functions for updating data, used by the background updater. * * Please note that these functions are invoked when the plugin is updated from a previous version, * but NOT when is newly installed. * * @package YITH\Wishlist\Functions * @version 4.0.0 */ if ( ! function_exists( 'yith_wcwl_update_100' ) ) { /** * Update from 0.x to 1.0 */ function yith_wcwl_update_100() { flush_rewrite_rules(); } } if ( ! function_exists( 'yith_wcwl_update_300' ) ) { /** * Update from version 2.0 to 3.0 * * @since 3.0.0 */ function yith_wcwl_update_300() { // update color options. $options = array( 'color_add_to_wishlist', 'color_add_to_cart', 'color_button_style_1', 'color_button_style_2', 'color_wishlist_table', ); foreach ( $options as $option ) { $base_option_name = "yith_wcwl_{$option}"; $background = get_option( "{$base_option_name}_background" ); $color = get_option( "{$base_option_name}_color" ); $border = get_option( "{$base_option_name}_border_color" ); if ( 'color_wishlist_table' !== $option ) { $background_hover = get_option( "{$base_option_name}_hover_background" ); $color_hover = get_option( "{$base_option_name}_hover_color" ); $border_hover = get_option( "{$base_option_name}_hover_border_color" ); } update_option( $base_option_name, array_merge( ! empty( $background ) ? array( 'background' => $background ) : array(), ! empty( $color ) ? array( 'text' => $color ) : array(), ! empty( $border ) ? array( 'border' => $border ) : array(), ! empty( $background_hover ) ? array( 'background_hover' => $background_hover ) : array(), ! empty( $color_hover ) ? array( 'text_hover' => $color_hover ) : array(), ! empty( $border_hover ) ? array( 'border_hover' => $border_hover ) : array() ) ); } // duplicate options. $options = array( 'yith_wcwl_color_button_style_1' => array( 'yith_wcwl_color_ask_an_estimate', ), 'yith_wcwl_color_button_style_1_hover' => array( 'yith_wcwl_color_ask_an_estimate_hover', ), 'woocommerce_promotion_mail_settings' => array( 'woocommerce_yith_wcwl_promotion_mail_settings', ), ); foreach ( $options as $original_option => $destinations ) { $option_value = get_option( $option ); if ( $option_value ) { foreach ( $destinations as $destination ) { update_option( $destination, $option_value ); } } } // button style options. $use_buttons = get_option( 'yith_wcwl_use_button' ); $use_theme_style = get_option( 'yith_wcwl_frontend_css' ); if ( 'yes' === $use_buttons && 'no' === $use_theme_style ) { $destination_value = 'button_custom'; } elseif ( 'yes' === $use_buttons ) { $destination_value = 'button_default'; } else { $destination_value = 'link'; } update_option( 'yith_wcwl_add_to_wishlist_style', $destination_value ); update_option( 'yith_wcwl_add_to_cart_style', $destination_value ); update_option( 'yith_wcwl_ask_an_estimate_style', $destination_value ); // rounded corners options. $rounded_corners = get_option( 'yith_wcwl_rounded_corners' ); $radius_value = 'yes' === $rounded_corners ? 16 : 0; update_option( 'yith_wcwl_rounded_corners_radius', $radius_value ); update_option( 'yith_wcwl_add_to_cart_rounded_corners_radius', $radius_value ); update_option( 'yith_wcwl_ask_an_estimate_rounded_corners_radius', $radius_value ); } } if ( ! function_exists( 'yith_wcwl_update_400' ) ) { /** * Run the plugin options updates for the 4.0.0 version */ function yith_wcwl_update_400() { update_option( 'yith_wcwl_rendering_method', 'php-templates' ); $icon = get_option( 'yith_wcwl_add_to_wishlist_icon', false ); if ( 'custom' === $icon ) { update_option( 'yith_wcwl_add_to_wishlist_icon_type', 'custom' ); delete_option( 'yith_wcwl_add_to_wishlist_icon' ); } // Icon options mapping. $fa_icon_mapping = array( 'fa-heart' => 'heart', 'fa-heart-o' => 'heart-outline', 'fa-bookmark' => 'bookmark', 'fa-bookmark-o' => 'bookmark-outline', 'fa-star' => 'star', 'fa-star-o' => 'star-outline', 'fa-shopping-cart' => 'shopping-cart', 'fa-cart-plus' => 'shopping-cart', 'fa-cart-arrow-down' => 'shopping-cart', 'fa-opencart' => 'shopping-cart', 'fa-shopping-basket' => 'shopping-bag', 'fa-shopping-bag' => 'shopping-bag', 'fa-envelope' => 'envelope', 'fa-envelope-o' => 'envelope-outline', ); $icon_options = array( 'yith_wcwl_add_to_wishlist_icon', 'yith_wcwl_added_to_wishlist_icon', 'yith_wcwl_ask_an_estimate_icon', 'yith_wcwl_add_to_cart_icon', ); foreach ( $icon_options as $icon_option ) { $option_value = get_option( $icon_option ); if ( array_key_exists( $option_value, $fa_icon_mapping ) ) { update_option( $icon_option, $fa_icon_mapping[ $option_value ] ); } else { delete_option( $icon_option ); } if ( in_array( $icon_option, array( 'yith_wcwl_added_to_wishlist_icon', 'yith_wcwl_ask_an_estimate_icon' ) ) ) { $types = array( 'none' => 'same', 'custom' => 'custom', ); update_option( $icon_option . '_type', array_key_exists( $option_value, $types ) ? $types[ $option_value ] : 'default' ); } } // Social icons mapping. $socials = array( 'wa', 'fb', 'pr', 'tw', 'em' ); foreach ( $socials as $social ) { $option_name = "yith_wcwl_{$social}_button_icon"; if ( ! in_array( get_option( $option_name, false ), array( 'none', 'default', 'custom' ) ) ) { update_option( $option_name, 'default' ); } } } } includes/class-yith-wcwl-rendering-method-frontend-handler.php 0000777 00000005201 15251156646 0020616 0 ustar 00 <?php /** * Class that handle the frontend rendering methods * * @since 4.0.0 * @package YITH\Wishlist\Classes * @author YITH <plugins@yithemes.com> */ defined( 'YITH_WCWL' ) || exit; if ( ! class_exists( 'YITH_WCWL_Rendering_Method_Frontend_Handler' ) ) { /** * Class that handle the frontend rendering methods */ class YITH_WCWL_Rendering_Method_Frontend_Handler { use YITH_WCWL_Singleton_Trait; use YITH_WCWL_Rendering_Method_Access_Trait; /** * Class constructor */ protected function __construct() { $this->maybe_update_preview_mode(); if(! is_customize_preview() && ! wp_doing_ajax()) add_action( 'wp_footer', array( $this, 'maybe_render_preview_mode_toggle' ) ); add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) ); } /** * Update preview mode if specific query args are set */ protected function maybe_update_preview_mode() { if ( ! empty( $_REQUEST[ self::$react_preview_key ] ) ) { self::update_preview_options( true ); } if ( ! empty( $_REQUEST[ 'yith-wcwl-preview-close-preview' ] ) ) { self::update_preview_options( false ); } } /** * Maybe render React preview mode toggle */ public function maybe_render_preview_mode_toggle() { if ( self::is_preview_mode() && ! defined( 'IFRAME_REQUEST' ) ) { $user_can_manage_rendering_method = self::current_user_can_manage_rendering_method(); $settings_url = YITH_WCWL_Admin_Panel::get_panel_page_url( 'settings' ); $convert_rendering_method_url = add_query_arg( array( self::$convert_to_react_rendering_param => 1, ), $settings_url ); $exit_from_preview_url = add_query_arg( array( self::$exit_from_preview_mode_param => 1, ), $settings_url ); yith_wcwl_get_template( 'react-preview-toggle.php', compact( 'user_can_manage_rendering_method', 'convert_rendering_method_url', 'exit_from_preview_url' ) ); } } public function enqueue_scripts() { $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min'; $prefix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? 'unminified/' : ''; wp_register_style( 'yith-wcwl-rendering-methods-frontend', YITH_WCWL_ASSETS_CSS_URL . 'frontend/rendering-methods.css', array(), YITH_WCWL_VERSION ); wp_register_script( 'yith-wcwl-rendering-methods-frontend', YITH_WCWL_ASSETS_JS_URL . $prefix . 'rendering-methods' . $suffix . '.js', array( 'jquery' ), YITH_WCWL_VERSION, true ); if ( self::is_preview_mode() ) { wp_enqueue_style( 'yith-wcwl-rendering-methods-frontend' ); wp_enqueue_script( 'yith-wcwl-rendering-methods-frontend' ); } } } } includes/class-yith-wcwl-wishlist.php 0000777 00000065070 15251156646 0014013 0 ustar 00 <?php /** * Wishlist class * * @package YITH\Wishlist\Classes\Wishlists * @author YITH <plugins@yithemes.com> * @version 3.0.0 */ if ( ! defined( 'YITH_WCWL' ) ) { exit; } // Exit if accessed directly if ( ! class_exists( 'YITH_WCWL_Wishlist' ) ) { /** * This class describes Wishlist object, and it is meant to be used whenever a wishlist needs to be retrieved * It is an abstract class to account for different type of wishlists; system will determine wishlist type basing * on user visiting the site * * @since 3.0.0 */ class YITH_WCWL_Wishlist extends WC_Data implements ArrayAccess { /** * Wishlist token (Unique identifier) * * @var string */ protected $token = ''; /** * Wishlist Data array * * @var array */ protected $data; /** * Wishlist items will be stored here, sometimes before they persist in the DB. * * @since 3.0.0 * @var array */ protected $items = array(); /** * Wishlist items that need deleting are stored here. * * @since 3.0.0 * @var array */ protected $items_to_delete = array(); /** * Stores meta in cache for future reads. * * A group must be set to enable caching. * * @var string */ protected $cache_group = 'wishlists'; /* === MAGIC METHODS === */ /** * Constructor * * @param int|string|\YITH_WCWL_Wishlist $wishlist Wishlist identifier. * * @throws Exception When not able to load Data Store class. */ public function __construct( $wishlist = 0 ) { // set default values. $this->data = array( /** * APPLY_FILTERS: yith_wcwl_default_wishlist_privacy * * Filter the default Wishlist privacy. * * @param string $wishlist_privacy Default wishlist privacy. Possible values are 0 (Public), 1 (Shared) or 2 (Private) * * @return string */ 'privacy' => apply_filters( 'yith_wcwl_default_wishlist_privacy', 0 ), 'user_id' => 0, 'session_id' => '', /** * APPLY_FILTERS: yith_wcwl_default_wishlist_name * * Filter the default Wishlist name. * * @param string $wishlist_name Default wishlist name * * @return string */ 'name' => apply_filters( 'yith_wcwl_default_wishlist_name', '' ), /** * APPLY_FILTERS: yith_wcwl_default_wishlist_slug * * Filter the default Wishlist slug. * * @param string $wishlist_slug Default wishlist slug * * @return string */ 'slug' => apply_filters( 'yith_wcwl_default_wishlist_slug', '' ), 'token' => '', 'is_default' => 0, 'date_added' => '', 'expiration' => '', ); parent::__construct(); if ( is_numeric( $wishlist ) && $wishlist > 0 ) { $this->set_id( $wishlist ); } elseif ( $wishlist instanceof self ) { $this->set_id( $wishlist->get_id() ); } elseif ( is_string( $wishlist ) ) { $this->set_token( $wishlist ); } else { $this->set_object_read( true ); } $this->data_store = WC_Data_Store::load( 'wishlist' ); if ( $this->get_id() > 0 || ! empty( $this->get_token() ) ) { $this->data_store->read( $this ); } } /* === HELPERS === */ /** * Return number of items for current wishlist * * @return int Count of items */ public function count_items() { return count( $this->get_items() ); } /** * Check whether wishlist was created for unautheticated user * * @return bool */ public function is_session_based() { return (bool) $this->get_session_id(); } /** * Returns true when wishlist is default * * @return bool Whether wishlist is default or not */ public function is_default() { return $this->get_is_default(); } /** * Check whether wishlist was created for authenticated user * * @return bool */ public function has_owner() { return (bool) $this->get_user_id(); } /** * Check if current user is owner of this wishlist (works both for authenticated users & guests) * * @param string|int|bool $current_user Optional user identifier, in the form of a User ID or session id; false for default. * @return bool */ public function is_current_user_owner( $current_user = false ) { $user_id = $this->get_user_id(); $session_id = $this->get_session_id(); $is_owner = false; if ( $current_user && ( (int) $current_user === $user_id || $current_user === $session_id ) ) { $is_owner = true; } if ( $this->has_owner() && is_user_logged_in() && get_current_user_id() === $user_id ) { $is_owner = true; } if ( $this->is_session_based() && YITH_WCWL_Session::get_instance()->maybe_get_session_id() === $session_id ) { $is_owner = true; } /** * APPLY_FILTERS: yith_wcwl_is_current_user_owner * * Filters whether the current user is the wishlist owner. * * @param bool $is_owner Whether the current user is the wishlist owner * * @return bool */ return apply_filters( 'yith_wcwl_is_current_user_owner', $is_owner ); } /** * Check whether current user can perform a specific action on wishlist * * Accepted capabilities: * * view * * update_wishlist * * add_to_wishlist * * remove_from_wishlist * * move_to_another_wishlist * * ask_an_estimate * * sort_items * * update_quantity * * download_pdf * * @param string $capability Capability to check; default "view". * @param string|int|bool $current_user Optional user identifier, in the form of a User ID or session id; false for default. * @return bool */ public function current_user_can( $capability = 'view', $current_user = false ) { // admin can do anything by default. /** * APPLY_FILTERS: yith_wcwl_admin_can * * Filter whether admin can perform a specific action on wishlist. * * @param bool $user_can Whether admin can perform some actions on the wishlist * @param string $capability Capability * @param WP_User $current_user Current user * @param YITH_WCWL_Wishlist $wishlist Wishlist object * * @return bool */ if ( is_user_logged_in() && current_user_can( 'manage_woocommerce' ) && apply_filters( 'yith_wcwl_admin_can', true, $capability, $current_user, $this ) ) { // phpcs:ignore WordPress.WP.Capabilities.Unknown return true; } // for other users, perform checks over capability required. switch ( $capability ) { case 'view': $can = $this->is_current_user_owner( $current_user ); if ( ! $can && $this->has_privacy( array( 'public', 'shared' ) ) ) { $can = true; } break; default: $can = $this->is_current_user_owner( $current_user ); break; } /** * APPLY_FILTERS: yith_wcwl_current_user_can * * Filter whether current user can perform a specific action on wishlist. * * @param bool $user_can Whether current user can perform some actions on the wishlist * @param string $capability Capability * @param WP_User $current_user Current user * @param YITH_WCWL_Wishlist $wishlist Wishlist object * * @return bool */ return apply_filters( 'yith_wcwl_current_user_can', $can, $capability, $current_user, $this ); } /* === GETTERS === */ /** * Get wishlist token * * @return string Wishlist unique token */ public function get_token() { return $this->token; } /** * Get privacy visibility * * @param string $context Context. * @return int Wishlist visibility (0 => public, 1 => shared, 2 => private) */ public function get_privacy( $context = 'view' ) { return (int) $this->get_prop( 'privacy', $context ); } /** * Get formatted privacy name * * @param string $context Context. * @return string Formatted privacy value */ public function get_formatted_privacy( $context = 'view' ) { $privacy = $this->get_privacy( $context ); $formatted_privacy = yith_wcwl_get_privacy_label( $privacy ); /** * APPLY_FILTERS: yith_wcwl_wishlist_formatted_privacy * * Filter the formatted wishlist privacy label. * * @param string $formatted_privacy Formatted privacy label * @param int $privacy Privacy option * @param YITH_WCWL_Wishlist $wishlist Wishlist object * @param string $context Context * * @return string */ return apply_filters( 'yith_wcwl_wishlist_formatted_privacy', $formatted_privacy, $privacy, $this, $context ); } /** * Checks if current wishlist has a specific privacy value * Method will accept both numeric privacy values and privacy labels * * @param int|string|array $privacy Privacy value (0|1|2) or label (public|shared|private), or array of acceptable values. * @return bool Whether wishlist matched privacy test */ public function has_privacy( $privacy ) { $wishlist_privacy = $this->get_privacy( 'edit' ); $has_privacy = false; if ( is_array( $privacy ) && ! empty( $privacy ) ) { foreach ( $privacy as $test_value ) { // return true if wishlist has any of the privacy value submitted. if ( $this->has_privacy( $test_value ) ) { return true; } } } elseif ( is_string( $privacy ) ) { $has_privacy = yith_wcwl_get_privacy_value( $privacy ) === $wishlist_privacy; } else { $has_privacy = $privacy === $wishlist_privacy; } return $has_privacy; } /** * Get owner id * * @param string $context Context. * @return int Wishlist owner id */ public function get_user_id( $context = 'view' ) { return (int) $this->get_prop( 'user_id', $context ); } /** * Get session id * * @param string $context Context. * @return int Wishlist owner id */ public function get_session_id( $context = 'view' ) { return $this->get_prop( 'session_id', $context ); } /** * Get wishlist name * * @param string $context Context. * @return string Wishlist name */ public function get_name( $context = 'view' ) { return wc_clean( stripslashes( $this->get_prop( 'name', $context ) ) ); } /** * Get wishlist formatted name * * @param string $context Context. * @return string Formatted name */ public function get_formatted_name( $context = 'view' ) { $name = $this->get_name( $context ); if ( $this->is_default() && ! $name ) { /** * APPLY_FILTERS: yith_wcwl_default_wishlist_formatted_title * * Filter the default wishlist title. * * @param string $title Default wishlist title * * @return string */ $name = apply_filters( 'yith_wcwl_default_wishlist_formatted_title', get_option( 'yith_wcwl_wishlist_title', __( 'My wishlist', 'yith-woocommerce-wishlist' ) ) ); } /** * APPLY_FILTERS: yith_wcwl_wishlist_formatted_title * * Filter the formatted wishlist title. * * @param string $title Formatted wishlist title * * @return string */ return apply_filters( 'yith_wcwl_wishlist_formatted_title', $name ); } /** * Get wishlist slug * * @param string $context Context. * @return string Wishlist slug */ public function get_slug( $context = 'view' ) { return $this->get_prop( 'slug', $context ); } /** * Check if wishlist is default one for the user * * @param string $context Context. * @return bool Whether wishlist is default one or not */ public function get_is_default( $context = 'view' ) { return (bool) $this->get_prop( 'is_default', $context ); } /** * Get wishlist date added * * @param string $context Context. * @return \WC_DateTime|string Wishlist date of creation */ public function get_date_added( $context = 'view' ) { $date_added = $this->get_prop( 'date_added', $context ); if ( $date_added && 'view' === $context ) { return $date_added->date_i18n( 'Y-m-d H:i:s' ); } return $date_added; } /** * Get formatted wishlist date added * * @param string $format Date format (if empty, WP date format will be applied). * @return string Wishlist date of creation */ public function get_date_added_formatted( $format = '' ) { $date_added = $this->get_date_added( 'edit' ); if ( $date_added ) { $format = $format ? $format : get_option( 'date_format' ); return $date_added->date_i18n( $format ); } return ''; } /** * Get wishlist date added * * @param string $context Context. * @return \WC_DateTime|string Wishlist date of creation */ public function get_expiration( $context = 'view' ) { $expiration = $this->get_prop( 'expiration', $context ); if ( $expiration && 'view' === $context ) { return $expiration->date_i18n( 'Y-m-d H:i:s' ); } return $expiration; } /** * Get formatted wishlist expiration added * * @param string $format Date format (if empty, WP date format will be applied). * @return string Wishlist date of expiration */ public function get_expiration_formatted( $format = '' ) { $expiration = $this->get_expiration( 'edit' ); if ( $expiration ) { $format = $format ? $format : get_option( 'date_format' ); return $expiration->date_i18n( $format ); } return ''; } /** * Retrieve email of the owner of the wishlist (if any) * * @return string|bool Email of wishlist owner (or false, if no registered owner) */ public function get_user_email() { $user_id = $this->get_user_id(); if ( ! $user_id ) { return false; } $user = get_userdata( $user_id ); return $user->user_email; } /** * Retrieve first name of the owner of the wishlist (if any) * * @return string|bool First name of wishlist owner (or false, if no registered owner) */ public function get_user_first_name() { $user_id = $this->get_user_id(); if ( ! $user_id ) { return false; } $user = get_userdata( $user_id ); return $user->first_name; } /** * Retrieve last name of the owner of the wishlist (if any) * * @return string|bool Last name of wishlist owner (or false, if no registered owner) */ public function get_user_last_name() { $user_id = $this->get_user_id(); if ( ! $user_id ) { return false; } $user = get_userdata( $user_id ); return $user->last_name; } /** * Return owner formatted name * * @return string User formatted name */ public function get_user_formatted_name() { $user_id = $this->get_user_id(); if ( ! $user_id ) { return false; } $user = get_userdata( $user_id ); $first_name = $user->first_name; $last_name = $user->last_name; $email = $user->user_email; $formatted_name = $email; if ( ! empty( $first_name ) || ! empty( $last_name ) ) { $formatted_name .= " <{$first_name} {$last_name}>"; } return $formatted_name; } /** * Return url to visit wishlist * * @return string Url to the wishlist */ public function get_url() { return YITH_WCWL()->get_wishlist_url( 'view/' . $this->get_token() ); } /** * Get url to download the wishlist as PDF file * * @return string Url to download */ public function get_download_url() { /** * APPLY_FILTERS: yith_wcwl_wishlist_download_url * * Filter the URL to download the wishlist PDF. * * @param string $download_url PDF download URL * @param YITH_WCWL_Wishlist $wishlist Wishlist object * * @return string */ return apply_filters( 'yith_wcwl_wishlist_download_url', wp_nonce_url( add_query_arg( 'download_wishlist', $this->get_id() ), 'download_wishlist', 'download_nonce' ), $this ); } /** * Get url to delete the wishlist * * @return string Url to delete the wishlist */ public function get_delete_url() { /** * APPLY_FILTERS: yith_wcwl_wishlist_delete_url * * Filter the URL to delete the wishlist. * * @param string $delete_url Delete wishlist URL * @param YITH_WCWL_Wishlist $wishlist Wishlist object * * @return string */ return apply_filters( 'yith_wcwl_wishlist_delete_url', wp_nonce_url( add_query_arg( 'wishlist_id', $this->get_id(), YITH_WCWL()->get_wishlist_url( 'manage' ) ), 'yith_wcwl_delete_action', 'yith_wcwl_delete' ), $this ); } /* === SETTERS === */ /** * Set wishlist token * * @param string $token Wishlist unique token. */ public function set_token( $token ) { $this->token = (string) $token; } /** * Set privacy visibility * * @param int $privacy Wishlist visibility (0 => public, 1 => shared, 2 => private). */ public function set_privacy( $privacy ) { $privacy = intval( $privacy ); if ( in_array( $privacy, array( 0, 1, 2 ), true ) ) { $this->set_prop( 'privacy', $privacy ); } } /** * Set owner id * * @param int $user_id Wishlist owner id. */ public function set_user_id( $user_id ) { $this->set_prop( 'user_id', $user_id ); } /** * Set session id * * @param int $session_id Wishlist session. */ public function set_session_id( $session_id ) { $this->set_prop( 'session_id', $session_id ); } /** * Set wishlist name * * @param string $name Wishlist name. */ public function set_name( $name ) { $this->set_prop( 'name', $name ); } /** * Set wishlist slug * * @param string $slug Wishlist slug. */ public function set_slug( $slug ) { $this->set_prop( 'slug', substr( $slug, 0, 200 ) ); } /** * Set if wishlist is default one for the user * * @param bool $is_default Whether wishlist is default one or not. */ public function set_is_default( $is_default ) { $this->set_prop( 'is_default', $is_default ); } /** * Set wishlist date added * * @param int|string $date_added Wishlist date of creation (timestamp or date). */ public function set_date_added( $date_added ) { $this->set_date_prop( 'date_added', $date_added ); } /** * Set wishlist date added * * @param int|string $expiration Wishlist date of creation (timestamp or date). */ public function set_expiration( $expiration ) { $this->set_date_prop( 'expiration', $expiration ); } /** * Sets a prop for a setter method. * * This stores changes in a special array so we can track what needs saving * the the DB later. * * @param string $prop Name of prop to set. * @param mixed $value Value of the prop. * @since 3.0.0 */ protected function set_prop( $prop, $value ) { parent::set_prop( $prop, $value ); if ( 'name' === $prop ) { $this->set_slug( sanitize_title_with_dashes( $this->get_name() ) ); } } /* === CRUD METHODS === */ /** * Save data to the database. * * @return int order ID * @since 3.0.0 */ public function save() { if ( $this->data_store ) { // Trigger action before saving to the DB. Allows you to adjust object props before save. do_action( 'woocommerce_before_' . $this->object_type . '_object_save', $this, $this->data_store ); if ( $this->get_id() ) { $this->data_store->update( $this ); } else { $this->data_store->create( $this ); } } $this->save_items(); return $this->get_id(); } /* === ITEM METHODS === */ /** * Returns true when wishlist is non-empty * * @return bool Whether wishlist is empty or not */ public function has_items() { $items = $this->get_items(); return ! empty( $items ); } /** * Return an array of items/products within this wishlist. * * @param int $limit When differs from 0, method will return at most this number of items. * @param int $offset When @see $limit is set, this will be used as offset to retrieve items. * * @return YITH_WCWL_Wishlist_Item[] */ public function get_items( $limit = 0, $offset = 0 ) { if ( ! $this->items ) { $this->items = array_filter( $this->data_store->read_items( $this ) ); } /** * APPLY_FILTERS: yith_wcwl_wishlist_get_items * * Filter the wishlist items. * * @param array $wishlist_items Wishlist items * @param YITH_WCWL_Wishlist $wishlist Wishlist object * * @return string */ $items = apply_filters( 'yith_wcwl_wishlist_get_items', $this->items, $this ); if ( $limit ) { $items = array_slice( $items, $offset, $limit ); } return $items; } /** * Save all wishlist items which are part of this wishlist. * * @return void */ protected function save_items() { foreach ( $this->items_to_delete as $item ) { $item->delete(); } $this->items_to_delete = array(); // Add/save items. foreach ( $this->items as $product_id => $item ) { if ( $item->get_wishlist_id() !== $this->get_id() ) { $item->set_wishlist_id( $this->get_id() ); } $item->save(); } } /** * Check whether a product is already in list * * @param int $product_id Product id. * @return bool Whether product is already in list */ public function has_product( $product_id ) { $product_id = yith_wcwl_object_id( $product_id, 'product', true, 'default' ); return array_key_exists( $product_id, $this->get_items() ); } /** * Retrieves a product from the list (if set) * * @param int $product_id Product ID. * @return \YITH_WCWL_Wishlist_Item|bool Item on success, false on failure */ public function get_product( $product_id ) { $product_id = yith_wcwl_object_id( $product_id, 'product', true, 'default' ); if ( ! $this->has_product( $product_id ) ) { return false; } $items = $this->get_items(); return $items[ $product_id ]; } /** * Add a product to the list * * @param int $product_id Product id. * * @return \YITH_WCWL_Wishlist_Item|bool Item on success; false on failure */ public function add_product( $product_id ) { $product_id = yith_wcwl_object_id( $product_id, 'product', true, 'default' ); $product = wc_get_product( $product_id ); if ( ! $product || $this->has_product( $product_id ) ) { return false; } try { $item = new YITH_WCWL_Wishlist_Item(); $item->set_product_id( $product_id ); $item->set_wishlist_id( $this->get_id() ); $item->set_user_id( $this->get_user_id() ); $this->items[ $product_id ] = $item; return $item; } catch ( Exception $e ) { return false; } } /** * Remove product from the list * * @param int $product_id Product id. * @return bool Status of the operation */ public function remove_product( $product_id ) { $product_id = yith_wcwl_object_id( $product_id, 'product', true, 'default' ); if ( ! $this->has_product( $product_id ) ) { return false; } $this->items_to_delete[] = $this->items[ $product_id ]; unset( $this->items[ $product_id ] ); return true; } /** * Check whether an item is already in list (by item id) * * @param int $item_id Item id. * @return bool Whether item is already in list */ public function has_item( $item_id ) { return in_array( (int) $item_id, array_column( $this->get_items(), 'id' ), true ); } /** * Retrieve a specific item of the list, by item id * * @param int $item_id Item id. * @return \YITH_WCWL_Wishlist_Item|bool Item to retrieve, or false on error */ public function get_item( $item_id ) { if ( ! $this->has_item( $item_id ) ) { return false; } $items = array_combine( array_column( $this->get_items(), 'id' ), $this->get_items() ); return $items[ $item_id ]; } /** * Add new item to the list * * @param \YITH_WCWL_Wishlist_Item $item Wishlist item. * @return \YITH_WCWL_Wishlist_Item|bool Item on success; false on failure */ public function add_item( $item ) { if ( ! $item->get_product_id() || $this->has_item( $item->get_id() ) ) { return false; } $item->set_wishlist_id( $this->get_id() ); $item->set_user_id( $this->get_user_id() ); $this->items[ $item->get_product_id() ] = $item; return $item; } /** * Remove item from the list * * @param int $item_id Item id. * @return bool status of the operation */ public function remove_item( $item_id ) { if ( ! $this->has_item( $item_id ) ) { return false; } $item = $this->get_item( $item_id ); $this->items_to_delete[] = $item; unset( $this->items[ $item->get_product_id() ] ); return true; } /* === ARRAY ACCESS METHODS === */ /** * OffsetSet for ArrayAccess. * * @param string $offset Offset. * @param mixed $value Value. */ #[\ReturnTypeWillChange] public function offsetSet( $offset, $value ) { $offset = $this->map_legacy_offsets( $offset ); if ( array_key_exists( $offset, $this->data ) ) { $setter = "set_$offset"; if ( is_callable( array( $this, $setter ) ) ) { $this->$setter( $value ); } } } /** * OffsetUnset for ArrayAccess. * * @param string $offset Offset. */ #[\ReturnTypeWillChange] public function offsetUnset( $offset ) { $offset = $this->map_legacy_offsets( $offset ); if ( array_key_exists( $offset, $this->data ) ) { unset( $this->data[ $offset ] ); } if ( array_key_exists( $offset, $this->changes ) ) { unset( $this->changes[ $offset ] ); } } /** * OffsetExists for ArrayAccess. * * @param string $offset Offset. * @return bool */ #[\ReturnTypeWillChange] public function offsetExists( $offset ) { $offset = $this->map_legacy_offsets( $offset ); $getter = "get_$offset"; if ( is_callable( array( $this, $getter ) ) ) { return true; } return false; } /** * OffsetGet for ArrayAccess. * * @param string $offset Offset. * @return mixed */ #[\ReturnTypeWillChange] public function offsetGet( $offset ) { $offset = $this->map_legacy_offsets( $offset ); $getter = "get_$offset"; if ( is_callable( array( $this, $getter ) ) ) { return $this->$getter(); } return null; } /** * Map legacy indexes to new properties, for ArrayAccess * * @param string $offset Offset to search. * @return string Mapped offset */ protected function map_legacy_offsets( $offset ) { $legacy_offset = $offset; if ( false !== strpos( $offset, 'wishlist_' ) ) { $offset = str_replace( 'wishlist_', '', $offset ); } if ( 'dateadded' === $offset ) { $offset = 'date_added'; } if ( 'first_name' === $offset ) { $offset = 'user_first_name'; } if ( 'last_name' === $offset ) { $offset = 'user_last_name'; } /** * APPLY_FILTERS: yith_wcwl_wishlist_map_legacy_offsets * * Filter the wishlist legacy offsets to index to new properties. * * @param string $offset Offset to search * @param string $legacy_offset Legacy offset * * @return string */ return apply_filters( 'yith_wcwl_wishlist_map_legacy_offsets', $offset, $legacy_offset ); } } } includes/class-yith-wcwl-install.php 0000777 00000006005 15251156646 0013604 0 ustar 00 <?php /** * Install file * * @package YITH\Wishlist\Classes * @author YITH <plugins@yithemes.com> * @version 3.0.0 */ defined( 'YITH_WCWL' ) || exit; // Exit if accessed directly. if ( ! class_exists( 'YITH_WCWL_Install' ) ) { /** * Install plugin table and create the wishlist page * * @since 1.0.0 */ class YITH_WCWL_Install { use YITH_WCWL_Singleton_Trait; const VERSION_OPTION = 'yith_wcwl_version'; /** * Constructor. * * @since 1.0.0 */ public function __construct() { YITH_WCWL_DB::define_tables(); add_action( 'init', array( $this, 'maybe_install' ) ); } /** * Run the installation * * @return void * @since 1.0.0 */ public function maybe_install() { if ( wp_doing_ajax() ) { return; } YITH_WCWL_DB::maybe_update(); $current_version = get_option( self::VERSION_OPTION ); if ( ! $current_version ) { $this->init(); } elseif ( version_compare( $current_version, YITH_WCWL_VERSION, '<' ) ) { YITH_WCWL_Install()->update( $current_version ); /** * DO_ACTION: yith_wcwl_updated * * Allows to fire some action when the plugin database is updated. */ do_action( 'yith_wcwl_updated' ); } // Plugin installed. /** * DO_ACTION: yith_wcwl_installed * * Allows to fire some action when the plugin database is installed. */ do_action( 'yith_wcwl_installed' ); } /** * Init pages and version of the plugin * * @since 1.0.0 */ public function init() { $this->add_pages(); $this->register_current_version(); } /** * Update db structure of the plugin * * @param string $current_version Version from which we're updating. * * @ince 3.0.0 */ public function update( $current_version ) { include_once YITH_WCWL_INC . '/functions-yith-wcwl-update.php'; if ( version_compare( $current_version, '1.0.0', '<' ) ) { yith_wcwl_update_100(); } if ( version_compare( $current_version, '3.0.0', '<' ) ) { yith_wcwl_update_300(); } if ( version_compare( $current_version, '4.0.0', '<' ) ) { yith_wcwl_update_400(); } $this->register_current_version(); } /** * Register current version of plugin and database structure * * @since 3.0.0 */ public function register_current_version() { delete_option( 'yith_wcwl_version' ); update_option( 'yith_wcwl_version', YITH_WCWL_VERSION ); } /** * Check if the table of the plugin already exists. * * @return bool * @since 1.0.0 */ public function is_installed() { return YITH_WCWL_DB::has_tables(); } /** * Add a page "Wishlist". * * @return void * @since 1.0.0 */ private function add_pages() { if ( function_exists( 'wc_create_page' ) ) { wc_create_page( sanitize_title_with_dashes( _x( 'wishlist', 'page_slug', 'yith-woocommerce-wishlist' ) ), 'yith_wcwl_wishlist_page_id', __( 'Wishlist', 'yith-woocommerce-wishlist' ), '<!-- wp:shortcode -->[yith_wcwl_wishlist]<!-- /wp:shortcode -->' ); } } } } includes/traits/trait-yith-wcwl-extensible-singleton-trait.php 0000777 00000002644 15251156646 0020752 0 ustar 00 <?php /** * Extensible Singleton class trait. * Useful to allow only one instance for Extended/Premium classes. * * @package YITH\Wishlist\Traits * @author YITH <plugins@yithemes.com> */ if ( ! trait_exists( 'YITH_WCWL_Extensible_Singleton_Trait' ) ) { /** * Extensible Singleton trait. */ trait YITH_WCWL_Extensible_Singleton_Trait { /** * Instance of the class. * * @var self|null */ private static $instance = null; /** * Constructor * * @return void */ protected function __construct() { } /** * Get class instance. * * @return self */ final public static function get_instance() { if ( is_null( self::$instance ) ) { $extensions = array( '_Premium', '_Extended' ); // Allowed extensions ordered by priority. $called_class = get_called_class(); $class = $called_class; $extensions_regex = array_map( function ( $extension ) { return '/' . preg_quote( $extension, '/' ) . '$/'; }, $extensions ); $base_class = preg_replace( $extensions_regex, '', $called_class ); foreach ( $extensions as $extension ) { $extension_class = $base_class . $extension; if ( class_exists( $extension_class ) ) { $class = $extension_class; break; } } self::$instance = new $class(); } return self::$instance; } /** * Prevent cloning. */ private function __clone() { } } } includes/traits/trait-yith-wcwl-rendering-method-access-trait.php 0000777 00000010245 15251156646 0021276 0 ustar 00 <?php /** * Trait to access to Template rendering method * * @since 4.0.0 * @package YITH\Wishlist\Traits * @author YITH <plugins@yithemes.com> */ if ( ! trait_exists( 'YITH_WCWL_Rendering_Method_Access_Trait' ) ) { trait YITH_WCWL_Rendering_Method_Access_Trait { /** * The option name that store the templates rendering method. * * @var string */ private static $rendering_method_option_name = 'yith_wcwl_rendering_method'; /** * The option name that store the templates rendering method. * * @var string */ private static $rendering_method = null; /** * The cookie name * * @var string */ private static $react_preview_key = 'yith-wcwl-react-preview-mode'; /** * The query param used to trigger the exit from preview mode * * @var string */ private static $exit_from_preview_mode_param = 'yith-wcwl-exit-from-preview-mode'; /** * The query param used to convert the rendering method using React Components * * @var string */ private static $convert_to_react_rendering_param = 'yith-wcwl-convert-to-react'; /** * Store whether the rendering method has been updated * * @var string */ private static $updated_rendering_method = false; /** * Get the templates rendering method option value * * @param string $default The default value. * @param bool $force_update Whether is needed to force the retrieving of the option value. * * @return string */ public static function get_rendering_method( $default = 'react-components', $force_update = false ) { if ( self::is_preview_mode() ) { self::$rendering_method = 'react-components'; } if ( is_null( self::$rendering_method ) || $force_update ) { // TODO: handle $force_update in preview mode. self::$rendering_method = self::get_rendering_method_option( $default ); } return apply_filters( 'yith_wcwl_rendering_method', self::$rendering_method, $default, $force_update ); } /** * get rendering method option value * * @param mixed $default The default value. * * @return string */ public static function get_rendering_method_option( $default = 'react-components' ) { if ( is_null( self::$rendering_method ) ) { self::$rendering_method = get_option( self::$rendering_method_option_name, $default ); } return self::$rendering_method; } /** * Set the templates rendering method option value * * @param string $value The value to set. * * @return string */ public static function update_rendering_method( $value ) { if ( self::current_user_can_manage_rendering_method() ) { self::$rendering_method = null; return update_option( self::$rendering_method_option_name, $value ); } } /** * Check whether the current user can manage the rendering method * * @return bool */ public static function current_user_can_manage_rendering_method() { return current_user_can( 'manage_options' ); } /** * Check if is the React rendering preview mode * * @return bool */ public static function is_preview_mode() { if ( 'php-templates' === self::get_rendering_method_option() ) { if ( yith_getcookie( self::$react_preview_key ) ) { return true; } if ( is_user_logged_in() ) { $user_id = function_exists( 'get_current_user_id' ) ? get_current_user_id() : false; if ( $user_id ) { if ( get_user_meta( $user_id, self::$react_preview_key, true ) ) { return true; } } } } return false; } /** * Check if is using the php-templates rendering method * * @return bool */ public static function is_php_templates_mode() { return 'php-templates' === self::get_rendering_method(); } /** * Update options related to preview rendering method (Session cookie and User meta if is logged id) * * @param bool $value The options value * * @return void */ protected function update_preview_options( $value ) { yith_setcookie( self::$react_preview_key, $value ); $user_id = function_exists( 'get_current_user_id' ) ? get_current_user_id() : false; if ( $user_id ) { update_user_meta( $user_id, self::$react_preview_key, $value ); } } } } includes/traits/trait-yith-wcwl-singleton-trait.php 0000777 00000001223 15251156646 0016602 0 ustar 00 <?php /** * Singleton class trait. * * @package YITH\Wishlist\Traits */ defined( 'YITH_WCWL' ) || exit; // Exit if accessed directly /** * Singleton trait. */ trait YITH_WCWL_Singleton_Trait { /** * The single instance of the class. * * @var self */ protected static $instance = null; /** * Constructor * * @return void */ protected function __construct() { } /** * Get class instance. * * @return self */ final public static function get_instance() { return ! is_null( static::$instance ) ? static::$instance : static::$instance = new static(); } /** * Prevent cloning. */ private function __clone() { } } includes/class-yith-wcwl-frontend.php 0000777 00000133035 15251156646 0013761 0 ustar 00 <?php /** * Init class * * @author YITH <plugins@yithemes.com> * @package YITH\Wishlist\Classes * @version 3.0.0 */ defined( 'YITH_WCWL' ) || exit; // Exit if accessed directly if ( ! class_exists( 'YITH_WCWL_Frontend' ) ) { /** * Initiator class. Install the plugin database and load all needed stuffs. * * @since 1.0.0 */ class YITH_WCWL_Frontend extends YITH_WCWL_Frontend_Legacy { /** * Plugin version * * @var string * @since 1.0.0 */ public $version; /** * Plugin database version * * @var string * @since 1.0.0 */ public $db_version; /** * Constructor * * @since 1.0.0 */ public function __construct() { // Leave for retro-compatibility. $this->version = YITH_WCWL_VERSION; $this->db_version = YITH_WCWL_DB::DB_VERSION; define( 'YITH_WCWL_DB_VERSION', YITH_WCWL_DB::DB_VERSION ); // add filter for font-awesome compatibility. add_filter( 'option_yith_wcwl_add_to_wishlist_icon', array( $this, 'update_font_awesome_classes' ) ); add_filter( 'option_yith_wcwl_add_to_cart_icon', array( $this, 'update_font_awesome_classes' ) ); // init class. add_action( 'init', array( $this, 'init' ), 0 ); // templates. add_action( 'init', array( $this, 'add_button' ) ); add_filter( 'body_class', array( $this, 'add_body_class' ), 90 ); add_action( 'template_redirect', array( $this, 'add_nocache_headers' ) ); add_action( 'wp_head', array( $this, 'add_noindex_header' ) ); add_filter( 'wp_robots', array( $this, 'add_noindex_robots' ) ); add_action( 'yith_wcwl_before_wishlist_title', array( $this, 'print_notices' ) ); add_action( 'yith_wcwl_wishlist_before_wishlist_content', array( $this, 'wishlist_header' ), 10, 1 ); add_action( 'yith_wcwl_wishlist_main_wishlist_content', array( $this, 'main_wishlist_content' ), 10, 1 ); add_action( 'yith_wcwl_wishlist_after_wishlist_content', array( $this, 'wishlist_footer' ), 10, 1 ); // template modifications. add_filter( 'post_class', array( $this, 'add_products_class_on_loop' ), 20, 3 ); // scripts. add_action( 'wp_head', array( $this, 'detect_javascript' ), 0 ); add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_styles_and_stuffs' ) ); // add YITH WooCommerce Frequently Bought Together Premium shortcode. add_action( 'yith_wcwl_after_wishlist_form', array( $this, 'yith_wcfbt_shortcode' ), 10, 1 ); add_filter( 'woocommerce_add_to_cart_redirect', array( $this, 'yith_wfbt_redirect_after_add_to_cart' ), 10, 1 ); // YITH WCWL Loaded. /** * DO_ACTION: yith_wcwl_loaded * * Allows to fire some action when the frontend class has loaded all the requirements. */ do_action( 'yith_wcwl_loaded' ); YITH_WCWL_Rendering_Method_Frontend_Handler::get_instance(); } /** * Initiator method. * * @return void * @since 1.0.0 */ public function init() { // update cookie from old version to new one. $this->update_cookies(); $this->destroy_serialized_cookies(); $this->convert_cookies_to_session(); // register assets. $this->register_styles(); $this->register_scripts(); } /* === ADD TO WISHLIST */ /** * Add the "Add to Wishlist" button. Needed to use in wp_head hook. * * @return void * @since 1.0.0 */ public function add_button() { $this->add_button_for_single(); $this->add_button_for_loop(); // Add the link "Add to wishlist" for Gutenberg blocks. add_filter( 'woocommerce_blocks_product_grid_item_html', array( $this, 'add_button_for_blocks_product_grid_item' ), 10, 3 ); } /** * Add ATW button to Single product page * Accounts for both Legacy Templates and Blockified ones * * @return void * @since 3.24.0 */ public function add_button_for_single() { // Add the link "Add to wishlist". $position = get_option( 'yith_wcwl_button_position', 'add-to-cart' ); /** * APPLY_FILTERS: yith_wcwl_positions * * Filter the array of positions where to display the 'Add to wishlist' button in the product page. * * @param array $positions Array of positions * * @return array */ $positions = apply_filters( 'yith_wcwl_positions', array( 'after_add_to_cart' => array( 'hook' => 'woocommerce_single_product_summary', 'priority' => 31, ), 'add-to-cart' => array( 'hook' => 'woocommerce_single_product_summary', 'priority' => 31, ), 'thumbnails' => array( 'hook' => 'woocommerce_before_single_product_summary', 'priority' => 21, ), 'summary' => array( 'hook' => 'woocommerce_after_single_product_summary', 'priority' => 11, ), ) ); if ( 'shortcode' === $position || ! isset( $positions[ $position ] ) ) { return; } if ( yith_plugin_fw_wc_is_using_block_template_in_single_product() ) { $this->add_button_for_blockified_template( 'single-product', $position ); } else { add_action( $positions[ $position ][ 'hook' ], array( $this, 'print_button' ), $positions[ $position ][ 'priority' ] ); } } /** * Add ATW button to Archive product page * Accounts for both Legacy Templates and Blockified ones * * @return void * @since 3.24.0 */ public function add_button_for_loop() { // check if Add to wishlist button is enabled for loop. $enabled_on_loop = 'yes' === get_option( 'yith_wcwl_show_on_loop', 'no' ); if ( ! $enabled_on_loop ) { return; } /** * APPLY_FILTERS: yith_wcwl_loop_positions * * Filter the array of positions where to display the 'Add to wishlist' button in the loop page. * * @param array $positions Array of positions * * @return array */ $positions = apply_filters( 'yith_wcwl_loop_positions', array( 'before_image' => array( 'hook' => 'woocommerce_before_shop_loop_item', 'priority' => 5, ), 'before_add_to_cart' => array( 'hook' => 'woocommerce_after_shop_loop_item', 'priority' => 7, ), 'after_add_to_cart' => array( 'hook' => 'woocommerce_after_shop_loop_item', 'priority' => 15, ), ) ); // Add the link "Add to wishlist" in the loop. $position = get_option( 'yith_wcwl_loop_position', 'after_add_to_cart' ); if ( 'shortcode' === $position || ! isset( $positions[ $position ] ) ) { return; } if ( yith_plugin_fw_wc_is_using_block_template_in_product_catalogue() ) { $this->add_button_for_blockified_template( 'archive-product', $position ); } else { add_action( $positions[ $position ][ 'hook' ], array( $this, 'print_button' ), $positions[ $position ][ 'priority' ] ); } } /** * Hooks action required to print ATW button in correct locations inside a Blockified template * * @param string $template Template to change. * @param string $position Position where to add button. * @return void * @since 3.24.0 */ public function add_button_for_blockified_template( $template, $position ) { switch ( $position ) { case 'add-to-cart': case 'after_add_to_cart': $block = 'single-product' === $template ? 'add-to-cart-form' : 'product-button'; add_filter( "render_block_woocommerce/$block", array( $this, 'add_button_after_block' ), 10, 3 ); break; case 'before_add_to_cart': $block = 'single-product' === $template ? 'add-to-cart-form' : 'product-button'; add_filter( "render_block_woocommerce/$block", array( $this, 'add_button_before_block' ), 10, 3 ); break; case 'thumbnails': add_filter( 'render_block_woocommerce/product-image-gallery', array( $this, 'add_button_after_block' ), 10, 3 ); break; case 'before_image': add_filter( 'render_block_woocommerce/product-image', array( $this, 'add_button_after_block' ), 10, 3 ); break; case 'summary': add_filter( 'render_block_woocommerce/product-details', array( $this, 'add_button_after_block' ), 10, 3 ); break; } } /** * Prepend ATW button to a block * Uses block context to retrieve product id. * * @param string $block_content The block content. * @param string $parsed_block The full block, including name and attributes. * @param WP_Block $block The block instance. * * @return string Filtered block content. */ public function add_button_before_block( $block_content, $parsed_block, $block ) { $post_id = $block->context[ 'postId' ]; $product = wc_get_product( $post_id ); if ( ! $product ) { return $block_content; } $button = $this->get_button( $product->get_id() ); return "$button $block_content"; } /** * Append ATW button to a block * Uses block context to retrieve product id. * * @param string $block_content The block content. * @param string $parsed_block The full block, including name and attributes. * @param WP_Block $block The block instance. * * @return string Filtered block content. */ public function add_button_after_block( $block_content, $parsed_block, $block ) { global $post; $post_id = isset( $block->context[ 'postId' ] ) ? $block->context[ 'postId' ] : false; $post_id = $post_id ?? isset( $post->ID ) ? $post->ID : false; $product = wc_get_product( $post_id ); if ( ! $product ) { return $block_content; } $button = $this->get_button( $product->get_id() ); return "$block_content $button"; } /** * Add ATW button to Products block item * * @param string $item_html HTML of the single block item. * @param array $data Data used to render the item. * @param WC_Product $product Current product. * * @return string Filtered HTML. */ public function add_button_for_blocks_product_grid_item( $item_html, $data, $product ) { $enabled_on_loop = 'yes' === get_option( 'yith_wcwl_show_on_loop', 'no' ); if ( ! $enabled_on_loop ) { return $item_html; } // Add the link "Add to wishlist" in the loop. $position = get_option( 'yith_wcwl_loop_position', 'after_add_to_cart' ); $button = $this->get_button( $product->get_id() ); $parts = array(); preg_match( '/(<li class=".*?">)[\S|\s]*?(<a .*?>[\S|\s]*?<\/a>)([\S|\s]*?)(<\/li>)/', $item_html, $parts ); if ( ! $parts || count( $parts ) < 5 ) { return $item_html; } // removes first match (entire match). array_shift( $parts ); // removes empty parts. $parts = array_filter( $parts ); $index = false; // searches for index to cut parts array. switch ( $position ) { case 'before_image': $index = 1; break; case 'before_add_to_cart': $index = 2; break; case 'after_add_to_cart': $index = 3; break; } // if index is found, stitch button in correct position. if ( $index ) { $first_set = array_slice( $parts, 0, $index ); $second_set = array_slice( $parts, $index ); $parts = array_merge( $first_set, (array) $button, $second_set ); // replace li classes. $parts[ 0 ] = preg_replace( '/class="(.*)"/', 'class="$1 add-to-wishlist-' . $position . '"', $parts[ 0 ] ); } // join all parts together. $item_html = implode( '', $parts ); // return item. return $item_html; } /** * Returns HTML for ATW button * * @param int $product_id Optional product id (if empty global product will be used instead by the shortcode). * @return string HTML for ATW button. */ public function get_button( $product_id = false ) { $button = YITH_WCWL_Add_To_Wishlist_Button::get( compact( 'product_id' ) ); return $button->render( true ); } /** * Print "Add to Wishlist" shortcode * * @return void * @since 2.2.2 */ public function print_button() { /** * Developers can use this filter to remove ATW button selectively from specific pages or products * You can use global $product or $post to execute checks * * @since 3.0.7 */ /** * APPLY_FILTERS: yith_wcwl_show_add_to_wishlist * * Filter whether to show the 'Add to wishlist' button. * * @param bool $show_button Whether to show the ATW button or not * * @return bool */ if ( ! apply_filters( 'yith_wcwl_show_add_to_wishlist', true ) ) { return; } if ( 'react-components' === self::get_rendering_method() ) { $button = YITH_WCWL_Add_To_Wishlist_Button::get(); $button->render(); } else { echo do_shortcode( '[yith_wcwl_add_to_wishlist]' ); } } /* === WISHLIST PAGE === */ /** * Prints wc notice for wishlist pages * * @return void * @since 2.0.5 */ public function print_notices() { if ( function_exists( 'wc_print_notices' ) ) { wc_print_notices(); } } /** * Add specific body class when the Wishlist page is opened * * @param array $classes Existing boy classes. * * @return array * @since 1.0.0 */ public function add_body_class( $classes ) { $wishlist_page_id = YITH_WCWL()->get_wishlist_page_id(); if ( ! empty( $wishlist_page_id ) && is_page( $wishlist_page_id ) ) { $classes[] = 'woocommerce-wishlist'; $classes[] = 'woocommerce'; $classes[] = 'woocommerce-page'; } return $classes; } /** * Send nocache headers on wishlist page * * @return void * @since 3.0.0 */ public function add_nocache_headers() { if ( ! headers_sent() && yith_wcwl_is_wishlist_page() ) { wc_nocache_headers(); } } /** * Send noindex header on Add To Wishlist url (?add_to_wishlist=12345) * Deprecated since version 5.7 of WordPress. * * @return void * @since 3.0.20 */ public function add_noindex_header() { /** * APPLY_FILTERS: yith_wcwl_skip_noindex_headers * * Filter whether to disable the 'Add to wishlist' action from robots. * * @param bool $show_button Whether to disable the ATW action from robots or not * * @return bool */ if ( function_exists( 'wp_robots_no_robots' ) || ! isset( $_GET[ 'add_to_wishlist' ] ) || apply_filters( 'yith_wcwl_skip_noindex_headers', false ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended return; } wp_robots_no_robots(); } /** * Disable search engines indexing for Add to Wishlist url. * Uses "wp_robots" filter introduced in WP 5.7. * * @since 3.0.20 * @param array $robots Associative array of robots directives. * @return array Filtered robots directives. */ public function add_noindex_robots( $robots ) { if ( ! isset( $_GET[ 'add_to_wishlist' ] ) || apply_filters( 'yith_wcwl_skip_noindex_headers', false ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended return $robots; } return wp_robots_no_robots( $robots ); } /* === SCRIPTS AND ASSETS === */ /** * Register styles required by the plugin * * @return void */ public function register_styles() { $woocommerce_base = WC()->template_path(); $assets_path = str_replace( array( 'http:', 'https:' ), '', WC()->plugin_url() ) . '/assets/'; // register dependencies. wp_register_style( 'jquery-selectBox', YITH_WCWL_URL . 'assets/css/jquery.selectBox.css', array(), '1.2.0' ); wp_register_style( 'woocommerce_prettyPhoto_css', $assets_path . 'css/prettyPhoto.css', array(), '3.1.6' ); /** * APPLY_FILTERS: yith_wcwl_main_style_deps * * Filter the style dependencies to be used in the plugin. * * @param array $deps Array of style dependencies * * @return array */ $deps = apply_filters( 'yith_wcwl_main_style_deps', array( 'jquery-selectBox', 'woocommerce_prettyPhoto_css' ) ); // register main style. $located = locate_template( array( $woocommerce_base . 'wishlist.css', 'wishlist.css', ) ); if ( ! $located ) { wp_register_style( 'yith-wcwl-main', YITH_WCWL_URL . 'assets/css/style.css', $deps, YITH_WCWL_VERSION ); } else { $stylesheet_directory = get_stylesheet_directory(); $stylesheet_directory_uri = get_stylesheet_directory_uri(); $template_directory = get_template_directory(); $template_directory_uri = get_template_directory_uri(); $style_url = ( strpos( $located, $stylesheet_directory ) !== false ) ? str_replace( $stylesheet_directory, $stylesheet_directory_uri, $located ) : str_replace( $template_directory, $template_directory_uri, $located ); wp_register_style( 'yith-wcwl-user-main', $style_url, $deps, YITH_WCWL_VERSION ); } // theme specific assets. $current_theme = wp_get_theme(); if ( $current_theme->exists() ) { $theme_slug = $current_theme->Template; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase if ( file_exists( YITH_WCWL_DIR . 'assets/css/themes/' . $theme_slug . '.css' ) ) { wp_register_style( 'yith-wcwl-theme', YITH_WCWL_URL . 'assets/css/themes/' . $theme_slug . '.css', array( $located ? 'yith-wcwl-user-main' : 'yith-wcwl-main' ), YITH_WCWL_VERSION ); } } } /** * Enqueue styles, scripts and other stuffs needed in the <head>. * * @return void * @since 1.0.0 */ public function enqueue_styles_and_stuffs() { // main plugin style. if ( ! wp_style_is( 'yith-wcwl-user-main', 'registered' ) ) { wp_enqueue_style( 'yith-wcwl-main' ); } else { wp_enqueue_style( 'yith-wcwl-user-main' ); } // theme specific style. if ( wp_style_is( 'yith-wcwl-theme', 'registered' ) ) { wp_enqueue_style( 'yith-wcwl-theme' ); } YITH_WCWL_Add_To_Wishlist_Button::get_class()::enqueue_style(); // custom style. $this->enqueue_custom_style(); } /** * Enqueue style dynamically generated by the plugin * * @param string $handle Get a custom handler in which add the inline style. * * @return void */ public function enqueue_custom_style( $handle = '' ) { $custom_css = $this->build_custom_css(); if ( $custom_css ) { if ( ! $handle || ! wp_script_is( $handle ) ) { $handle = wp_script_is( 'yith-wcwl-user-main' ) ? 'yith-wcwl-user-main' : 'yith-wcwl-main'; } wp_add_inline_style( $handle, $custom_css ); } } /** * Enqueue plugin scripts. * * @return void * @since 1.0.0 */ public function enqueue_scripts() { if ( ! wp_script_is( 'jquery-yith-wcwl-user', 'registered' ) ) { wp_enqueue_script( 'jquery-yith-wcwl' ); } else { wp_enqueue_script( 'jquery-yith-wcwl-user' ); } } /** * Return localize array * * @return array Array with variables to be localized inside js * @since 2.2.3 */ public function get_localize() { /** * APPLY_FILTERS: yith_wcwl_localize_script * * Filter the array with the parameters sent to the plugin scripts through localize. * * @param array $localize Array of parameters * * @return array */ return apply_filters( 'yith_wcwl_localize_script', array( 'ajax_url' => admin_url( 'admin-ajax.php', 'relative' ), 'redirect_to_cart' => get_option( 'yith_wcwl_redirect_cart' ), 'yith_wcwl_button_position' => get_option( 'yith_wcwl_button_position' ), 'multi_wishlist' => false, /** * APPLY_FILTERS: yith_wcwl_hide_add_button * * Filter whether to hide the 'Add to wishlist' button. * * @param bool $hide_button Whether to hide the ATW button or not * * @return bool */ 'hide_add_button' => apply_filters( 'yith_wcwl_hide_add_button', true ), 'enable_ajax_loading' => 'yes' === get_option( 'yith_wcwl_ajax_enable', 'no' ), 'ajax_loader_url' => YITH_WCWL_URL . 'assets/images/ajax-loader-alt.svg', 'remove_from_wishlist_after_add_to_cart' => 'yes' === get_option( 'yith_wcwl_remove_after_add_to_cart' ), /** * APPLY_FILTERS: yith_wcwl_is_wishlist_responsive * * Filter whether to use the responsive layout for the wishlist. * * @param bool $is_responsive Whether to use responsive layout or not * * @return bool */ 'is_wishlist_responsive' => apply_filters( 'yith_wcwl_is_wishlist_responsive', true ), /** * APPLY_FILTERS: yith_wcwl_time_to_close_prettyphoto * * Filter the time (in miliseconds) to close the popup after the 'Ask for an estimate' request has been sent. * * @param int $time Time to close the popup * * @return int */ 'time_to_close_prettyphoto' => apply_filters( 'yith_wcwl_time_to_close_prettyphoto', 3000 ), /** * APPLY_FILTERS: yith_wcwl_fragments_index_glue * * Filter the character used for the fragments index. * * @param string $char Character * * @return string */ 'fragments_index_glue' => apply_filters( 'yith_wcwl_fragments_index_glue', '.' ), /** * APPLY_FILTERS: yith_wcwl_reload_on_found_variation * * Filter whether to reload fragments on new variations found. * * @param bool $reload_variations Whether to reload fragments * * @return bool */ 'reload_on_found_variation' => apply_filters( 'yith_wcwl_reload_on_found_variation', true ), /** * APPLY_FILTERS: yith_wcwl_mobile_media_query * * Filter the breakpoint size for the mobile media queries. * * @param int $breakpoint Breakpoint size * * @return int */ 'mobile_media_query' => apply_filters( 'yith_wcwl_mobile_media_query', 768 ), 'labels' => array( 'cookie_disabled' => __( 'We are sorry, but this feature is available only if cookies on your browser are enabled.', 'yith-woocommerce-wishlist' ), /** * APPLY_FILTERS: yith_wcwl_added_to_cart_message * * Filter the message when a product has been added succesfully to the cart from the wishlist. * * @param string $message Message * * @return string */ 'added_to_cart_message' => sprintf( '<div class="woocommerce-notices-wrapper"><div class="woocommerce-message" role="alert">%s</div></div>', apply_filters( 'yith_wcwl_added_to_cart_message', __( 'Product added to cart successfully', 'yith-woocommerce-wishlist' ) ) ), ), 'actions' => array( 'add_to_wishlist_action' => 'add_to_wishlist', 'remove_from_wishlist_action' => 'remove_from_wishlist', 'reload_wishlist_and_adding_elem_action' => 'reload_wishlist_and_adding_elem', 'load_mobile_action' => 'load_mobile', 'delete_item_action' => 'delete_item', 'save_title_action' => 'save_title', 'save_privacy_action' => 'save_privacy', 'load_fragments' => 'load_fragments', ), 'nonce' => array( 'add_to_wishlist_nonce' => wp_create_nonce( 'add_to_wishlist' ), 'remove_from_wishlist_nonce' => wp_create_nonce( 'remove_from_wishlist' ), 'reload_wishlist_and_adding_elem_nonce' => wp_create_nonce( 'reload_wishlist_and_adding_elem' ), 'load_mobile_nonce' => wp_create_nonce( 'load_mobile' ), 'delete_item_nonce' => wp_create_nonce( 'delete_item' ), 'save_title_nonce' => wp_create_nonce( 'save_title' ), 'save_privacy_nonce' => wp_create_nonce( 'save_privacy' ), 'load_fragments_nonce' => wp_create_nonce( 'load_fragments' ), ), /** * APPLY_FILTERS: yith_wcwl_redirect_after_ask_an_estimate * * Filter whether to redirect after the 'Ask for an estimate' form has been submitted. * * @param bool $redirect Whether to redirect or not * * @return bool */ 'redirect_after_ask_estimate' => apply_filters( 'yith_wcwl_redirect_after_ask_an_estimate', false ), /** * APPLY_FILTERS: yith_wcwl_redirect_url_after_ask_an_estimate * * Filter the URL to redirect after the 'Ask for an estimate' form has been submitted. * * @param string $redirect_url Redirect URL * * @return string */ 'ask_estimate_redirect_url' => apply_filters( 'yith_wcwl_redirect_url_after_ask_an_estimate', get_home_url() ), ) ); } /** * Remove the class no-js when javascript is activated * * We add the action at the start of head, to do this operation immediatly, without gap of all libraries loading * * @return void * @since 1.0.0 */ public function detect_javascript() { if ( ! defined( 'YIT' ) ) : ?> <script>document.documentElement.className = document.documentElement.className + ' yes-js js_active js'</script> <?php endif; } /* === TEMPLATES === */ /** * Include main wishlist template * * @param array $var Array of variables to pass to the template. * * @var $var array Array of parameters for current view * @return void */ public function main_wishlist_content( $var ) { // phpcs:ignore Universal.NamingConventions.NoReservedKeywordParameterNames.varFound $template = isset( $var[ 'template_part' ] ) ? $var[ 'template_part' ] : 'view'; $layout = ! empty( $var[ 'layout' ] ) ? $var[ 'layout' ] : ''; yith_wcwl_get_template_part( $template, '', $layout, $var ); } /** * Include wishlist header template * * @param array $var Array of variables to pass to the template. * * @var $var array Array of parameters for current view * @return void */ public function wishlist_header( $var ) { // phpcs:ignore Universal.NamingConventions.NoReservedKeywordParameterNames.varFound $template = isset( $var[ 'template_part' ] ) ? $var[ 'template_part' ] : 'view'; $layout = ! empty( $var[ 'layout' ] ) ? $var[ 'layout' ] : ''; yith_wcwl_get_template_part( $template, 'header', $layout, $var ); } /** * Include wishlist footer template * * @param array $var Array of variables to pass to the template. * * @var $var array Array of parameters for current view * @return void */ public function wishlist_footer( $var ) { // phpcs:ignore Universal.NamingConventions.NoReservedKeywordParameterNames.varFound $template = isset( $var[ 'template_part' ] ) ? $var[ 'template_part' ] : 'view'; $layout = ! empty( $var[ 'layout' ] ) ? $var[ 'layout' ] : ''; yith_wcwl_get_template_part( $template, 'footer', $layout, $var ); } /* === TEMPLATE MODIFICATIONS === */ /** * Add class to products when Add to Wishlist is shown on loop * * @param array $classes Array of available classes for the product. * @param string|array $class Additional class. * @param int $post_id Post ID. * @return array Array of filtered classes for the product * @since 3.0.0 */ public function add_products_class_on_loop( $classes, $class = '', $post_id = 0 ) { // phpcs:ignore Universal.NamingConventions.NoReservedKeywordParameterNames.classFound if ( yith_wcwl_is_single() || doing_action( 'body_class' ) || ! $post_id || ! in_array( get_post_type( $post_id ), array( 'product', 'product_variation' ), true ) ) { return $classes; } $enabled_on_loop = 'yes' === get_option( 'yith_wcwl_show_on_loop', 'no' ); if ( ! $enabled_on_loop ) { return $classes; } $position = get_option( 'yith_wcwl_loop_position', 'after_add_to_cart' ); if ( 'shortcode' === $position ) { return $classes; } $classes[] = "add-to-wishlist-$position"; return $classes; } /* === UTILS === */ /** * Format options that will sent through AJAX calls to refresh arguments * * @param array $options Array of options. * @param string $context Widget/Shortcode that will use the options. * @return array Array of formatted options * @since 3.0.0 */ public function format_fragment_options( $options, $context = '' ) { // removes unusable values, and changes options common for all fragments. if ( ! empty( $options ) ) { foreach ( $options as $id => $value ) { if ( is_object( $value ) || is_array( $value ) ) { // remove item if type is not supported. unset( $options[ $id ] ); } elseif ( 'ajax_loading' === $id ) { $options[ 'ajax_loading' ] = false; } } } // applies context specific changes. if ( ! empty( $context ) ) { $options[ 'item' ] = $context; switch ( $context ) { case 'add_to_wishlist': unset( $options[ 'template_part' ] ); unset( $options[ 'label' ] ); unset( $options[ 'exists' ] ); unset( $options[ 'icon' ] ); unset( $options[ 'link_classes' ] ); unset( $options[ 'link_popup_classes' ] ); unset( $options[ 'container_classes' ] ); unset( $options[ 'found_in_list' ] ); unset( $options[ 'found_item' ] ); unset( $options[ 'popup_title' ] ); unset( $options[ 'wishlist_url' ] ); break; } } return $options; } /** * Decode options that comes from the fragment * * @param array $options Options for the fragments. * @return array Filtered options for the fragment */ public function decode_fragment_options( $options ) { if ( ! empty( $options ) ) { foreach ( $options as $id => $value ) { if ( 'true' === $value ) { $options[ $id ] = true; } elseif ( 'false' === $value ) { $options[ $id ] = false; } else { $options[ $id ] = sanitize_text_field( wp_unslash( $value ) ); } } } return $options; } /** * Alter add to cart button when on wishlist page * * @return void * @since 2.0.0 * @version 3.0.0 */ public function alter_add_to_cart_button() { add_filter( 'woocommerce_loop_add_to_cart_args', array( $this, 'alter_add_to_cart_args' ) ); add_filter( 'woocommerce_product_add_to_cart_text', array( $this, 'alter_add_to_cart_text' ), 10, 2 ); add_filter( 'woocommerce_product_add_to_cart_url', array( $this, 'alter_add_to_cart_url' ), 10, 2 ); } /** * Restore default Add to Cart button, after wishlist handling * * @return void * @since 3.0.0 */ public function restore_add_to_cart_button() { remove_filter( 'woocommerce_loop_add_to_cart_args', array( $this, 'alter_add_to_cart_args' ) ); remove_filter( 'woocommerce_product_add_to_cart_text', array( $this, 'alter_add_to_cart_text' ) ); remove_filter( 'woocommerce_product_add_to_cart_url', array( $this, 'alter_add_to_cart_url' ) ); } /** * Changes arguments used to print Add to Cart button on wishlist (classes and attributes) * * @param array $args Array of arguments. * @return array Array of filtered arguments * @since 3.0.0 */ public function alter_add_to_cart_args( $args ) { $use_custom_button = get_option( 'yith_wcwl_add_to_cart_style' ); $button_class = in_array( $use_custom_button, array( 'button_custom', 'button_default' ), true ); $icon = get_option( 'yith_wcwl_add_to_cart_icon' ); $custom_icon = get_option( 'yith_wcwl_add_to_cart_custom_icon' ); $classes = isset( $args[ 'class' ] ) ? explode( ' ', $args[ 'class' ] ) : array(); $pos = array_search( 'button', $classes, true ); if ( ! $button_class && false !== $pos ) { unset( $classes[ $pos ] ); } elseif ( $button_class ) { if ( 'button_default' === $use_custom_button ) { $classes[] = 'yith-wcwl-themed-button-style'; } $classes[] = 'button'; } $classes[] = 'add_to_cart'; $classes[] = 'alt'; $args[ 'class' ] = implode( ' ', $classes ); if ( 'button_custom' === $use_custom_button && 'none' !== $icon ) { if ( ! isset( $args[ 'attributes' ] ) ) { $args[ 'attributes' ] = array(); } if ( 'custom' !== $icon ) { $args[ 'attributes' ][ 'data-icon' ] = $icon; } elseif ( $custom_icon ) { $args[ 'attributes' ][ 'data-icon' ] = $custom_icon; } } return $args; } /** * Filter Add to Cart button label on wishlist page * * @param string $text Button label. * @param \WC_Product $product Current product. * @return string Filtered label */ public function alter_add_to_cart_text( $text, $product ) { $label_option = get_option( 'yith_wcwl_add_to_cart_text', __( 'Add to cart', 'yith-woocommerce-wishlist' ) ); /** * APPLY_FILTERS: yith_wcwl_add_to_cart_label * * Filter the label of the 'Add to cart' button in the wishlist page. * * @param string $label Label * * @return string */ $label = $product->is_type( 'variable' ) ? $text : apply_filters( 'yith_wcwl_add_to_cart_label', $label_option ); return $label; } /** * Filter Add to Cart button url on wishlist page * * @param string $url Url to the Add to Cart. * @param \WC_Product $product Current product. * @return string Filtered url */ public function alter_add_to_cart_url( $url, $product ) { global $yith_wcwl_wishlist_token; if ( $yith_wcwl_wishlist_token ) { $wishlist = yith_wcwl_get_wishlist( $yith_wcwl_wishlist_token ); if ( ! $wishlist ) { return $url; } $wishlist_id = $wishlist->get_id(); $item = $wishlist->get_product( $product->get_id() ); if ( wp_doing_ajax() ) { $url = add_query_arg( 'add-to-cart', $product->get_id(), YITH_WCWL()->get_wishlist_url( 'view/' . $yith_wcwl_wishlist_token ) ); } if ( $product->is_type( array( 'simple', 'variation' ) ) && 'yes' === get_option( 'yith_wcwl_redirect_cart' ) ) { $url = add_query_arg( 'add-to-cart', $product->get_id(), wc_get_cart_url() ); } if ( ! $product->is_type( 'external' ) && 'yes' === get_option( 'yith_wcwl_remove_after_add_to_cart' ) ) { $url = add_query_arg( array( 'remove_from_wishlist_after_add_to_cart' => $product->get_id(), 'wishlist_id' => $wishlist_id, 'wishlist_token' => $yith_wcwl_wishlist_token, ), $url ); } if ( $item && 'yes' === get_option( 'yith_wcwl_quantity_show' ) ) { $url = add_query_arg( 'quantity', $item->get_quantity(), $url ); } } /** * APPLY_FILTERS: yit_wcwl_add_to_cart_redirect_url * * Filter the URL to redirect after adding to the cart from the wishlist. * * @param string $redirect_url Redirect URL * @param string $original_url Original URL * @param WC_Product $product Product object * * @return string */ return apply_filters( 'yit_wcwl_add_to_cart_redirect_url', esc_url_raw( $url ), $url, $product ); } /** * Modernize font-awesome class, for old wishlist users * * @param string $class Original font-awesome class. * @return string Filtered font-awesome class * @since 2.0.2 */ public function update_font_awesome_classes( $class ) { // phpcs:ignore Universal.NamingConventions.NoReservedKeywordParameterNames.classFound $exceptions = array( 'icon-envelope' => 'fa-envelope-o', 'icon-star-empty' => 'fa-star-o', 'icon-ok' => 'fa-check', 'icon-zoom-in' => 'fa-search-plus', 'icon-zoom-out' => 'fa-search-minus', 'icon-off' => 'fa-power-off', 'icon-trash' => 'fa-trash-o', 'icon-share' => 'fa-share-square-o', 'icon-check' => 'fa-check-square-o', 'icon-move' => 'fa-arrows', 'icon-file' => 'fa-file-o', 'icon-time' => 'fa-clock-o', 'icon-download-alt' => 'fa-download', 'icon-download' => 'fa-arrow-circle-o-down', 'icon-upload' => 'fa-arrow-circle-o-up', 'icon-play-circle' => 'fa-play-circle-o', 'icon-indent-left' => 'fa-dedent', 'icon-indent-right' => 'fa-indent', 'icon-facetime-video' => 'fa-video-camera', 'icon-picture' => 'fa-picture-o', 'icon-plus-sign' => 'fa-plus-circle', 'icon-minus-sign' => 'fa-minus-circle', 'icon-remove-sign' => 'fa-times-circle', 'icon-ok-sign' => 'fa-check-circle', 'icon-question-sign' => 'fa-question-circle', 'icon-info-sign' => 'fa-info-circle', 'icon-screenshot' => 'fa-crosshairs', 'icon-remove-circle' => 'fa-times-circle-o', 'icon-ok-circle' => 'fa-check-circle-o', 'icon-ban-circle' => 'fa-ban', 'icon-share-alt' => 'fa-share', 'icon-resize-full' => 'fa-expand', 'icon-resize-small' => 'fa-compress', 'icon-exclamation-sign' => 'fa-exclamation-circle', 'icon-eye-open' => 'fa-eye', 'icon-eye-close' => 'fa-eye-slash', 'icon-warning-sign' => 'fa-warning', 'icon-folder-close' => 'fa-folder', 'icon-resize-vertical' => 'fa-arrows-v', 'icon-resize-horizontal' => 'fa-arrows-h', 'icon-twitter-sign' => 'fa-twitter-square', 'icon-facebook-sign' => 'fa-facebook-square', 'icon-thumbs-up' => 'fa-thumbs-o-up', 'icon-thumbs-down' => 'fa-thumbs-o-down', 'icon-heart-empty' => 'fa-heart-o', 'icon-signout' => 'fa-sign-out', 'icon-linkedin-sign' => 'fa-linkedin-square', 'icon-pushpin' => 'fa-thumb-tack', 'icon-signin' => 'fa-sign-in', 'icon-github-sign' => 'fa-github-square', 'icon-upload-alt' => 'fa-upload', 'icon-lemon' => 'fa-lemon-o', 'icon-check-empty' => 'fa-square-o', 'icon-bookmark-empty' => 'fa-bookmark-o', 'icon-phone-sign' => 'fa-phone-square', 'icon-hdd' => 'fa-hdd-o', 'icon-hand-right' => 'fa-hand-o-right', 'icon-hand-left' => 'fa-hand-o-left', 'icon-hand-up' => 'fa-hand-o-up', 'icon-hand-down' => 'fa-hand-o-down', 'icon-circle-arrow-left' => 'fa-arrow-circle-left', 'icon-circle-arrow-right' => 'fa-arrow-circle-right', 'icon-circle-arrow-up' => 'fa-arrow-circle-up', 'icon-circle-arrow-down' => 'fa-arrow-circle-down', 'icon-fullscreen' => 'fa-arrows-alt', 'icon-beaker' => 'fa-flask', 'icon-paper-clip' => 'fa-paperclip', 'icon-sign-blank' => 'fa-square', 'icon-pinterest-sign' => 'fa-pinterest-square', 'icon-google-plus-sign' => 'fa-google-plus-square', 'icon-envelope-alt' => 'fa-envelope', 'icon-comment-alt' => 'fa-comment-o', 'icon-comments-alt' => 'fa-comments-o', ); if ( in_array( $class, array_keys( $exceptions ), true ) ) { $class = $exceptions[ $class ]; } $class = str_replace( 'icon-', 'fa-', $class ); return $class; } /** * Add Frequently Bought Together shortcode to wishlist page * * @param mixed $meta Meta. */ public function yith_wcfbt_shortcode( $meta ) { if ( ! ( defined( 'YITH_WFBT' ) && YITH_WFBT ) || 'no' === get_option( 'yith_wfbt_enable_integration' ) || empty( $meta ) ) { return; } $products = yith_wcwl_wishlists()->get_items( array( 'wishlist_id' => is_user_logged_in() ? $meta[ 'ID' ] : '', ) ); $ids = array(); // take id of products in wishlist. foreach ( $products as $product ) { $ids[] = $product[ 'prod_id' ]; } if ( empty( $ids ) ) { return; } do_shortcode( '[yith_wfbt products="' . implode( ',', $ids ) . '"]' ); } /** * Redirect after add to cart from YITH WooCommerce Frequently Bought Together Premium shortcode * * @param string $url Redirect url. * * @since 2.0.0 */ public function yith_wfbt_redirect_after_add_to_cart( $url ) { if ( ! isset( $_REQUEST[ 'yith_wfbt_shortcode' ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended return $url; } return 'yes' === get_option( 'yith_wcwl_redirect_cart' ) ? wc_get_cart_url() : YITH_WCWL()->get_wishlist_url(); } /** * Generate CSS code to append to each page, to apply custom style to wishlist elements * * @param array $rules Array of additional rules to add to default ones. * @return string Generated CSS code */ protected function build_custom_css( $rules = array() ) { $feedback_duration = yith_wcwl_get_feedback_duration(); /** * APPLY_FILTERS: yith_wcwl_custom_css_rules * * Filter the array with the custom CSS rules to be used. * * @param array $css_rules CSS rules * * TODO: update filter name and deprecation. * * @return array */ $rules = apply_filters( 'yith_wcwl_custom_css_rules', array_merge( array( 'add_to_wishlist_icon_color' => array(), 'added_to_wishlist_icon_color' => array(), 'color_add_to_wishlist' => array( 'deps' => array( 'yith_wcwl_add_to_wishlist_style' => 'button_custom', ), ), 'rounded_corners_radius' => array(), 'color_add_to_cart' => array( 'deps' => array( 'yith_wcwl_add_to_cart_style' => 'button_custom', ), ), 'add_to_cart_rounded_corners_radius' => array( 'deps' => array( 'yith_wcwl_add_to_cart_style' => 'button_custom', ), ), 'color_button_style_1' => array( 'deps' => array( 'yith_wcwl_add_to_cart_style' => 'button_custom', ), ), 'color_button_style_2' => array( 'deps' => array( 'yith_wcwl_add_to_cart_style' => 'button_custom', ), ), 'color_wishlist_table' => array( 'deps' => array( 'yith_wcwl_add_to_cart_style' => 'button_custom', ), ), 'color_headers_background' => array( 'deps' => array( 'yith_wcwl_add_to_cart_style' => 'button_custom', ), ), 'color_share_button' => array(), 'color_fb_button' => array(), 'color_tw_button' => array(), 'color_pr_button' => array(), 'color_em_button' => array(), 'color_wa_button' => array(), 'feedback_duration' => array( 'value' => ( $feedback_duration / 1000 ) . 's', ), ), $rules ) ); // TODO: check if need to handle the dependencies. $css_variables = array(); foreach ( $rules as $key => $value ) { $option_name = "yith_wcwl_$key"; $value = $value[ 'value' ] ?? get_option( $option_name, $value[ 'default' ] ?? null ); if ( ! is_null( $value ) ) { $variable_name = str_replace( '_', '-', $key ); if ( is_array( $value ) ) { foreach ( $value as $sub_key => $sub_value ) { $sub_variable_name = $variable_name . '-' . str_replace( '_', '-', $sub_key ); $css_variables[] = "--$sub_variable_name: $sub_value"; } } else { $css_variables[] = "--$variable_name: $value" . ( is_numeric( $value ) ? 'px' : '' ); } } } $generated_code = ' :root { ' . implode( '; ', $css_variables ) . ' } '; $custom_css = get_option( 'yith_wcwl_custom_css' ); if ( $custom_css ) { $generated_code .= ' ' . $custom_css; } return $generated_code; } /** * Generate each single CSS rule that will be included in custom plugin CSS * * @param string $rule Rule to use; placeholders may be applied to be replaced with value {@see sprintf}. * @param string $value Value to inject inside rule, replacing placeholders. * @param string $default Default value, to be used instead of value when it is empty. * * @return string Formatted CSS rule */ protected function build_css_rule( $rule, $value, $default = '' ) { // phpcs:ignore Universal.NamingConventions.NoReservedKeywordParameterNames.defaultFound $value = ( '0' === $value || ( ! empty( $value ) && ! is_array( $value ) ) ) ? $value : $default; return sprintf( rtrim( $rule, ';' ) . ';', $value ); } /** * Destroy serialize cookies, to prevent major vulnerability * * @return void * @since 2.0.7 */ protected function destroy_serialized_cookies() { $name = 'yith_wcwl_products'; if ( isset( $_COOKIE[ $name ] ) && is_serialized( sanitize_text_field( wp_unslash( $_COOKIE[ $name ] ) ) ) ) { $_COOKIE[ $name ] = wp_json_encode( array() ); yith_destroycookie( $name ); } } /** * Update old wishlist cookies * * @return void * @since 2.0.0 */ protected function update_cookies() { $cookie = yith_getcookie( 'yith_wcwl_products' ); $new_cookie = array(); if ( ! empty( $cookie ) ) { foreach ( $cookie as $item ) { if ( ! isset( $item[ 'add-to-wishlist' ] ) ) { return; } $new_cookie[] = array( 'prod_id' => $item[ 'add-to-wishlist' ], 'quantity' => isset( $item[ 'quantity' ] ) ? $item[ 'quantity' ] : 1, 'wishlist_id' => false, ); } yith_setcookie( 'yith_wcwl_products', $new_cookie ); } } /** * Convert wishlist stored into cookies into */ protected function convert_cookies_to_session() { $cookie = yith_getcookie( 'yith_wcwl_products' ); if ( ! empty( $cookie ) ) { $default_list = YITH_WCWL_Wishlist_Factory::get_default_wishlist(); if ( ! $default_list ) { return false; } foreach ( $cookie as $item ) { if ( $default_list->has_product( $item[ 'prod_id' ] ) ) { continue; } $new_item = new YITH_WCWL_Wishlist_Item(); $new_item->set_product_id( $item[ 'prod_id' ] ); $new_item->set_quantity( $item[ 'quantity' ] ); if ( isset( $item[ 'dateadded' ] ) ) { $new_item->set_date_added( $item[ 'dateadded' ] ); } $default_list->add_item( $new_item ); } $default_list->save(); yith_destroycookie( 'yith_wcwl_products' ); } } } } includes/class-yith-wcwl-session.php 0000777 00000021573 15251156646 0013630 0 ustar 00 <?php /** * Wishlist Session Handler * * @package YITH\Wishlist\Classes * @author YITH <plugins@yithemes.com> * @version 3.0.0 */ defined( 'YITH_WCWL' ) || exit; // Exit if accessed directly if ( ! class_exists( 'YITH_WCWL_Session' ) ) { /** * This class implements Session handler for wishlist * Unique session id is assigned to any new customer, and registered in a cookie * * Expiration is set accordingly to plugin options * * @since 3.0.0 */ class YITH_WCWL_Session { use YITH_WCWL_Singleton_Trait; /** * Session ID. * * @var int $session_id Session ID. */ protected $session_id; /** * Cookie name used for the session. * * @var string cookie name */ protected $cookie_name; /** * Cookie content. * * @var array cookie content. */ protected $cookie; /** * Stores session expiry. * * @var string session due to expire timestamp */ protected $session_expiring; /** * Stores session expiration. * * @var string session expiration timestamp */ protected $session_expiration; /** * True when the cookie exists. * * @var bool Based on whether a cookie exists. */ protected $has_cookie = false; /** * Construct session class */ public function __construct() { // prefetch session cookie. add_action( 'init', array( $this, 'get_session_cookie' ), 5 ); // add action to finalize session. add_action( 'init', array( $this, 'finalize_session' ) ); } /** * Setup cookie and customer ID. * * @since 3.0.0 */ public function init_session_cookie() { $cookie = $this->get_session_cookie(); if ( is_array( $cookie ) && ! empty( $cookie['session_id'] ) && ! empty( $cookie['session_expiration'] ) ) { if ( is_user_logged_in() ) { // If the user logs in, forget session. /** * Once customer logs in, we can permanently register wishlists for his account */ $this->finalize_session(); } elseif ( time() > $this->session_expiring ) { // Update session if its close to expiring. $this->set_session_expiration(); $this->update_session_timestamp( $this->session_id, $this->session_expiration ); } } else { $this->set_session_expiration(); $this->session_id = $this->session_id ? $this->session_id : $this->generate_session_id(); } if ( ! $this->has_cookie ) { $this->set_session_cookie(); } } /** * Sets the session cookie on-demand * * @return void */ public function set_session_cookie() { /** * APPLY_FILTERS: yith_wcwl_set_session_cookie * * Filter whether to set the session cookie. * * @param bool $set_session_cookie Whether to set session cookie or not * * @return bool */ if ( headers_sent() || ! apply_filters( 'yith_wcwl_set_session_cookie', true ) ) { return; } $to_hash = $this->session_id . '|' . $this->session_expiration; $hash = hash_hmac( 'md5', $to_hash, wp_hash( $to_hash ) ); $cookie_value = array( 'session_id' => $this->session_id, 'session_expiration' => $this->session_expiration, 'session_expiring' => $this->session_expiring, 'cookie_hash' => $hash, ); yith_setcookie( $this->get_session_cookie_name(), $cookie_value, $this->session_expiration, $this->use_secure_cookie(), true ); // cookie has been set. $this->cookie = $cookie_value; $this->has_cookie = true; } /** * Get the session cookie, if set. Otherwise return false. * * Session cookies without a customer ID are invalid. * * @return bool|array */ public function get_session_cookie() { if ( ! empty( $this->cookie ) ) { return $this->cookie; } $cookie_value = yith_getcookie( $this->get_session_cookie_name() ); // @codingStandardsIgnoreLine. if ( empty( $cookie_value ) || ! is_array( $cookie_value ) ) { return false; } if ( empty( $cookie_value['session_id'] ) ) { return false; } // Validate hash. $to_hash = $cookie_value['session_id'] . '|' . $cookie_value['session_expiration']; $hash = hash_hmac( 'md5', $to_hash, wp_hash( $to_hash ) ); if ( empty( $cookie_value['cookie_hash'] ) || ! hash_equals( $hash, $cookie_value['cookie_hash'] ) ) { return false; } $this->cookie = $cookie_value; $this->has_cookie = true; $this->session_id = $cookie_value['session_id']; $this->session_expiration = $cookie_value['session_expiration']; $this->session_expiring = $cookie_value['session_expiring']; return $cookie_value; } /** * Returns true if system should use HTTPS only cookies * * @return bool */ public function use_secure_cookie() { /** * APPLY_FILTERS: yith_wcwl_session_use_secure_cookie * * Filter whether to use secure cookies. * * @param bool $use_secure_cookie Wether to use secure cookies or not * * @return bool */ return apply_filters( 'yith_wcwl_session_use_secure_cookie', wc_site_is_https() && is_ssl() ); } /** * Returns name for the session cookie * * @return string * @since 3.0.3 */ public function get_session_cookie_name() { if ( empty( $this->cookie_name ) ) { /** * APPLY_FILTERS: yith_wcwl_session_cookie * * Filter the session cookie name. * * @param string $cookie_name Cookie name * * @return string */ $this->cookie_name = apply_filters( 'yith_wcwl_session_cookie', 'yith_wcwl_session_' . COOKIEHASH ); } return $this->cookie_name; } /** * Returns current session expiration; if session doesn't exist, creates it; if user is logged in, return false * * @return string Current customer id */ public function get_session_expiration() { $session_id = $this->get_session_id(); if ( $session_id ) { return $this->session_expiration; } return false; } /** * Set session expiration. */ public function set_session_expiration() { $this->session_expiring = time() + yith_wcwl_get_cookie_expiration() - HOUR_IN_SECONDS; $this->session_expiration = time() + yith_wcwl_get_cookie_expiration(); } /** * Return true if the current user has an active session, i.e. a cookie to retrieve values. * * @return bool */ public function has_session() { return $this->has_cookie; // @codingStandardsIgnoreLine. } /** * Returns current session id; if session doesn't exist, creates it; if user is logged in, return false * * @return string Current customer id */ public function get_session_id() { if ( $this->has_session() ) { return $this->session_id; } elseif ( ! is_user_logged_in() ) { $this->init_session_cookie(); return $this->session_id; } return false; } /** * Returns current session id, if any; false otherwise (won't create a session) * * @return string|bool Current customer id, or false, if none */ public function maybe_get_session_id() { if ( $this->has_session() ) { return $this->session_id; } return false; } /** * Generate a unique customer ID for guests, or return false if logged in. * * Uses Portable PHP password hashing framework to generate a unique cryptographically strong ID. * * @return string|bool */ public function generate_session_id() { $session_id = ''; if ( is_user_logged_in() ) { return false; } require_once ABSPATH . 'wp-includes/class-phpass.php'; $hasher = new PasswordHash( 8, false ); $session_id = md5( $hasher->get_random_bytes( 32 ) ); return $session_id; } /** * Converts session to stable database items * * @return void */ public function finalize_session() { if ( ! is_user_logged_in() ) { return; } $cookie = $this->get_session_cookie(); if ( ! $cookie ) { return; } if ( empty( $cookie['session_id'] ) ) { return; } $user_id = get_current_user_id(); $session_id = $cookie['session_id']; try { WC_Data_Store::load( 'wishlist' )->assign_to_user( $session_id, $user_id ); } catch ( Exception $e ) { wc_caught_exception( $e, __FUNCTION__, func_get_args() ); return; } $this->forget_session(); } /** * Update the session expiry timestamp. * * @param string $session_id Session ID. * @param int $timestamp Timestamp to expire the cookie. */ public function update_session_timestamp( $session_id, $timestamp ) { try { WC_Data_Store::load( 'wishlist' )->update_raw( array( 'expiration' => 'FROM_UNIXTIME(%d)' ), array( $timestamp ), array( 'session_id' => '%s' ), array( $session_id ) ); } catch ( Exception $e ) { wc_caught_exception( $e, __FUNCTION__, func_get_args() ); return; } } /** * Forget all session data without destroying it. */ public function forget_session() { yith_destroycookie( $this->get_session_cookie_name() ); $this->session_id = $this->generate_session_id(); $this->cookie = null; } } } languages/yith-woocommerce-wishlist-da_DK.po 0000777 00000157563 15251156646 0015213 0 ustar 00 # Copyright (C) 2019 YITH WooCommerce Wishlist # This file is distributed under the same license as the YITH WooCommerce Wishlist package. msgid "" msgstr "" "Project-Id-Version: YITH WCWL\n" "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/yith-woocommerce-" "wishlist\n" "POT-Creation-Date: 2025-11-18T14:57:58+00:00\n" "PO-Revision-Date: 2020-10-16 14:04+0200\n" "Last-Translator: Morten Ruus <altombasketball@gmail.com>\n" "Language-Team: Your Inspiration Themes <support@yithemes.com>\n" "Language: da_DK\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 2.4.1\n" "X-Poedit-KeywordsList: __;_e;_x\n" "X-Poedit-Basepath: ..\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Poedit-SearchPath-0: .\n" "X-Poedit-SearchPathExcluded-0: plugin-fw\n" #. Plugin Name of the plugin #: init.php msgid "YITH WooCommerce Wishlist" msgstr "Ønskeliste" #. Plugin URI of the plugin #: init.php msgid "https://yithemes.com/themes/plugins/yith-woocommerce-wishlist/" msgstr "" #. Description of the plugin #: init.php msgid "" "<code><strong>YITH WooCommerce Wishlist</strong></code> gives your users the " "possibility to create, fill, manage and share their wishlists allowing you " "to analyze their interests and needs to improve your marketing strategies. " "<a href=\"https://yithemes.com/\" target=\"_blank\">Get more plugins for " "your e-commerce on <strong>YITH</strong></a>" msgstr "" #. Author of the plugin #: init.php msgid "YITH" msgstr "" #. Author URI of the plugin #: init.php msgid "https://yithemes.com/" msgstr "" #: includes/admin/class-yith-wcwl-admin-panel.php:62 msgctxt "Settings tab name" msgid "Settings" msgstr "" #: includes/admin/class-yith-wcwl-admin-panel.php:66 msgid "Customization" msgstr "" #: includes/admin/class-yith-wcwl-admin-panel.php:92 msgid "" "Allows your customers to create and share lists of products that they want " "to purchase on your e-commerce." msgstr "" #: includes/admin/class-yith-wcwl-admin-panel.php:139 msgctxt "[HELP TAB] Video title" msgid "" "Check this video to learn how to <b>configure wishlist and customize options:" "</b>" msgstr "" #: includes/admin/class-yith-wcwl-admin-panel.php:164 msgid "Allow users to create multiple wishlists" msgstr "" #: includes/admin/class-yith-wcwl-admin-panel.php:165 msgid "" "In the premium version, your customers can create a wishlist for their " "birthday, Christmas, a graduation party, etc." msgstr "" #: includes/admin/class-yith-wcwl-admin-panel.php:168 msgid "Advanced wishlist management" msgstr "" #: includes/admin/class-yith-wcwl-admin-panel.php:169 msgid "" "Allow users to rename wishlists, choose whether to make them public or " "private, move products from one list to another, and more." msgstr "" #: includes/admin/class-yith-wcwl-admin-panel.php:172 msgid "Different wishlist layouts" msgstr "" #: includes/admin/class-yith-wcwl-admin-panel.php:173 msgid "" "Choose which layout you prefer to display products in the wishlist for a " "more modern and 100% mobile-friendly user experience." msgstr "" #: includes/admin/class-yith-wcwl-admin-panel.php:176 msgid "Insert a wishlist widget in the header of your shop" msgstr "" #: includes/admin/class-yith-wcwl-admin-panel.php:177 msgid "" "Give instant access to the wishlist and show a preview of the products added " "to it by inserting the widget in the site header." msgstr "" #: includes/admin/class-yith-wcwl-admin-panel.php:180 msgid "" "Analyze your customers' wishlists and the most popular products in your shop" msgstr "" #: includes/admin/class-yith-wcwl-admin-panel.php:181 msgid "" "In the premium version, you can analyze the wishlists of each user in your " "shop and get a clear overview of the most popular products in your shop." msgstr "" #: includes/admin/class-yith-wcwl-admin-panel.php:184 msgid "" "Create targeted promotions and take advantage of the wishlists to increase " "conversions" msgstr "" #: includes/admin/class-yith-wcwl-admin-panel.php:185 msgid "" "The premium version of the plugin allows you to structure effective " "marketing strategies and increase conversions. Some examples? You can send " "promotional emails and offer a discount to all users who have a specific " "product on their wishlist, notify customers when a product on their wishlist " "is on sale, or notify them when an out-of-stock product is available again " "in your shop." msgstr "" #: includes/admin/class-yith-wcwl-admin-panel.php:209 msgid "Watch our first steps video" msgstr "" #: includes/admin/class-yith-wcwl-admin-panel.php:210 msgid "See how it works before you start using it" msgstr "" #: includes/admin/class-yith-wcwl-admin-panel.php:214 msgid "Set up your shop's wishlist settings" msgstr "" #: includes/admin/class-yith-wcwl-admin-panel.php:215 msgid "And embark on this new adventure!" msgstr "" #: includes/admin/class-yith-wcwl-admin.php:67 #, fuzzy msgid "Wishlist Page" msgstr "Ønskeliste" #: includes/admin/class-yith-wcwl-admin.php:98 msgctxt "[Admin] Delete wishlist from panel confirmation modal" msgid "Confirm delete" msgstr "" #. translators: %s is the name of the wishlist #: includes/admin/class-yith-wcwl-admin.php:100 #, php-format msgctxt "[Admin] Delete wishlist from panel confirmation modal" msgid "Are you sure you want to delete %s?" msgstr "" #: includes/admin/class-yith-wcwl-admin.php:101 msgctxt "[Admin] Delete wishlist from panel confirmation modal" msgid "Delete" msgstr "" #. translators: %1$s is the opening tag to hyperlink the text; %2$s id the closing tag to hyperlink the text; #: includes/admin/class-yith-wcwl-rendering-method-admin-handler.php:49 #, php-format msgid "" "YITH Wishlist 4.0 includes the new React Components. %1$s Read how to " "convert to them to improve the plugin performance %2$s" msgstr "" #: includes/admin/class-yith-wcwl-rendering-method-admin-handler.php:57 msgid "Successfully switched to the new React Components management!" msgstr "" #: includes/admin/class-yith-wcwl-rendering-method-admin-handler.php:98 msgid "" "This option is available only in the new React templates. Convert now to " "unlock all the new features!" msgstr "" #: includes/admin/class-yith-wcwl-rendering-method-admin-handler.php:102 msgid "" "YITH Wishlist 4.0 includes new React Components. Convert now to improve the " "plugin performance!" msgstr "" #: includes/admin/class-yith-wcwl-rendering-method-admin-handler.php:103 msgid "" "In this update, we converted our frontend templates using React to improve " "code readability and plugin performance.<br><br><b>Our PHP templates will be " "deprecated soon</b> (in the next major update) so we suggest you convert " "them now to enjoy the new system and check if everything works properly." "<br><br>Any doubts? Don't worry! You can click on the button below to see a " "preview of the new system on your site before you apply the changes!" msgstr "" #: includes/class-yith-wcwl-add-to-wishlist-button.php:862 #, fuzzy msgid "Select a wishlist" msgstr "ønskeliste" #: includes/class-yith-wcwl-add-to-wishlist-button.php:863 #, fuzzy msgid "Move to another wishlist" msgstr "ønskeliste" #: includes/class-yith-wcwl-add-to-wishlist-button.php:866 #: includes/widgets/elementor/class-yith-wcwl-elementor-add-to-wishlist.php:118 #: plugin-options/customization/labels-options.php:28 #: plugin-options/customization/style-options.php:25 msgid "Add to wishlist" msgstr "" #: includes/class-yith-wcwl-add-to-wishlist-button.php:870 #: plugin-options/customization/labels-options.php:36 msgid "Product added!" msgstr "" #: includes/class-yith-wcwl-add-to-wishlist-button.php:874 #: includes/class-yith-wcwl-add-to-wishlist-button.php:878 #: plugin-options/customization/labels-options.php:44 msgid "Remove from list" msgstr "" #: includes/class-yith-wcwl-add-to-wishlist-button.php:882 #: plugin-options/customization/labels-options.php:60 msgid "The product is already in your wishlist!" msgstr "" #: includes/class-yith-wcwl-add-to-wishlist-button.php:886 #: includes/class-yith-wcwl-privacy.php:315 #: includes/class-yith-wcwl-shortcode.php:262 #: includes/class-yith-wcwl-wishlist.php:392 #: includes/data-stores/class-yith-wcwl-wishlist-data-store.php:1079 #: plugin-options/customization/labels-options.php:79 #, fuzzy msgid "My wishlist" msgstr "ønskeliste" #: includes/class-yith-wcwl-add-to-wishlist-button.php:965 msgid "{{product_name}} has been added to your {{wishlist_name}} list!" msgstr "" #: includes/class-yith-wcwl-add-to-wishlist-button.php:966 msgid "{{product_name}} has been removed from your {{wishlist_name}} list!" msgstr "" #: includes/class-yith-wcwl-ajax-handler.php:92 #: templates/add-to-wishlist-remove.php:79 msgid "View ›" msgstr "" #: includes/class-yith-wcwl-ajax-handler.php:93 #: templates/add-to-wishlist-remove.php:67 msgid "or" msgstr "" #: includes/class-yith-wcwl-ajax-handler.php:94 msgid "Close" msgstr "" #: includes/class-yith-wcwl-ajax-handler.php:209 #: includes/class-yith-wcwl-ajax-handler.php:264 msgid "Product successfully removed." msgstr "" #: includes/class-yith-wcwl-form-handler.php:193 msgid "Please, make sure to enter a valid title" msgstr "" #: includes/class-yith-wcwl-frontend.php:713 #: includes/legacy/class-yith-wcwl-frontend-legacy.php:248 msgid "" "We are sorry, but this feature is available only if cookies on your browser " "are enabled." msgstr "" #: includes/class-yith-wcwl-frontend.php:723 #: includes/legacy/class-yith-wcwl-frontend-legacy.php:258 msgid "Product added to cart successfully" msgstr "" #: includes/class-yith-wcwl-frontend.php:1011 #: includes/class-yith-wcwl-shortcode.php:270 #: plugin-options/customization/labels-options.php:105 #: templates/wishlist-view-footer-mobile.php:59 #: templates/wishlist-view-footer.php:59 msgid "Add to cart" msgstr "" #: includes/class-yith-wcwl-install.php:134 msgctxt "page_slug" msgid "wishlist" msgstr "" #: includes/class-yith-wcwl-install.php:136 msgid "Wishlist" msgstr "Ønskeliste" #: includes/class-yith-wcwl-privacy.php:51 msgid "While you visit our site, we’ll track:" msgstr "" #: includes/class-yith-wcwl-privacy.php:53 msgid "" "Products you’ve added to the wishlist: we’ll use this to show you and other " "users your favourite products, and to create targeted email campaigns." msgstr "" #: includes/class-yith-wcwl-privacy.php:54 msgid "" "Wishlists you’ve created: we’ll keep track of the wishlists you create, and " "make them visible to the store staff" msgstr "" #: includes/class-yith-wcwl-privacy.php:56 msgid "" "We’ll also use cookies to keep track of wishlist contents while you’re " "browsing our site." msgstr "" #: includes/class-yith-wcwl-privacy.php:59 msgid "" "Members of our team have access to the information you provide us with. For " "example, both Administrators and Shop Managers can access:" msgstr "" #: includes/class-yith-wcwl-privacy.php:61 msgid "" "Wishlist details, such as products added, date of addition, name and privacy " "settings of your wishlists" msgstr "" #: includes/class-yith-wcwl-privacy.php:63 msgid "" "Our team members have access to this information to offer you better deals " "for the products you love." msgstr "" #: includes/class-yith-wcwl-privacy.php:93 #: includes/class-yith-wcwl-privacy.php:109 msgid "Customer wishlists" msgstr "" #: includes/class-yith-wcwl-privacy.php:146 plugin-options/lists-options.php:33 #: plugin-options/lists-options.php:39 msgid "Wishlists" msgstr "Ønskeliste" #. Translators: %s Order number. #: includes/class-yith-wcwl-privacy.php:232 #, php-format msgid "Removed wishlist %s." msgstr "" #. Translators: %s Order number. #: includes/class-yith-wcwl-privacy.php:236 #, php-format msgid "Wishlist %s has been retained." msgstr "" #: includes/class-yith-wcwl-privacy.php:271 msgid "Token" msgstr "" #: includes/class-yith-wcwl-privacy.php:272 msgid "Wishlist URL" msgstr "" #: includes/class-yith-wcwl-privacy.php:273 msgid "Title" msgstr "Titel felt" #: includes/class-yith-wcwl-privacy.php:274 msgctxt "date when wishlist was created" msgid "Created on" msgstr "" #: includes/class-yith-wcwl-privacy.php:275 msgid "Visibility" msgstr "" #: includes/class-yith-wcwl-privacy.php:276 msgid "Items added" msgstr "" #: includes/class-yith-wcwl-shortcode.php:55 msgctxt "[gutenberg]: block name" msgid "YITH Add to wishlist" msgstr "" #: includes/class-yith-wcwl-shortcode.php:56 msgctxt "[gutenberg]: block description" msgid "Shows Add to wishlist button" msgstr "" #: includes/class-yith-wcwl-shortcode.php:61 msgid "" "ID of the product to add to the wishlist (leave empty to use the global " "product)" msgstr "" #: includes/class-yith-wcwl-shortcode.php:66 msgid "URL of the wishlist page (leave empty to use the default settings)" msgstr "" #: includes/class-yith-wcwl-shortcode.php:71 msgid "Button label (leave empty to use the default settings)" msgstr "" #: includes/class-yith-wcwl-shortcode.php:76 msgid "\"Browse wishlist\" label (leave empty to use the default settings)" msgstr "" #: includes/class-yith-wcwl-shortcode.php:81 msgid "" "\"Product already in wishlist\" label (leave empty to use the default " "settings)" msgstr "" #: includes/class-yith-wcwl-shortcode.php:86 msgid "" "\"Product added to wishlist\" label (leave empty to use the default settings)" msgstr "" #: includes/class-yith-wcwl-shortcode.php:91 msgid "" "Icon for the button (use any FontAwesome valid class, or leave empty to use " "the default settings)" msgstr "" #: includes/class-yith-wcwl-shortcode.php:96 msgid "" "Additional CSS classes for the button (leave empty to use the default " "settings)" msgstr "" #: includes/class-yith-wcwl-shortcode.php:104 msgctxt "[gutenberg]: block name" msgid "YITH Wishlist" msgstr "" #: includes/class-yith-wcwl-shortcode.php:105 msgctxt "[gutenberg]: block description" msgid "Shows a list of products in wishlist" msgstr "" #: includes/class-yith-wcwl-shortcode.php:110 msgid "Choose whether to paginate items in the wishlist or show them all" msgstr "" #: includes/class-yith-wcwl-shortcode.php:113 #: includes/widgets/elementor/class-yith-wcwl-elementor-wishlist.php:118 msgid "Paginate" msgstr "" #: includes/class-yith-wcwl-shortcode.php:114 #: includes/widgets/elementor/class-yith-wcwl-elementor-wishlist.php:119 msgid "Do not paginate" msgstr "" #: includes/class-yith-wcwl-shortcode.php:119 msgid "Number of items to show per page" msgstr "" #: includes/class-yith-wcwl-shortcode.php:124 msgid "ID of the wishlist to show (e.g. K6EOWXB888ZD)" msgstr "" #: includes/class-yith-wcwl-shortcode.php:474 msgid "Share on:" msgstr "Del på:" #: includes/class-yith-wcwl-shortcode.php:516 #: plugin-options/settings/wishlist_page-options.php:147 msgid "Share on Facebook" msgstr "" #: includes/class-yith-wcwl-shortcode.php:521 #: plugin-options/settings/wishlist_page-options.php:156 msgid "Tweet on Twitter (X)" msgstr "" #: includes/class-yith-wcwl-shortcode.php:527 #: plugin-options/settings/wishlist_page-options.php:165 msgid "Pin on Pinterest" msgstr "" #: includes/class-yith-wcwl-shortcode.php:532 msgid "Share via email" msgstr "" #: includes/class-yith-wcwl-shortcode.php:538 #: plugin-options/settings/wishlist_page-options.php:183 msgid "Share on WhatsApp" msgstr "" #: includes/class-yith-wcwl-wishlist-item.php:201 msgid "Free!" msgstr "Gratis!" #. translators: 1. % of reduction/increase in price. #: includes/class-yith-wcwl-wishlist-item.php:488 #, php-format msgctxt "" "Part of the template that shows price variation since addition to list; " "placeholder will be replaced with a percentage" msgid "Price is %1$s%%" msgstr "" #. translators: 2: original product price. #: includes/class-yith-wcwl-wishlist-item.php:490 #, php-format msgctxt "" "Part of the template that shows price variation since addition to list; " "placeholder will be replaced with a price" msgid "(Was %2$s when added in list)" msgstr "" #: includes/class-yith-wcwl-wishlists.php:47 msgid "There was an error while processing your request; please, try later" msgstr "" #: includes/class-yith-wcwl-wishlists.php:290 msgid "The item cannot be added to this wishlist" msgstr "" #: includes/class-yith-wcwl-wishlists.php:294 #: includes/class-yith-wcwl-wishlists.php:300 msgid "An error occurred while adding the products to the wishlist." msgstr "" #: includes/class-yith-wcwl-wishlists.php:400 #: includes/class-yith-wcwl-wishlists.php:426 msgid "Error. Unable to remove the product from the wishlist." msgstr "" #: includes/data-stores/class-yith-wcwl-wishlist-data-store.php:252 #: includes/data-stores/class-yith-wcwl-wishlist-data-store.php:274 msgid "Invalid wishlist." msgstr "" #: includes/data-stores/class-yith-wcwl-wishlist-item-data-store.php:212 msgid "Invalid wishlist item." msgstr "" #. translators: 1. Number of users. #: includes/functions-yith-wcwl.php:375 #, php-format msgid "%d user" msgid_plural "%d users" msgstr[0] "" msgstr[1] "" #: includes/functions-yith-wcwl.php:376 msgid "has this item in wishlist" msgid_plural "have this item in wishlist" msgstr[0] "" msgstr[1] "" #: includes/functions-yith-wcwl.php:378 msgid "You're the first" msgstr "" #: includes/functions-yith-wcwl.php:379 msgid "to add this item in wishlist" msgstr "" #. translators: 1. Count of users when many, or "another" when only one. #: includes/functions-yith-wcwl.php:383 #, php-format msgid "You and %s user" msgid_plural "You and %d users" msgstr[0] "" msgstr[1] "" #. translators: 1. Count of users when many, or "another" when only one. #: includes/functions-yith-wcwl.php:383 msgid "another" msgstr "" #: includes/functions-yith-wcwl.php:384 msgid "have this item in wishlist" msgstr "" #: includes/functions-yith-wcwl.php:602 msgid "None" msgstr "" #: includes/functions-yith-wcwl.php:603 msgid "Custom" msgstr "" #: includes/functions-yith-wcwl.php:711 msgid "Shared" msgstr "Delt" #: includes/functions-yith-wcwl.php:712 msgid "Only people with the link can view it" msgstr "" #: includes/functions-yith-wcwl.php:716 msgid "Private" msgstr "Privat" #: includes/functions-yith-wcwl.php:717 msgid "Only you can view it" msgstr "" #: includes/functions-yith-wcwl.php:721 msgid "Public" msgstr "Offentlig" #: includes/functions-yith-wcwl.php:722 msgid "Anybody can view it" msgstr "" #: includes/rest-api/controllers/v1/class-yith-wcwl-rest-v1-items-controller.php:46 #: includes/rest-api/controllers/v1/class-yith-wcwl-rest-v1-items-controller.php:90 #: includes/rest-api/controllers/v1/class-yith-wcwl-rest-v1-items-controller.php:118 msgctxt "[REST-API] The schema field description" msgid "The product ID" msgstr "" #: includes/rest-api/controllers/v1/class-yith-wcwl-rest-v1-items-controller.php:51 #: includes/rest-api/controllers/v1/class-yith-wcwl-rest-v1-items-controller.php:95 #, fuzzy msgctxt "[REST-API] The schema field description" msgid "The Wishlist ID" msgstr "Ønskeliste" #: includes/rest-api/controllers/v1/class-yith-wcwl-rest-v1-items-controller.php:55 msgctxt "[REST-API] The schema field description" msgid "The quantity to add in wishlist" msgstr "" #: includes/rest-api/controllers/v1/class-yith-wcwl-rest-v1-items-controller.php:59 #: includes/rest-api/controllers/v1/class-yith-wcwl-rest-v1-items-controller.php:99 msgctxt "[REST-API] The schema field description" msgid "The User ID" msgstr "" #: includes/rest-api/controllers/v1/class-yith-wcwl-rest-v1-items-controller.php:63 msgctxt "[REST-API] The schema field description" msgid "The timestamp to use as added date." msgstr "" #: includes/rest-api/controllers/v1/class-yith-wcwl-rest-v1-items-controller.php:67 #: includes/rest-api/controllers/v1/class-yith-wcwl-rest-v1-items-controller.php:132 #: includes/rest-api/controllers/v1/class-yith-wcwl-rest-v1-lists-controller.php:59 #, fuzzy msgctxt "[REST-API] The schema field description" msgid "The wishlist name." msgstr "ønskeliste" #: includes/rest-api/controllers/v1/class-yith-wcwl-rest-v1-items-controller.php:71 #: includes/rest-api/controllers/v1/class-yith-wcwl-rest-v1-items-controller.php:136 #: includes/rest-api/controllers/v1/class-yith-wcwl-rest-v1-lists-controller.php:64 msgctxt "[REST-API] The schema field description" msgid "The wishlist visibility value." msgstr "" #: includes/rest-api/controllers/v1/class-yith-wcwl-rest-v1-items-controller.php:123 msgctxt "[REST-API] The schema field description" msgid "The destination wishlist ID" msgstr "" #: includes/rest-api/controllers/v1/class-yith-wcwl-rest-v1-items-controller.php:128 #, fuzzy msgctxt "[REST-API] The schema field description" msgid "The origin wishlist ID" msgstr "Ønskeliste" #: includes/rest-api/controllers/v1/class-yith-wcwl-rest-v1-lists-controller.php:69 msgctxt "[REST-API] The schema field description" msgid "The unique identifier for the user." msgstr "" #: includes/rest-api/controllers/v1/class-yith-wcwl-rest-v1-lists-controller.php:73 msgctxt "[REST-API] The schema field description" msgid "The unique identifier for the session." msgstr "" #: includes/rest-api/controllers/v1/class-yith-wcwl-rest-v1-products-controller.php:43 msgctxt "[REST-API] The schema field description" msgid "The list of product ids for which data is being requested." msgstr "" #: includes/rest-api/controllers/v1/class-yith-wcwl-rest-v1-products-controller.php:58 msgctxt "[REST-API] The schema field description" msgid "The unique identifier for the product." msgstr "" #: includes/widgets/elementor/class-yith-wcwl-elementor-add-to-wishlist.php:45 msgctxt "Elementor widget name" msgid "YITH Wishlist Add button" msgstr "" #: includes/widgets/elementor/class-yith-wcwl-elementor-add-to-wishlist.php:87 msgctxt "Elementor section title" msgid "Product" msgstr "" #: includes/widgets/elementor/class-yith-wcwl-elementor-add-to-wishlist.php:95 msgctxt "Elementor control label" msgid "Product ID" msgstr "" #: includes/widgets/elementor/class-yith-wcwl-elementor-add-to-wishlist.php:107 msgctxt "Elementor section title" msgid "Labels" msgstr "" #: includes/widgets/elementor/class-yith-wcwl-elementor-add-to-wishlist.php:115 msgctxt "Elementor control label" msgid "Button label" msgstr "" #: includes/widgets/elementor/class-yith-wcwl-elementor-add-to-wishlist.php:125 msgctxt "Elementor control label" msgid "\"Browse wishlist\" label" msgstr "" #: includes/widgets/elementor/class-yith-wcwl-elementor-add-to-wishlist.php:128 #: plugin-options/customization/labels-options.php:52 msgid "Browse wishlist" msgstr "" #: includes/widgets/elementor/class-yith-wcwl-elementor-add-to-wishlist.php:135 msgctxt "Elementor control label" msgid "\"Product already in wishlist\" label" msgstr "" #: includes/widgets/elementor/class-yith-wcwl-elementor-add-to-wishlist.php:138 msgid "Product already in wishlist" msgstr "" #: includes/widgets/elementor/class-yith-wcwl-elementor-add-to-wishlist.php:145 msgctxt "Elementor control label" msgid "\"Product added to wishlist\" label" msgstr "" #: includes/widgets/elementor/class-yith-wcwl-elementor-add-to-wishlist.php:148 msgid "Product added to wishlist" msgstr "" #: includes/widgets/elementor/class-yith-wcwl-elementor-add-to-wishlist.php:157 msgctxt "Elementor section title" msgid "Advanced" msgstr "" #: includes/widgets/elementor/class-yith-wcwl-elementor-add-to-wishlist.php:165 msgctxt "Elementor control label" msgid "URL of the wishlist page" msgstr "" #: includes/widgets/elementor/class-yith-wcwl-elementor-add-to-wishlist.php:175 msgctxt "Elementor control label" msgid "Icon for the button" msgstr "" #: includes/widgets/elementor/class-yith-wcwl-elementor-add-to-wishlist.php:185 msgctxt "Elementor control label" msgid "Additional CSS classes for the button" msgstr "" #: includes/widgets/elementor/class-yith-wcwl-elementor-wishlist.php:45 #, fuzzy msgctxt "Elementor widget name" msgid "YITH Wishlist" msgstr "Ønskeliste" #: includes/widgets/elementor/class-yith-wcwl-elementor-wishlist.php:87 #, fuzzy msgctxt "Elementor section title" msgid "Wishlist" msgstr "Ønskeliste" #: includes/widgets/elementor/class-yith-wcwl-elementor-wishlist.php:95 #, fuzzy msgctxt "Elementor control label" msgid "Wishlist ID" msgstr "Ønskeliste" #: includes/widgets/elementor/class-yith-wcwl-elementor-wishlist.php:107 msgctxt "Elementor section title" msgid "Pagination" msgstr "" #: includes/widgets/elementor/class-yith-wcwl-elementor-wishlist.php:115 msgctxt "Elementor control label" msgid "Paginate items" msgstr "" #: init.php:142 msgid "" "YITH WooCommerce Wishlist was deactivated as you're running an higher tier " "version of the same plugin." msgstr "" #: init.php:158 msgid "is enabled but not effective. It requires WooCommerce to work." msgstr "" #: plugin-options/customization-options.php:12 msgctxt "Tab title in plugin settings panel" msgid "Customization" msgstr "" #: plugin-options/customization-options.php:13 msgid "Customize the style of the whole plugin." msgstr "" #: plugin-options/customization-options.php:16 msgctxt "Tab title in plugin settings panel" msgid "Labels" msgstr "" #: plugin-options/customization-options.php:17 msgctxt "Tab description in plugin settings panel" msgid "Customize the labels of the whole plugin." msgstr "" #: plugin-options/customization/labels-options.php:20 #, fuzzy msgid "Add to wishlist " msgstr "ønskeliste" #: plugin-options/customization/labels-options.php:25 msgid "\"Add to wishlist\" text" msgstr "" #: plugin-options/customization/labels-options.php:26 msgid "Enter a text for \"Add to wishlist\" button" msgstr "" #: plugin-options/customization/labels-options.php:33 msgid "\"Product added\" text" msgstr "" #: plugin-options/customization/labels-options.php:34 msgid "" "Enter the text of the message displayed when the user adds a product to the " "wishlist" msgstr "" #: plugin-options/customization/labels-options.php:41 msgid "\"Remove from wishlist\" text" msgstr "" #: plugin-options/customization/labels-options.php:42 msgid "Enter a text for the \"Remove from wishlist\" button" msgstr "" #: plugin-options/customization/labels-options.php:49 msgid "\"Browse wishlist\" text" msgstr "" #: plugin-options/customization/labels-options.php:50 msgid "Enter a text for the \"Browse wishlist\" link on the product page" msgstr "" #: plugin-options/customization/labels-options.php:57 msgid "\"Product already in wishlist\" text" msgstr "" #: plugin-options/customization/labels-options.php:58 msgid "" "Enter the text for the message displayed when the user views a product that " "is already in the wishlist" msgstr "" #: plugin-options/customization/labels-options.php:71 #: plugin-options/customization/style-options.php:243 #: plugin-options/settings/wishlist_page-options.php:28 #: plugin-options/settings/wishlist_page-options.php:35 msgid "Wishlist page" msgstr "" #: plugin-options/customization/labels-options.php:76 msgid "Default wishlist name" msgstr "" #: plugin-options/customization/labels-options.php:77 msgid "" "Enter a name for the default wishlist. This is the wishlist that will be " "automatically generated for all users if they do not create any custom one" msgstr "" #: plugin-options/customization/labels-options.php:84 msgid "Sharing title" msgstr "" #: plugin-options/customization/labels-options.php:85 msgid "Wishlist title used for sharing (only used on Twitter and Pinterest)" msgstr "" #. translators: 1. Blog name. #: plugin-options/customization/labels-options.php:88 #, php-format msgid "My wishlist on %s" msgstr "" #: plugin-options/customization/labels-options.php:93 msgid "Social text" msgstr "" #: plugin-options/customization/labels-options.php:94 msgid "" "Type the message you want to publish when you share your wishlist on Twitter " "and Pinterest" msgstr "" #: plugin-options/customization/labels-options.php:102 msgid "\"Add to cart\" text" msgstr "" #: plugin-options/customization/labels-options.php:103 msgid "Enter a text for the \"Add to cart\" button" msgstr "" #: plugin-options/customization/style-options.php:31 msgid "Style of \"Add to wishlist\"" msgstr "" #: plugin-options/customization/style-options.php:32 msgid "" "Choose if you want to show a textual \"Add to wishlist\" link or a button" msgstr "" #: plugin-options/customization/style-options.php:35 #: plugin-options/customization/style-options.php:252 msgid "Textual (anchor)" msgstr "" #: plugin-options/customization/style-options.php:36 #: plugin-options/customization/style-options.php:253 msgid "Button with theme style" msgstr "" #: plugin-options/customization/style-options.php:37 #: plugin-options/customization/style-options.php:254 msgid "Button with custom style" msgstr "" #: plugin-options/customization/style-options.php:45 msgid "\"Add to wishlist\" button style" msgstr "" #: plugin-options/customization/style-options.php:52 #: plugin-options/customization/style-options.php:270 #: plugin-options/customization/style-options.php:372 #: plugin-options/customization/style-options.php:421 #: plugin-options/customization/style-options.php:469 #: plugin-options/customization/style-options.php:558 #: plugin-options/customization/style-options.php:605 #: plugin-options/customization/style-options.php:660 #: plugin-options/customization/style-options.php:707 #: plugin-options/customization/style-options.php:754 msgid "Background" msgstr "" #: plugin-options/customization/style-options.php:57 #: plugin-options/customization/style-options.php:275 #: plugin-options/customization/style-options.php:377 #: plugin-options/customization/style-options.php:426 #: plugin-options/customization/style-options.php:474 #: plugin-options/customization/style-options.php:511 msgid "Text" msgstr "" #: plugin-options/customization/style-options.php:62 #: plugin-options/customization/style-options.php:280 #: plugin-options/customization/style-options.php:382 #: plugin-options/customization/style-options.php:431 #: plugin-options/customization/style-options.php:479 msgid "Border" msgstr "" #: plugin-options/customization/style-options.php:69 #: plugin-options/customization/style-options.php:288 #: plugin-options/customization/style-options.php:390 #: plugin-options/customization/style-options.php:439 msgid "Background Hover" msgstr "" #: plugin-options/customization/style-options.php:74 #: plugin-options/customization/style-options.php:293 #: plugin-options/customization/style-options.php:395 #: plugin-options/customization/style-options.php:444 msgid "Text Hover" msgstr "" #: plugin-options/customization/style-options.php:79 #: plugin-options/customization/style-options.php:298 #: plugin-options/customization/style-options.php:400 #: plugin-options/customization/style-options.php:449 msgid "Border Hover" msgstr "" #: plugin-options/customization/style-options.php:92 #: plugin-options/customization/style-options.php:311 msgid "Border radius" msgstr "" #: plugin-options/customization/style-options.php:93 msgid "Choose radius for the \"Add to wishlist\" button" msgstr "" #: plugin-options/customization/style-options.php:107 #: plugin-options/customization/style-options.php:120 msgid "\"Add to wishlist\" icon" msgstr "" #: plugin-options/customization/style-options.php:108 msgid "Choose whether to use one of the default icons or a custom one" msgstr "" #: plugin-options/customization/style-options.php:114 #: plugin-options/customization/style-options.php:177 msgid "Use default icon" msgstr "" #: plugin-options/customization/style-options.php:115 #: plugin-options/customization/style-options.php:178 #: plugin-options/customization/style-options.php:533 #: plugin-options/customization/style-options.php:580 #: plugin-options/customization/style-options.php:635 #: plugin-options/customization/style-options.php:682 #: plugin-options/customization/style-options.php:729 msgid "Upload a custom icon" msgstr "" #: plugin-options/customization/style-options.php:121 msgid "Select an icon for the \"Add to wishlist\" button (optional)" msgstr "" #: plugin-options/customization/style-options.php:144 #: plugin-options/customization/style-options.php:220 msgid "Icon color" msgstr "" #: plugin-options/customization/style-options.php:156 msgid "\"Add to wishlist\" custom icon" msgstr "" #: plugin-options/customization/style-options.php:157 #: plugin-options/customization/style-options.php:208 msgid "" "Upload an icon you'd like to use for \"Add to wishlist\" button (suggested " "32px x 32px)" msgstr "" #: plugin-options/customization/style-options.php:169 #: plugin-options/customization/style-options.php:183 msgid "\"Added to wishlist\" icon" msgstr "" #: plugin-options/customization/style-options.php:170 #: plugin-options/customization/style-options.php:184 msgid "Select an icon for the \"Added to wishlist\" button (optional)" msgstr "" #: plugin-options/customization/style-options.php:176 msgid "Same used for Add to wishlist" msgstr "" #: plugin-options/customization/style-options.php:207 msgid "\"Added to wishlist\" custom icon" msgstr "" #: plugin-options/customization/style-options.php:228 msgid "Custom CSS" msgstr "" #: plugin-options/customization/style-options.php:229 msgid "Enter custom CSS to be applied to Wishlist elements (optional)" msgstr "" #: plugin-options/customization/style-options.php:248 msgid "Style of \"Add to cart\"" msgstr "" #: plugin-options/customization/style-options.php:249 msgid "Choose whether to show a textual \"Add to cart\" link or a button" msgstr "" #: plugin-options/customization/style-options.php:262 msgid "\"Add to cart\" button style" msgstr "" #: plugin-options/customization/style-options.php:268 msgid "Choose the colors for the \"Add to cart\" button" msgstr "" #: plugin-options/customization/style-options.php:286 msgid "Choose colors for the \"Add to cart\" button on hover state" msgstr "" #: plugin-options/customization/style-options.php:312 msgid "Set the radius for the \"Add to cart\" button" msgstr "" #: plugin-options/customization/style-options.php:326 msgid "\"Add to cart\" icon" msgstr "" #: plugin-options/customization/style-options.php:327 msgid "Select an icon for the \"Add to cart\" button (optional)" msgstr "" #: plugin-options/customization/style-options.php:351 msgid "\"Add to cart\" custom icon" msgstr "" #: plugin-options/customization/style-options.php:352 msgid "" "Upload an icon you'd like to use for the \"Add to cart\" button (suggested " "32px x 32px)" msgstr "" #: plugin-options/customization/style-options.php:364 msgid "Primary button style" msgstr "" #: plugin-options/customization/style-options.php:370 msgid "" "Choose colors for the primary button<br/><small>This style will be applied " "to \"Edit title\" button on Wishlist view, \"Submit Changes\" button on " "Manage view and \"Search wishlist\" button on Search view</small>" msgstr "" #: plugin-options/customization/style-options.php:388 msgid "" "Choose colors for the primary button on hover state<br/><small>This style " "will be applied to \"Edit title\" button on Wishlist view, \"Submit " "Changes\" button on Manage view and \"Search wishlist\" button on Search " "view</small>" msgstr "" #: plugin-options/customization/style-options.php:413 msgid "Secondary button style" msgstr "" #: plugin-options/customization/style-options.php:419 #: plugin-options/customization/style-options.php:437 msgid "" "Choose colors of the secondary button<br/><small>This style will be applied " "to the buttons that allow showing and hiding the Edit title form on Wishlist " "view and \"Create new Wishlist\" button on Manage view</small>" msgstr "" #: plugin-options/customization/style-options.php:462 msgid "Wishlist table style" msgstr "" #: plugin-options/customization/style-options.php:463 msgid "" "Choose the colors for the wishlist table (when set to \"Traditional\" layout)" msgstr "" #: plugin-options/customization/style-options.php:491 msgid "Highlight color" msgstr "" #: plugin-options/customization/style-options.php:492 msgid "" "Choose the color for all sections with background<br/><small>This color will " "be used as background for the wishlist table heading and footer (when set to " "\"Traditional\" layout), and for various form across wishlist views</small>" msgstr "" #: plugin-options/customization/style-options.php:504 msgid "Share button text color" msgstr "" #: plugin-options/customization/style-options.php:505 msgid "Choose colors for share buttons text" msgstr "" #: plugin-options/customization/style-options.php:516 msgid "Text hover" msgstr "" #: plugin-options/customization/style-options.php:524 msgid "Facebook share button icon" msgstr "" #: plugin-options/customization/style-options.php:525 msgid "Select an icon for the Facebook share button" msgstr "" #: plugin-options/customization/style-options.php:531 #: plugin-options/customization/style-options.php:578 #: plugin-options/customization/style-options.php:633 #: plugin-options/customization/style-options.php:727 msgid "Show social label without icon" msgstr "" #: plugin-options/customization/style-options.php:532 #: plugin-options/customization/style-options.php:579 #: plugin-options/customization/style-options.php:634 #: plugin-options/customization/style-options.php:728 msgid "Social default icon" msgstr "" #: plugin-options/customization/style-options.php:538 msgid "Facebook share button custom icon" msgstr "" #: plugin-options/customization/style-options.php:539 msgid "" "Upload an icon you'd like to use for Facebook share button (suggested 32px x " "32px)" msgstr "" #: plugin-options/customization/style-options.php:551 msgid "Facebook share button style" msgstr "" #: plugin-options/customization/style-options.php:552 msgid "Choose colors for Facebook share button" msgstr "" #: plugin-options/customization/style-options.php:563 #: plugin-options/customization/style-options.php:610 #: plugin-options/customization/style-options.php:665 #: plugin-options/customization/style-options.php:712 #: plugin-options/customization/style-options.php:759 msgid "Background hover" msgstr "" #: plugin-options/customization/style-options.php:571 msgid "Twitter (X) share button icon" msgstr "" #: plugin-options/customization/style-options.php:572 msgid "Select an icon for the Twitter (X) share button" msgstr "" #: plugin-options/customization/style-options.php:585 msgid "Twitter (X) share button custom icon" msgstr "" #: plugin-options/customization/style-options.php:586 msgid "" "Upload an icon you'd like to use for Twitter (X) share button (suggested " "32px x 32px)" msgstr "" #: plugin-options/customization/style-options.php:598 msgid "Twitter (X) share button style" msgstr "" #: plugin-options/customization/style-options.php:599 msgid "Choose colors for Twitter (X) share button" msgstr "" #: plugin-options/customization/style-options.php:618 msgid "Pinterest image" msgstr "" #: plugin-options/customization/style-options.php:619 msgid "Set an image to share the list on Pinterest" msgstr "" #: plugin-options/customization/style-options.php:626 msgid "Pinterest share button icon" msgstr "" #: plugin-options/customization/style-options.php:627 msgid "Select an icon for the Pinterest share button" msgstr "" #: plugin-options/customization/style-options.php:640 msgid "Pinterest share button custom icon" msgstr "" #: plugin-options/customization/style-options.php:641 msgid "" "Upload an icon you'd like to use for Pinterest share button (suggested 32px " "x 32px)" msgstr "" #: plugin-options/customization/style-options.php:653 msgid "Pinterest share button style" msgstr "" #: plugin-options/customization/style-options.php:654 msgid "Choose colors for Pinterest share button" msgstr "" #: plugin-options/customization/style-options.php:673 msgid "Email share button icon" msgstr "" #: plugin-options/customization/style-options.php:674 msgid "Select an icon for the Email share button" msgstr "" #: plugin-options/customization/style-options.php:680 msgid "Show email label without icon" msgstr "" #: plugin-options/customization/style-options.php:681 msgid "Email default icon" msgstr "" #: plugin-options/customization/style-options.php:687 msgid "Email share button custom icon" msgstr "" #: plugin-options/customization/style-options.php:688 msgid "" "Upload an icon you'd like to use for the Email share button (suggested 32px " "x 32px)" msgstr "" #: plugin-options/customization/style-options.php:700 msgid "Email share button style" msgstr "" #: plugin-options/customization/style-options.php:701 msgid "Choose colors for the Email share button" msgstr "" #: plugin-options/customization/style-options.php:720 msgid "WhatsApp share button icon" msgstr "" #: plugin-options/customization/style-options.php:721 msgid "Select an icon for the WhatsApp share button" msgstr "" #: plugin-options/customization/style-options.php:734 msgid "WhatsApp share button custom icon" msgstr "" #: plugin-options/customization/style-options.php:735 msgid "" "Upload an icon you'd like to use for WhatsApp share button (suggested 32px x " "32px)" msgstr "" #: plugin-options/customization/style-options.php:747 msgid "WhatsApp share button style" msgstr "" #: plugin-options/customization/style-options.php:748 msgid "Choose colors for WhatsApp share button" msgstr "" #: plugin-options/icons-list.php:21 msgctxt "[Admin] The icon label show in the select" msgid "Bookmark" msgstr "" #: plugin-options/icons-list.php:28 msgctxt "[Admin] The icon label show in the select" msgid "Bookmark outline" msgstr "" #: plugin-options/icons-list.php:35 msgctxt "[Admin] The icon label show in the select" msgid "Heart" msgstr "" #: plugin-options/icons-list.php:42 msgctxt "[Admin] The icon label show in the select" msgid "Heart outline" msgstr "" #: plugin-options/icons-list.php:49 msgctxt "[Admin] The icon label show in the select" msgid "Heart remove" msgstr "" #: plugin-options/icons-list.php:56 msgctxt "[Admin] The icon label show in the select" msgid "Heart arrows" msgstr "" #: plugin-options/icons-list.php:64 msgctxt "[Admin] The icon label show in the select" msgid "Heart check" msgstr "" #: plugin-options/icons-list.php:71 msgctxt "[Admin] The icon label show in the select" msgid "Star" msgstr "" #: plugin-options/icons-list.php:78 msgctxt "[Admin] The icon label show in the select" msgid "Star outline" msgstr "" #: plugin-options/icons-list.php:85 msgctxt "[Admin] The icon label show in the select" msgid "Plus" msgstr "" #: plugin-options/icons-list.php:91 msgctxt "[Admin] The icon label show in the select" msgid "Plus circle" msgstr "" #: plugin-options/icons-list.php:99 msgctxt "[Admin] The icon label show in the select" msgid "Plus circle outline" msgstr "" #: plugin-options/icons-list.php:107 msgctxt "[Admin] The icon label show in the select" msgid "Shopping bag" msgstr "" #: plugin-options/icons-list.php:113 msgctxt "[Admin] The icon label show in the select" msgid "Shopping bag outline" msgstr "" #: plugin-options/icons-list.php:119 msgctxt "[Admin] The icon label show in the select" msgid "Shopping cart" msgstr "" #: plugin-options/icons-list.php:125 msgctxt "[Admin] The icon label show in the select" msgid "Shopping cart outline" msgstr "" #: plugin-options/icons-list.php:131 msgctxt "[Admin] The icon label show in the select" msgid "Calculator" msgstr "" #: plugin-options/icons-list.php:137 msgctxt "[Admin] The icon label show in the select" msgid "Calculator outline" msgstr "" #: plugin-options/icons-list.php:143 msgctxt "[Admin] The icon label show in the select" msgid "Chat bubble" msgstr "" #: plugin-options/icons-list.php:149 msgctxt "[Admin] The icon label show in the select" msgid "Chat bubble outline" msgstr "" #: plugin-options/icons-list.php:155 msgctxt "[Admin] The icon label show in the select" msgid "Document arrow up" msgstr "" #: plugin-options/icons-list.php:161 msgctxt "[Admin] The icon label show in the select" msgid "Document arrow up outline" msgstr "" #: plugin-options/icons-list.php:167 msgctxt "[Admin] The icon label show in the select" msgid "Document chart bar" msgstr "" #: plugin-options/icons-list.php:173 msgctxt "[Admin] The icon label show in the select" msgid "Document chart bar outline" msgstr "" #: plugin-options/icons-list.php:179 msgctxt "[Admin] The icon label show in the select" msgid "Document text" msgstr "" #: plugin-options/icons-list.php:185 msgctxt "[Admin] The icon label show in the select" msgid "Document text outline" msgstr "" #: plugin-options/icons-list.php:191 msgctxt "[Admin] The icon label show in the select" msgid "Question mark" msgstr "" #: plugin-options/icons-list.php:197 msgctxt "[Admin] The icon label show in the select" msgid "Question mark outline" msgstr "" #: plugin-options/icons-list.php:203 msgctxt "[Admin] The icon label show in the select" msgid "Receipt percent" msgstr "" #: plugin-options/icons-list.php:209 msgctxt "[Admin] The icon label show in the select" msgid "Receipt percent outline" msgstr "" #: plugin-options/lists-options.php:41 msgid "Search list" msgstr "" #: plugin-options/settings-options.php:12 msgctxt "Tab title in plugin settings panel" msgid "General" msgstr "" #: plugin-options/settings-options.php:14 msgctxt "Tab description in plugin settings panel" msgid "Configure the plugin general settings." msgstr "" #: plugin-options/settings-options.php:17 #, fuzzy msgctxt "Tab title in plugin settings panel" msgid "Add to wishlist" msgstr "ønskeliste" #: plugin-options/settings-options.php:19 msgctxt "Tab description in plugin settings panel" msgid "Configure the Add to wishlist settings." msgstr "" #: plugin-options/settings-options.php:22 #, fuzzy msgctxt "Tab title in plugin settings panel" msgid "Wishlist page" msgstr "Ønskeliste" #: plugin-options/settings-options.php:24 msgctxt "Tab description in plugin settings panel" msgid "Configure the wishlist page settings." msgstr "" #: plugin-options/settings/add_to_wishlist-options.php:29 #: plugin-options/settings/general-options.php:32 msgid "General settings" msgstr "" #: plugin-options/settings/add_to_wishlist-options.php:36 msgid "After product is added to wishlist" msgstr "" #: plugin-options/settings/add_to_wishlist-options.php:37 msgid "" "Choose the look of the Wishlist button when the product has already been " "added to a wishlist" msgstr "" #: plugin-options/settings/add_to_wishlist-options.php:40 msgid "Show \"Add to wishlist\" button" msgstr "" #: plugin-options/settings/add_to_wishlist-options.php:41 msgid "Show \"View wishlist\" link" msgstr "" #: plugin-options/settings/add_to_wishlist-options.php:42 msgid "Show \"Remove from list\" link" msgstr "" #: plugin-options/settings/add_to_wishlist-options.php:55 msgid "Loop settings" msgstr "" #: plugin-options/settings/add_to_wishlist-options.php:57 msgid "" "Loop options will be visible on Shop page, category pages, product " "shortcodes, products sliders, and all the other places where the WooCommerce " "products' loop is used" msgstr "" #: plugin-options/settings/add_to_wishlist-options.php:62 msgid "Show \"Add to wishlist\" in loop" msgstr "" #: plugin-options/settings/add_to_wishlist-options.php:63 msgid "Enable the \"Add to wishlist\" feature in WooCommerce products' loop" msgstr "" #: plugin-options/settings/add_to_wishlist-options.php:71 msgid "Position of \"Add to wishlist\" in loop" msgstr "" #: plugin-options/settings/add_to_wishlist-options.php:72 msgid "" "Choose where to show \"Add to wishlist\" button or link in WooCommerce " "products' loop. <span class=\"addon\">Copy this shortcode <span " "class=\"code\"><code>[yith_wcwl_add_to_wishlist]</code></span> and paste it " "where you want to show the \"Add to wishlist\" link or button</span>" msgstr "" #: plugin-options/settings/add_to_wishlist-options.php:79 msgid "On top of the image" msgstr "" #: plugin-options/settings/add_to_wishlist-options.php:80 msgid "Before \"Add to cart\" button" msgstr "" #: plugin-options/settings/add_to_wishlist-options.php:81 msgid "After \"Add to cart\" button" msgstr "" #: plugin-options/settings/add_to_wishlist-options.php:82 #: plugin-options/settings/add_to_wishlist-options.php:114 msgid "Use shortcode" msgstr "" #: plugin-options/settings/add_to_wishlist-options.php:96 msgid "Product page settings" msgstr "" #: plugin-options/settings/add_to_wishlist-options.php:103 msgid "Position of \"Add to wishlist\" on product page" msgstr "" #: plugin-options/settings/add_to_wishlist-options.php:104 msgid "" "Choose where to show \"Add to wishlist\" button or link on the product page. " "<span class=\"addon\">Copy this shortcode <span " "class=\"code\"><code>[yith_wcwl_add_to_wishlist]</code></span> and paste it " "where you want to show the \"Add to wishlist\" link or button</span>" msgstr "" #: plugin-options/settings/add_to_wishlist-options.php:111 msgid "After \"Add to cart\"" msgstr "" #: plugin-options/settings/add_to_wishlist-options.php:112 msgid "After thumbnails" msgstr "" #: plugin-options/settings/add_to_wishlist-options.php:113 msgid "After summary" msgstr "" #: plugin-options/settings/general-options.php:38 msgid "Enable AJAX loading" msgstr "" #: plugin-options/settings/general-options.php:39 msgid "Load any cacheable wishlist item via AJAX" msgstr "" #: plugin-options/settings/general-options.php:53 msgid "YITH WooCommerce Frequently Bought Together Integration" msgstr "" #: plugin-options/settings/general-options.php:59 msgid "Enable slider in wishlist" msgstr "" #: plugin-options/settings/general-options.php:60 msgid "Enable the slider with linked products on the Wishlist page." msgstr "" #: plugin-options/settings/wishlist_page-options.php:36 msgid "" "Pick a page as the main Wishlist page; make sure you add the <span " "class=\"code\"><code>[yith_wcwl_wishlist]</code></span> shortcode into the " "page content" msgstr "" #: plugin-options/settings/wishlist_page-options.php:49 #, fuzzy msgid "Wishlist detail page" msgstr "Ønskeliste" #: plugin-options/settings/wishlist_page-options.php:56 #: plugin-options/settings/wishlist_page-options.php:65 #: plugin-options/settings/wishlist_page-options.php:74 #: plugin-options/settings/wishlist_page-options.php:83 #: plugin-options/settings/wishlist_page-options.php:92 #: plugin-options/settings/wishlist_page-options.php:101 #: plugin-options/settings/wishlist_page-options.php:110 msgid "In wishlist table show" msgstr "" #: plugin-options/settings/wishlist_page-options.php:57 msgid "Product variations selected by the user (example: size or color)" msgstr "" #: plugin-options/settings/wishlist_page-options.php:66 msgid "Product price" msgstr "" #: plugin-options/settings/wishlist_page-options.php:75 msgid "Product stock (show if the product is available or not)" msgstr "" #: plugin-options/settings/wishlist_page-options.php:84 msgid "Date on which the product was added to the wishlist" msgstr "" #: plugin-options/settings/wishlist_page-options.php:93 msgid "Add to cart option for each product" msgstr "" #: plugin-options/settings/wishlist_page-options.php:102 msgid "" "Icon to remove the product from the wishlist - to the left of the product" msgstr "" #: plugin-options/settings/wishlist_page-options.php:111 msgid "" "Button to remove the product from the wishlist - to the right of the product" msgstr "" #: plugin-options/settings/wishlist_page-options.php:119 msgid "Redirect to cart" msgstr "" #: plugin-options/settings/wishlist_page-options.php:120 msgid "" "Redirect users to the cart page when they add a product to the cart from the " "wishlist page" msgstr "" #: plugin-options/settings/wishlist_page-options.php:128 msgid "Remove items when added to the cart" msgstr "" #: plugin-options/settings/wishlist_page-options.php:129 msgid "" "Remove the product from the wishlist after it has been added to the cart" msgstr "" #: plugin-options/settings/wishlist_page-options.php:137 msgid "Share wishlist" msgstr "" #: plugin-options/settings/wishlist_page-options.php:138 msgid "Enable this option to let users share their wishlist on social media" msgstr "" #: plugin-options/settings/wishlist_page-options.php:146 #: plugin-options/settings/wishlist_page-options.php:155 #: plugin-options/settings/wishlist_page-options.php:164 #: plugin-options/settings/wishlist_page-options.php:173 #: plugin-options/settings/wishlist_page-options.php:182 msgid "Share on social media" msgstr "" #: plugin-options/settings/wishlist_page-options.php:174 msgid "Share by email" msgstr "" #: plugin-options/settings/wishlist_page-options.php:191 msgid "Share by URL" msgstr "" #: plugin-options/settings/wishlist_page-options.php:192 msgid "Show \"Share URL\" field on wishlist page" msgstr "" #: templates/react-preview-toggle.php:20 msgid "Preview mode" msgstr "" #: templates/react-preview-toggle.php:28 msgid "" "Your site is in preview mode: in this way, you can see how the new React " "Components would work on your site.<br><br>Is everything working smoothly?" msgstr "" #: templates/react-preview-toggle.php:33 msgid "Yes! Convert PHP templates to React" msgstr "" #: templates/react-preview-toggle.php:36 msgid "No, thanks, close the preview" msgstr "" #: templates/share.php:56 templates/share.php:57 msgid "Facebook" msgstr "" #: templates/share.php:64 templates/share.php:65 msgid "Twitter (X)" msgstr "" #: templates/share.php:72 templates/share.php:73 msgid "Pinterest" msgstr "" #: templates/share.php:102 templates/share.php:103 msgid "Email" msgstr "E-mail" #: templates/share.php:110 msgid "WhatsApp" msgstr "" #: templates/share.php:111 msgid "Whatsapp" msgstr "" #: templates/share.php:120 msgid "(Now" msgstr "" #: templates/share.php:120 msgid "copy" msgstr "" #: templates/share.php:120 msgid "this wishlist link and share it anywhere)" msgstr "" #: templates/wishlist-view-footer-mobile.php:55 #: templates/wishlist-view-footer.php:55 msgid "Apply this action to all the selected items:" msgstr "" #: templates/wishlist-view-footer-mobile.php:73 #: templates/wishlist-view-footer.php:73 msgid "Remove from wishlist" msgstr "" #. translators: 1. Wishlist formatted name. #: templates/wishlist-view-footer-mobile.php:93 #: templates/wishlist-view-footer.php:93 #, php-format msgid "Move to %s" msgstr "" #: templates/wishlist-view-footer-mobile.php:99 #: templates/wishlist-view-footer.php:99 msgid "Apply" msgstr "" #: templates/wishlist-view-footer-mobile.php:107 #: templates/wishlist-view-footer.php:107 msgid "Update" msgstr "" #: templates/wishlist-view-footer-mobile.php:113 #: templates/wishlist-view-footer.php:151 msgid "Add all to cart" msgstr "" #: templates/wishlist-view-header.php:86 msgid "Edit title" msgstr "Rediger titel" #: templates/wishlist-view-mobile.php:143 msgid "Added on:" msgstr "" #: templates/wishlist-view-mobile.php:154 msgid "Price:" msgstr "" #: templates/wishlist-view-mobile.php:181 msgid "Quantity:" msgstr "" #: templates/wishlist-view-mobile.php:196 msgid "Stock:" msgstr "" #: templates/wishlist-view-mobile.php:199 templates/wishlist-view.php:431 msgid "Out of stock" msgstr "" #: templates/wishlist-view-mobile.php:199 templates/wishlist-view.php:431 msgid "In Stock" msgstr "På lager" #: templates/wishlist-view-mobile.php:232 templates/wishlist-view.php:544 msgid "Move" msgstr "Flyt" #: templates/wishlist-view-mobile.php:263 templates/wishlist-view.php:575 msgid "Move to another list ›" msgstr "" #: templates/wishlist-view-mobile.php:283 templates/wishlist-view.php:250 #: templates/wishlist-view.php:607 msgid "Remove this product" msgstr "Fjern denne vare" #: templates/wishlist-view-mobile.php:304 templates/wishlist-view.php:649 msgid "No products added to the wishlist" msgstr "" #: templates/wishlist-view.php:102 msgid "Product name" msgstr "" #: templates/wishlist-view.php:122 msgid "Unit price" msgstr "" #: templates/wishlist-view.php:143 msgid "Quantity" msgstr "" #: templates/wishlist-view.php:164 msgid "Stock status" msgstr "" #: templates/wishlist-view.php:206 msgid "Arrange" msgstr "" #. translators: 1. Date product was added to wishlist. #: templates/wishlist-view.php:479 #, php-format msgid "Added on: %s" msgstr "" #: templates/wishlist-view.php:607 msgid "Remove" msgstr "Fjern" #: views/rendering-methods/modal/footer.php:14 msgid "Preview your site in a new tab" msgstr "" #: views/rendering-methods/modal/footer.php:17 msgid "Convert PHP templates to React" msgstr "" #: views/rendering-methods/modal/footer.php:20 msgid "No, thanks, I'll wait until the next update" msgstr "" #. translators: %1$s is the placeholder for the HTML opening tag to hyperlink the text; %2$s is the placeholder for the HTML closing tag to hyperlink the text; #: views/rendering-methods/react-only-option-notice.php:14 #, php-format msgid "" "This option is available only in the new React templates. %1$s Convert your " "templates now to unlock all the new features > %2$s" msgstr "" #: assets/js/dist/components/add-to-wishlist/index.js:5167 #: assets/js/dist/components/add-to-wishlist/index.js:3457 msgid "Create a new list" msgstr "" #~ msgid "Save" #~ msgstr "Gem" #~ msgid "Cancel" #~ msgstr "Annullere" #~ msgid "Ask for an estimate" #~ msgstr "Efterspørg estimat" languages/yith-woocommerce-wishlist-es_AR.po 0000777 00000162675 15251156646 0015242 0 ustar 00 # Copyright (C) 2019 YITH WooCommerce Wishlist # This file is distributed under the same license as the YITH WooCommerce Wishlist package. msgid "" msgstr "" "Project-Id-Version: YITH WooCommerce Wishlist\n" "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/yith-woocommerce-" "wishlist\n" "POT-Creation-Date: 2025-11-18T14:57:58+00:00\n" "PO-Revision-Date: 2020-10-16 14:04+0200\n" "Last-Translator: YIThemes <support@yithemes.com>\n" "Language-Team: Your Inspiration Themes <plugins@yithemes.com>\n" "Language: es_AR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 2.4.1\n" "X-Poedit-KeywordsList: " "_;gettext;gettext_noop;__;_e;_n:1,2;__ngettext:1,2;__ngettext_noop:1,2;_n_noop:1,2;_c,_nc:4c,1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;_nx_noop:4c,1,2\n" "X-Poedit-Basepath: .\n" "Plural-Forms: nplurals=2; plural=n!=1;\n" "X-Poedit-SourceCharset: UTF-8\n" "X-Poedit-SearchPath-0: ..\n" "X-Poedit-SearchPathExcluded-0: ../plugin-fw\n" #. Plugin Name of the plugin #: init.php msgid "YITH WooCommerce Wishlist" msgstr "Agregar a la Lista de deseos" #. Plugin URI of the plugin #: init.php msgid "https://yithemes.com/themes/plugins/yith-woocommerce-wishlist/" msgstr "" #. Description of the plugin #: init.php msgid "" "<code><strong>YITH WooCommerce Wishlist</strong></code> gives your users the " "possibility to create, fill, manage and share their wishlists allowing you " "to analyze their interests and needs to improve your marketing strategies. " "<a href=\"https://yithemes.com/\" target=\"_blank\">Get more plugins for " "your e-commerce on <strong>YITH</strong></a>" msgstr "" #. Author of the plugin #: init.php msgid "YITH" msgstr "" #. Author URI of the plugin #: init.php msgid "https://yithemes.com/" msgstr "" #: includes/admin/class-yith-wcwl-admin-panel.php:62 #, fuzzy msgctxt "Settings tab name" msgid "Settings" msgstr "Configuraciones generales" #: includes/admin/class-yith-wcwl-admin-panel.php:66 #, fuzzy msgid "Customization" msgstr "CSS personalizado" #: includes/admin/class-yith-wcwl-admin-panel.php:92 msgid "" "Allows your customers to create and share lists of products that they want " "to purchase on your e-commerce." msgstr "" #: includes/admin/class-yith-wcwl-admin-panel.php:139 msgctxt "[HELP TAB] Video title" msgid "" "Check this video to learn how to <b>configure wishlist and customize options:" "</b>" msgstr "" #: includes/admin/class-yith-wcwl-admin-panel.php:164 msgid "Allow users to create multiple wishlists" msgstr "" #: includes/admin/class-yith-wcwl-admin-panel.php:165 msgid "" "In the premium version, your customers can create a wishlist for their " "birthday, Christmas, a graduation party, etc." msgstr "" #: includes/admin/class-yith-wcwl-admin-panel.php:168 msgid "Advanced wishlist management" msgstr "" #: includes/admin/class-yith-wcwl-admin-panel.php:169 msgid "" "Allow users to rename wishlists, choose whether to make them public or " "private, move products from one list to another, and more." msgstr "" #: includes/admin/class-yith-wcwl-admin-panel.php:172 msgid "Different wishlist layouts" msgstr "" #: includes/admin/class-yith-wcwl-admin-panel.php:173 msgid "" "Choose which layout you prefer to display products in the wishlist for a " "more modern and 100% mobile-friendly user experience." msgstr "" #: includes/admin/class-yith-wcwl-admin-panel.php:176 msgid "Insert a wishlist widget in the header of your shop" msgstr "" #: includes/admin/class-yith-wcwl-admin-panel.php:177 msgid "" "Give instant access to the wishlist and show a preview of the products added " "to it by inserting the widget in the site header." msgstr "" #: includes/admin/class-yith-wcwl-admin-panel.php:180 msgid "" "Analyze your customers' wishlists and the most popular products in your shop" msgstr "" #: includes/admin/class-yith-wcwl-admin-panel.php:181 msgid "" "In the premium version, you can analyze the wishlists of each user in your " "shop and get a clear overview of the most popular products in your shop." msgstr "" #: includes/admin/class-yith-wcwl-admin-panel.php:184 msgid "" "Create targeted promotions and take advantage of the wishlists to increase " "conversions" msgstr "" #: includes/admin/class-yith-wcwl-admin-panel.php:185 msgid "" "The premium version of the plugin allows you to structure effective " "marketing strategies and increase conversions. Some examples? You can send " "promotional emails and offer a discount to all users who have a specific " "product on their wishlist, notify customers when a product on their wishlist " "is on sale, or notify them when an out-of-stock product is available again " "in your shop." msgstr "" #: includes/admin/class-yith-wcwl-admin-panel.php:209 msgid "Watch our first steps video" msgstr "" #: includes/admin/class-yith-wcwl-admin-panel.php:210 msgid "See how it works before you start using it" msgstr "" #: includes/admin/class-yith-wcwl-admin-panel.php:214 #, fuzzy msgid "Set up your shop's wishlist settings" msgstr "Ya está en tu lista de deseos!" #: includes/admin/class-yith-wcwl-admin-panel.php:215 msgid "And embark on this new adventure!" msgstr "" #: includes/admin/class-yith-wcwl-admin.php:67 #, fuzzy msgid "Wishlist Page" msgstr "Lista de deseos" #: includes/admin/class-yith-wcwl-admin.php:98 msgctxt "[Admin] Delete wishlist from panel confirmation modal" msgid "Confirm delete" msgstr "" #. translators: %s is the name of the wishlist #: includes/admin/class-yith-wcwl-admin.php:100 #, php-format msgctxt "[Admin] Delete wishlist from panel confirmation modal" msgid "Are you sure you want to delete %s?" msgstr "" #: includes/admin/class-yith-wcwl-admin.php:101 msgctxt "[Admin] Delete wishlist from panel confirmation modal" msgid "Delete" msgstr "" #. translators: %1$s is the opening tag to hyperlink the text; %2$s id the closing tag to hyperlink the text; #: includes/admin/class-yith-wcwl-rendering-method-admin-handler.php:49 #, php-format msgid "" "YITH Wishlist 4.0 includes the new React Components. %1$s Read how to " "convert to them to improve the plugin performance %2$s" msgstr "" #: includes/admin/class-yith-wcwl-rendering-method-admin-handler.php:57 msgid "Successfully switched to the new React Components management!" msgstr "" #: includes/admin/class-yith-wcwl-rendering-method-admin-handler.php:98 msgid "" "This option is available only in the new React templates. Convert now to " "unlock all the new features!" msgstr "" #: includes/admin/class-yith-wcwl-rendering-method-admin-handler.php:102 msgid "" "YITH Wishlist 4.0 includes new React Components. Convert now to improve the " "plugin performance!" msgstr "" #: includes/admin/class-yith-wcwl-rendering-method-admin-handler.php:103 msgid "" "In this update, we converted our frontend templates using React to improve " "code readability and plugin performance.<br><br><b>Our PHP templates will be " "deprecated soon</b> (in the next major update) so we suggest you convert " "them now to enjoy the new system and check if everything works properly." "<br><br>Any doubts? Don't worry! You can click on the button below to see a " "preview of the new system on your site before you apply the changes!" msgstr "" #: includes/class-yith-wcwl-add-to-wishlist-button.php:862 #, fuzzy msgid "Select a wishlist" msgstr "Mi lista de deseos en %s" #: includes/class-yith-wcwl-add-to-wishlist-button.php:863 #, fuzzy msgid "Move to another wishlist" msgstr "Ya está en tu lista de deseos!" #: includes/class-yith-wcwl-add-to-wishlist-button.php:866 #: includes/widgets/elementor/class-yith-wcwl-elementor-add-to-wishlist.php:118 #: plugin-options/customization/labels-options.php:28 #: plugin-options/customization/style-options.php:25 msgid "Add to wishlist" msgstr "" #: includes/class-yith-wcwl-add-to-wishlist-button.php:870 #: plugin-options/customization/labels-options.php:36 msgid "Product added!" msgstr "¡Agregado!" #: includes/class-yith-wcwl-add-to-wishlist-button.php:874 #: includes/class-yith-wcwl-add-to-wishlist-button.php:878 #: plugin-options/customization/labels-options.php:44 msgid "Remove from list" msgstr "" #: includes/class-yith-wcwl-add-to-wishlist-button.php:882 #: plugin-options/customization/labels-options.php:60 msgid "The product is already in your wishlist!" msgstr "" #: includes/class-yith-wcwl-add-to-wishlist-button.php:886 #: includes/class-yith-wcwl-privacy.php:315 #: includes/class-yith-wcwl-shortcode.php:262 #: includes/class-yith-wcwl-wishlist.php:392 #: includes/data-stores/class-yith-wcwl-wishlist-data-store.php:1079 #: plugin-options/customization/labels-options.php:79 #, fuzzy msgid "My wishlist" msgstr "Mi lista de deseos en %s" #: includes/class-yith-wcwl-add-to-wishlist-button.php:965 msgid "{{product_name}} has been added to your {{wishlist_name}} list!" msgstr "" #: includes/class-yith-wcwl-add-to-wishlist-button.php:966 msgid "{{product_name}} has been removed from your {{wishlist_name}} list!" msgstr "" #: includes/class-yith-wcwl-ajax-handler.php:92 #: templates/add-to-wishlist-remove.php:79 msgid "View ›" msgstr "" #: includes/class-yith-wcwl-ajax-handler.php:93 #: templates/add-to-wishlist-remove.php:67 msgid "or" msgstr "" #: includes/class-yith-wcwl-ajax-handler.php:94 msgid "Close" msgstr "" #: includes/class-yith-wcwl-ajax-handler.php:209 #: includes/class-yith-wcwl-ajax-handler.php:264 msgid "Product successfully removed." msgstr "Bien, lo hemos eliminado de tu lista..." #: includes/class-yith-wcwl-form-handler.php:193 msgid "Please, make sure to enter a valid title" msgstr "" #: includes/class-yith-wcwl-frontend.php:713 #: includes/legacy/class-yith-wcwl-frontend-legacy.php:248 msgid "" "We are sorry, but this feature is available only if cookies on your browser " "are enabled." msgstr "" #: includes/class-yith-wcwl-frontend.php:723 #: includes/legacy/class-yith-wcwl-frontend-legacy.php:258 msgid "Product added to cart successfully" msgstr "" #: includes/class-yith-wcwl-frontend.php:1011 #: includes/class-yith-wcwl-shortcode.php:270 #: plugin-options/customization/labels-options.php:105 #: templates/wishlist-view-footer-mobile.php:59 #: templates/wishlist-view-footer.php:59 msgid "Add to cart" msgstr "" #: includes/class-yith-wcwl-install.php:134 msgctxt "page_slug" msgid "wishlist" msgstr "" #: includes/class-yith-wcwl-install.php:136 msgid "Wishlist" msgstr "Lista de deseos" #: includes/class-yith-wcwl-privacy.php:51 msgid "While you visit our site, we’ll track:" msgstr "" #: includes/class-yith-wcwl-privacy.php:53 msgid "" "Products you’ve added to the wishlist: we’ll use this to show you and other " "users your favourite products, and to create targeted email campaigns." msgstr "" #: includes/class-yith-wcwl-privacy.php:54 msgid "" "Wishlists you’ve created: we’ll keep track of the wishlists you create, and " "make them visible to the store staff" msgstr "" #: includes/class-yith-wcwl-privacy.php:56 msgid "" "We’ll also use cookies to keep track of wishlist contents while you’re " "browsing our site." msgstr "" #: includes/class-yith-wcwl-privacy.php:59 msgid "" "Members of our team have access to the information you provide us with. For " "example, both Administrators and Shop Managers can access:" msgstr "" #: includes/class-yith-wcwl-privacy.php:61 msgid "" "Wishlist details, such as products added, date of addition, name and privacy " "settings of your wishlists" msgstr "" #: includes/class-yith-wcwl-privacy.php:63 msgid "" "Our team members have access to this information to offer you better deals " "for the products you love." msgstr "" #: includes/class-yith-wcwl-privacy.php:93 #: includes/class-yith-wcwl-privacy.php:109 msgid "Customer wishlists" msgstr "" #: includes/class-yith-wcwl-privacy.php:146 plugin-options/lists-options.php:33 #: plugin-options/lists-options.php:39 msgid "Wishlists" msgstr "Lista de deseos" #. Translators: %s Order number. #: includes/class-yith-wcwl-privacy.php:232 #, php-format msgid "Removed wishlist %s." msgstr "Mi lista de deseos en %s" #. Translators: %s Order number. #: includes/class-yith-wcwl-privacy.php:236 #, fuzzy, php-format msgid "Wishlist %s has been retained." msgstr "Texto de la tabla de la Lista de Deseos" #: includes/class-yith-wcwl-privacy.php:271 msgid "Token" msgstr "" #: includes/class-yith-wcwl-privacy.php:272 msgid "Wishlist URL" msgstr "" #: includes/class-yith-wcwl-privacy.php:273 msgid "Title" msgstr "" #: includes/class-yith-wcwl-privacy.php:274 msgctxt "date when wishlist was created" msgid "Created on" msgstr "" #: includes/class-yith-wcwl-privacy.php:275 msgid "Visibility" msgstr "" #: includes/class-yith-wcwl-privacy.php:276 msgid "Items added" msgstr "" #: includes/class-yith-wcwl-shortcode.php:55 msgctxt "[gutenberg]: block name" msgid "YITH Add to wishlist" msgstr "" #: includes/class-yith-wcwl-shortcode.php:56 msgctxt "[gutenberg]: block description" msgid "Shows Add to wishlist button" msgstr "" #: includes/class-yith-wcwl-shortcode.php:61 msgid "" "ID of the product to add to the wishlist (leave empty to use the global " "product)" msgstr "" #: includes/class-yith-wcwl-shortcode.php:66 msgid "URL of the wishlist page (leave empty to use the default settings)" msgstr "" #: includes/class-yith-wcwl-shortcode.php:71 msgid "Button label (leave empty to use the default settings)" msgstr "" #: includes/class-yith-wcwl-shortcode.php:76 msgid "\"Browse wishlist\" label (leave empty to use the default settings)" msgstr "" #: includes/class-yith-wcwl-shortcode.php:81 msgid "" "\"Product already in wishlist\" label (leave empty to use the default " "settings)" msgstr "" #: includes/class-yith-wcwl-shortcode.php:86 msgid "" "\"Product added to wishlist\" label (leave empty to use the default settings)" msgstr "" #: includes/class-yith-wcwl-shortcode.php:91 msgid "" "Icon for the button (use any FontAwesome valid class, or leave empty to use " "the default settings)" msgstr "" #: includes/class-yith-wcwl-shortcode.php:96 msgid "" "Additional CSS classes for the button (leave empty to use the default " "settings)" msgstr "" #: includes/class-yith-wcwl-shortcode.php:104 msgctxt "[gutenberg]: block name" msgid "YITH Wishlist" msgstr "" #: includes/class-yith-wcwl-shortcode.php:105 msgctxt "[gutenberg]: block description" msgid "Shows a list of products in wishlist" msgstr "" #: includes/class-yith-wcwl-shortcode.php:110 msgid "Choose whether to paginate items in the wishlist or show them all" msgstr "" #: includes/class-yith-wcwl-shortcode.php:113 #: includes/widgets/elementor/class-yith-wcwl-elementor-wishlist.php:118 msgid "Paginate" msgstr "" #: includes/class-yith-wcwl-shortcode.php:114 #: includes/widgets/elementor/class-yith-wcwl-elementor-wishlist.php:119 msgid "Do not paginate" msgstr "" #: includes/class-yith-wcwl-shortcode.php:119 msgid "Number of items to show per page" msgstr "" #: includes/class-yith-wcwl-shortcode.php:124 msgid "ID of the wishlist to show (e.g. K6EOWXB888ZD)" msgstr "" #: includes/class-yith-wcwl-shortcode.php:474 msgid "Share on:" msgstr "Compartir en:" #: includes/class-yith-wcwl-shortcode.php:516 #: plugin-options/settings/wishlist_page-options.php:147 msgid "Share on Facebook" msgstr "Compartir en Facebook" #: includes/class-yith-wcwl-shortcode.php:521 #: plugin-options/settings/wishlist_page-options.php:156 #, fuzzy msgid "Tweet on Twitter (X)" msgstr "Tuitear en Twitter" #: includes/class-yith-wcwl-shortcode.php:527 #: plugin-options/settings/wishlist_page-options.php:165 msgid "Pin on Pinterest" msgstr "Compartir en Pinterest" #: includes/class-yith-wcwl-shortcode.php:532 msgid "Share via email" msgstr "" #: includes/class-yith-wcwl-shortcode.php:538 #: plugin-options/settings/wishlist_page-options.php:183 msgid "Share on WhatsApp" msgstr "" #: includes/class-yith-wcwl-wishlist-item.php:201 msgid "Free!" msgstr "" #. translators: 1. % of reduction/increase in price. #: includes/class-yith-wcwl-wishlist-item.php:488 #, php-format msgctxt "" "Part of the template that shows price variation since addition to list; " "placeholder will be replaced with a percentage" msgid "Price is %1$s%%" msgstr "" #. translators: 2: original product price. #: includes/class-yith-wcwl-wishlist-item.php:490 #, php-format msgctxt "" "Part of the template that shows price variation since addition to list; " "placeholder will be replaced with a price" msgid "(Was %2$s when added in list)" msgstr "" #: includes/class-yith-wcwl-wishlists.php:47 msgid "There was an error while processing your request; please, try later" msgstr "" #: includes/class-yith-wcwl-wishlists.php:290 msgid "The item cannot be added to this wishlist" msgstr "" #: includes/class-yith-wcwl-wishlists.php:294 #: includes/class-yith-wcwl-wishlists.php:300 msgid "An error occurred while adding the products to the wishlist." msgstr "" #: includes/class-yith-wcwl-wishlists.php:400 #: includes/class-yith-wcwl-wishlists.php:426 msgid "Error. Unable to remove the product from the wishlist." msgstr "" "¡Ups! Ha ocurrido un error al eliminar el producto de tu lista. Intenta " "nuevamente, por favor." #: includes/data-stores/class-yith-wcwl-wishlist-data-store.php:252 #: includes/data-stores/class-yith-wcwl-wishlist-data-store.php:274 msgid "Invalid wishlist." msgstr "" #: includes/data-stores/class-yith-wcwl-wishlist-item-data-store.php:212 msgid "Invalid wishlist item." msgstr "" #. translators: 1. Number of users. #: includes/functions-yith-wcwl.php:375 #, php-format msgid "%d user" msgid_plural "%d users" msgstr[0] "" msgstr[1] "" #: includes/functions-yith-wcwl.php:376 msgid "has this item in wishlist" msgid_plural "have this item in wishlist" msgstr[0] "" msgstr[1] "" #: includes/functions-yith-wcwl.php:378 msgid "You're the first" msgstr "" #: includes/functions-yith-wcwl.php:379 msgid "to add this item in wishlist" msgstr "" #. translators: 1. Count of users when many, or "another" when only one. #: includes/functions-yith-wcwl.php:383 #, php-format msgid "You and %s user" msgid_plural "You and %d users" msgstr[0] "" msgstr[1] "" #. translators: 1. Count of users when many, or "another" when only one. #: includes/functions-yith-wcwl.php:383 msgid "another" msgstr "" #: includes/functions-yith-wcwl.php:384 msgid "have this item in wishlist" msgstr "" #: includes/functions-yith-wcwl.php:602 msgid "None" msgstr "" #: includes/functions-yith-wcwl.php:603 #, fuzzy msgid "Custom" msgstr "CSS personalizado" #: includes/functions-yith-wcwl.php:711 msgid "Shared" msgstr "Compartir en:" #: includes/functions-yith-wcwl.php:712 msgid "Only people with the link can view it" msgstr "" #: includes/functions-yith-wcwl.php:716 msgid "Private" msgstr "" #: includes/functions-yith-wcwl.php:717 msgid "Only you can view it" msgstr "" #: includes/functions-yith-wcwl.php:721 msgid "Public" msgstr "" #: includes/functions-yith-wcwl.php:722 msgid "Anybody can view it" msgstr "" #: includes/rest-api/controllers/v1/class-yith-wcwl-rest-v1-items-controller.php:46 #: includes/rest-api/controllers/v1/class-yith-wcwl-rest-v1-items-controller.php:90 #: includes/rest-api/controllers/v1/class-yith-wcwl-rest-v1-items-controller.php:118 #, fuzzy msgctxt "[REST-API] The schema field description" msgid "The product ID" msgstr "¡Agregado!" #: includes/rest-api/controllers/v1/class-yith-wcwl-rest-v1-items-controller.php:51 #: includes/rest-api/controllers/v1/class-yith-wcwl-rest-v1-items-controller.php:95 #, fuzzy msgctxt "[REST-API] The schema field description" msgid "The Wishlist ID" msgstr "Lista de deseos" #: includes/rest-api/controllers/v1/class-yith-wcwl-rest-v1-items-controller.php:55 msgctxt "[REST-API] The schema field description" msgid "The quantity to add in wishlist" msgstr "" #: includes/rest-api/controllers/v1/class-yith-wcwl-rest-v1-items-controller.php:59 #: includes/rest-api/controllers/v1/class-yith-wcwl-rest-v1-items-controller.php:99 msgctxt "[REST-API] The schema field description" msgid "The User ID" msgstr "" #: includes/rest-api/controllers/v1/class-yith-wcwl-rest-v1-items-controller.php:63 msgctxt "[REST-API] The schema field description" msgid "The timestamp to use as added date." msgstr "" #: includes/rest-api/controllers/v1/class-yith-wcwl-rest-v1-items-controller.php:67 #: includes/rest-api/controllers/v1/class-yith-wcwl-rest-v1-items-controller.php:132 #: includes/rest-api/controllers/v1/class-yith-wcwl-rest-v1-lists-controller.php:59 #, fuzzy msgctxt "[REST-API] The schema field description" msgid "The wishlist name." msgstr "Mi lista de deseos en %s" #: includes/rest-api/controllers/v1/class-yith-wcwl-rest-v1-items-controller.php:71 #: includes/rest-api/controllers/v1/class-yith-wcwl-rest-v1-items-controller.php:136 #: includes/rest-api/controllers/v1/class-yith-wcwl-rest-v1-lists-controller.php:64 msgctxt "[REST-API] The schema field description" msgid "The wishlist visibility value." msgstr "" #: includes/rest-api/controllers/v1/class-yith-wcwl-rest-v1-items-controller.php:123 msgctxt "[REST-API] The schema field description" msgid "The destination wishlist ID" msgstr "" #: includes/rest-api/controllers/v1/class-yith-wcwl-rest-v1-items-controller.php:128 #, fuzzy msgctxt "[REST-API] The schema field description" msgid "The origin wishlist ID" msgstr "Lista de deseos" #: includes/rest-api/controllers/v1/class-yith-wcwl-rest-v1-lists-controller.php:69 msgctxt "[REST-API] The schema field description" msgid "The unique identifier for the user." msgstr "" #: includes/rest-api/controllers/v1/class-yith-wcwl-rest-v1-lists-controller.php:73 msgctxt "[REST-API] The schema field description" msgid "The unique identifier for the session." msgstr "" #: includes/rest-api/controllers/v1/class-yith-wcwl-rest-v1-products-controller.php:43 msgctxt "[REST-API] The schema field description" msgid "The list of product ids for which data is being requested." msgstr "" #: includes/rest-api/controllers/v1/class-yith-wcwl-rest-v1-products-controller.php:58 msgctxt "[REST-API] The schema field description" msgid "The unique identifier for the product." msgstr "" #: includes/widgets/elementor/class-yith-wcwl-elementor-add-to-wishlist.php:45 msgctxt "Elementor widget name" msgid "YITH Wishlist Add button" msgstr "" #: includes/widgets/elementor/class-yith-wcwl-elementor-add-to-wishlist.php:87 #, fuzzy msgctxt "Elementor section title" msgid "Product" msgstr "¡Agregado!" #: includes/widgets/elementor/class-yith-wcwl-elementor-add-to-wishlist.php:95 #, fuzzy msgctxt "Elementor control label" msgid "Product ID" msgstr "¡Agregado!" #: includes/widgets/elementor/class-yith-wcwl-elementor-add-to-wishlist.php:107 msgctxt "Elementor section title" msgid "Labels" msgstr "" #: includes/widgets/elementor/class-yith-wcwl-elementor-add-to-wishlist.php:115 msgctxt "Elementor control label" msgid "Button label" msgstr "" #: includes/widgets/elementor/class-yith-wcwl-elementor-add-to-wishlist.php:125 #, fuzzy msgctxt "Elementor control label" msgid "\"Browse wishlist\" label" msgstr "Ir a la Lista de deseos" #: includes/widgets/elementor/class-yith-wcwl-elementor-add-to-wishlist.php:128 #: plugin-options/customization/labels-options.php:52 msgid "Browse wishlist" msgstr "" #: includes/widgets/elementor/class-yith-wcwl-elementor-add-to-wishlist.php:135 #, fuzzy msgctxt "Elementor control label" msgid "\"Product already in wishlist\" label" msgstr "Ya está en tu lista de deseos!" #: includes/widgets/elementor/class-yith-wcwl-elementor-add-to-wishlist.php:138 #, fuzzy msgid "Product already in wishlist" msgstr "Ya está en tu lista de deseos!" #: includes/widgets/elementor/class-yith-wcwl-elementor-add-to-wishlist.php:145 #, fuzzy msgctxt "Elementor control label" msgid "\"Product added to wishlist\" label" msgstr "Ya está en tu lista de deseos!" #: includes/widgets/elementor/class-yith-wcwl-elementor-add-to-wishlist.php:148 #, fuzzy msgid "Product added to wishlist" msgstr "Ya está en tu lista de deseos!" #: includes/widgets/elementor/class-yith-wcwl-elementor-add-to-wishlist.php:157 msgctxt "Elementor section title" msgid "Advanced" msgstr "" #: includes/widgets/elementor/class-yith-wcwl-elementor-add-to-wishlist.php:165 msgctxt "Elementor control label" msgid "URL of the wishlist page" msgstr "" #: includes/widgets/elementor/class-yith-wcwl-elementor-add-to-wishlist.php:175 msgctxt "Elementor control label" msgid "Icon for the button" msgstr "" #: includes/widgets/elementor/class-yith-wcwl-elementor-add-to-wishlist.php:185 msgctxt "Elementor control label" msgid "Additional CSS classes for the button" msgstr "" #: includes/widgets/elementor/class-yith-wcwl-elementor-wishlist.php:45 #, fuzzy msgctxt "Elementor widget name" msgid "YITH Wishlist" msgstr "Lista de deseos" #: includes/widgets/elementor/class-yith-wcwl-elementor-wishlist.php:87 #, fuzzy msgctxt "Elementor section title" msgid "Wishlist" msgstr "Lista de deseos" #: includes/widgets/elementor/class-yith-wcwl-elementor-wishlist.php:95 #, fuzzy msgctxt "Elementor control label" msgid "Wishlist ID" msgstr "Lista de deseos" #: includes/widgets/elementor/class-yith-wcwl-elementor-wishlist.php:107 msgctxt "Elementor section title" msgid "Pagination" msgstr "" #: includes/widgets/elementor/class-yith-wcwl-elementor-wishlist.php:115 msgctxt "Elementor control label" msgid "Paginate items" msgstr "" #: init.php:142 msgid "" "YITH WooCommerce Wishlist was deactivated as you're running an higher tier " "version of the same plugin." msgstr "" #: init.php:158 msgid "is enabled but not effective. It requires WooCommerce to work." msgstr "" #: plugin-options/customization-options.php:12 #, fuzzy msgctxt "Tab title in plugin settings panel" msgid "Customization" msgstr "CSS personalizado" #: plugin-options/customization-options.php:13 msgid "Customize the style of the whole plugin." msgstr "" #: plugin-options/customization-options.php:16 msgctxt "Tab title in plugin settings panel" msgid "Labels" msgstr "" #: plugin-options/customization-options.php:17 msgctxt "Tab description in plugin settings panel" msgid "Customize the labels of the whole plugin." msgstr "" #: plugin-options/customization/labels-options.php:20 #, fuzzy msgid "Add to wishlist " msgstr "Ya está en tu lista de deseos!" #: plugin-options/customization/labels-options.php:25 msgid "\"Add to wishlist\" text" msgstr "" #: plugin-options/customization/labels-options.php:26 msgid "Enter a text for \"Add to wishlist\" button" msgstr "" #: plugin-options/customization/labels-options.php:33 msgid "\"Product added\" text" msgstr "¡Agregado!" #: plugin-options/customization/labels-options.php:34 msgid "" "Enter the text of the message displayed when the user adds a product to the " "wishlist" msgstr "" #: plugin-options/customization/labels-options.php:41 #, fuzzy msgid "\"Remove from wishlist\" text" msgstr "Ir a la Lista de deseos" #: plugin-options/customization/labels-options.php:42 msgid "Enter a text for the \"Remove from wishlist\" button" msgstr "" #: plugin-options/customization/labels-options.php:49 msgid "\"Browse wishlist\" text" msgstr "Ir a la Lista de deseos" #: plugin-options/customization/labels-options.php:50 msgid "Enter a text for the \"Browse wishlist\" link on the product page" msgstr "" #: plugin-options/customization/labels-options.php:57 msgid "\"Product already in wishlist\" text" msgstr "Ya está en tu lista de deseos!" #: plugin-options/customization/labels-options.php:58 msgid "" "Enter the text for the message displayed when the user views a product that " "is already in the wishlist" msgstr "" #: plugin-options/customization/labels-options.php:71 #: plugin-options/customization/style-options.php:243 #: plugin-options/settings/wishlist_page-options.php:28 #: plugin-options/settings/wishlist_page-options.php:35 msgid "Wishlist page" msgstr "" #: plugin-options/customization/labels-options.php:76 msgid "Default wishlist name" msgstr "" #: plugin-options/customization/labels-options.php:77 msgid "" "Enter a name for the default wishlist. This is the wishlist that will be " "automatically generated for all users if they do not create any custom one" msgstr "" #: plugin-options/customization/labels-options.php:84 msgid "Sharing title" msgstr "" #: plugin-options/customization/labels-options.php:85 msgid "Wishlist title used for sharing (only used on Twitter and Pinterest)" msgstr "" #. translators: 1. Blog name. #: plugin-options/customization/labels-options.php:88 #, php-format msgid "My wishlist on %s" msgstr "Mi lista de deseos en %s" #: plugin-options/customization/labels-options.php:93 msgid "Social text" msgstr "Texto de sociales" #: plugin-options/customization/labels-options.php:94 msgid "" "Type the message you want to publish when you share your wishlist on Twitter " "and Pinterest" msgstr "" #: plugin-options/customization/labels-options.php:102 msgid "\"Add to cart\" text" msgstr "" #: plugin-options/customization/labels-options.php:103 msgid "Enter a text for the \"Add to cart\" button" msgstr "" #: plugin-options/customization/style-options.php:31 msgid "Style of \"Add to wishlist\"" msgstr "" #: plugin-options/customization/style-options.php:32 msgid "" "Choose if you want to show a textual \"Add to wishlist\" link or a button" msgstr "" #: plugin-options/customization/style-options.php:35 #: plugin-options/customization/style-options.php:252 msgid "Textual (anchor)" msgstr "" #: plugin-options/customization/style-options.php:36 #: plugin-options/customization/style-options.php:253 msgid "Button with theme style" msgstr "" #: plugin-options/customization/style-options.php:37 #: plugin-options/customization/style-options.php:254 msgid "Button with custom style" msgstr "" #: plugin-options/customization/style-options.php:45 msgid "\"Add to wishlist\" button style" msgstr "" #: plugin-options/customization/style-options.php:52 #: plugin-options/customization/style-options.php:270 #: plugin-options/customization/style-options.php:372 #: plugin-options/customization/style-options.php:421 #: plugin-options/customization/style-options.php:469 #: plugin-options/customization/style-options.php:558 #: plugin-options/customization/style-options.php:605 #: plugin-options/customization/style-options.php:660 #: plugin-options/customization/style-options.php:707 #: plugin-options/customization/style-options.php:754 msgid "Background" msgstr "" #: plugin-options/customization/style-options.php:57 #: plugin-options/customization/style-options.php:275 #: plugin-options/customization/style-options.php:377 #: plugin-options/customization/style-options.php:426 #: plugin-options/customization/style-options.php:474 #: plugin-options/customization/style-options.php:511 msgid "Text" msgstr "" #: plugin-options/customization/style-options.php:62 #: plugin-options/customization/style-options.php:280 #: plugin-options/customization/style-options.php:382 #: plugin-options/customization/style-options.php:431 #: plugin-options/customization/style-options.php:479 msgid "Border" msgstr "" #: plugin-options/customization/style-options.php:69 #: plugin-options/customization/style-options.php:288 #: plugin-options/customization/style-options.php:390 #: plugin-options/customization/style-options.php:439 msgid "Background Hover" msgstr "" #: plugin-options/customization/style-options.php:74 #: plugin-options/customization/style-options.php:293 #: plugin-options/customization/style-options.php:395 #: plugin-options/customization/style-options.php:444 msgid "Text Hover" msgstr "" #: plugin-options/customization/style-options.php:79 #: plugin-options/customization/style-options.php:298 #: plugin-options/customization/style-options.php:400 #: plugin-options/customization/style-options.php:449 msgid "Border Hover" msgstr "" #: plugin-options/customization/style-options.php:92 #: plugin-options/customization/style-options.php:311 msgid "Border radius" msgstr "" #: plugin-options/customization/style-options.php:93 msgid "Choose radius for the \"Add to wishlist\" button" msgstr "" #: plugin-options/customization/style-options.php:107 #: plugin-options/customization/style-options.php:120 msgid "\"Add to wishlist\" icon" msgstr "" #: plugin-options/customization/style-options.php:108 msgid "Choose whether to use one of the default icons or a custom one" msgstr "" #: plugin-options/customization/style-options.php:114 #: plugin-options/customization/style-options.php:177 msgid "Use default icon" msgstr "" #: plugin-options/customization/style-options.php:115 #: plugin-options/customization/style-options.php:178 #: plugin-options/customization/style-options.php:533 #: plugin-options/customization/style-options.php:580 #: plugin-options/customization/style-options.php:635 #: plugin-options/customization/style-options.php:682 #: plugin-options/customization/style-options.php:729 msgid "Upload a custom icon" msgstr "" #: plugin-options/customization/style-options.php:121 msgid "Select an icon for the \"Add to wishlist\" button (optional)" msgstr "" #: plugin-options/customization/style-options.php:144 #: plugin-options/customization/style-options.php:220 msgid "Icon color" msgstr "" #: plugin-options/customization/style-options.php:156 msgid "\"Add to wishlist\" custom icon" msgstr "" #: plugin-options/customization/style-options.php:157 #: plugin-options/customization/style-options.php:208 msgid "" "Upload an icon you'd like to use for \"Add to wishlist\" button (suggested " "32px x 32px)" msgstr "" #: plugin-options/customization/style-options.php:169 #: plugin-options/customization/style-options.php:183 msgid "\"Added to wishlist\" icon" msgstr "" #: plugin-options/customization/style-options.php:170 #: plugin-options/customization/style-options.php:184 msgid "Select an icon for the \"Added to wishlist\" button (optional)" msgstr "" #: plugin-options/customization/style-options.php:176 msgid "Same used for Add to wishlist" msgstr "" #: plugin-options/customization/style-options.php:207 msgid "\"Added to wishlist\" custom icon" msgstr "" #: plugin-options/customization/style-options.php:228 msgid "Custom CSS" msgstr "CSS personalizado" #: plugin-options/customization/style-options.php:229 msgid "Enter custom CSS to be applied to Wishlist elements (optional)" msgstr "" #: plugin-options/customization/style-options.php:248 msgid "Style of \"Add to cart\"" msgstr "" #: plugin-options/customization/style-options.php:249 msgid "Choose whether to show a textual \"Add to cart\" link or a button" msgstr "" #: plugin-options/customization/style-options.php:262 msgid "\"Add to cart\" button style" msgstr "" #: plugin-options/customization/style-options.php:268 msgid "Choose the colors for the \"Add to cart\" button" msgstr "" #: plugin-options/customization/style-options.php:286 msgid "Choose colors for the \"Add to cart\" button on hover state" msgstr "" #: plugin-options/customization/style-options.php:312 msgid "Set the radius for the \"Add to cart\" button" msgstr "" #: plugin-options/customization/style-options.php:326 msgid "\"Add to cart\" icon" msgstr "" #: plugin-options/customization/style-options.php:327 msgid "Select an icon for the \"Add to cart\" button (optional)" msgstr "" #: plugin-options/customization/style-options.php:351 msgid "\"Add to cart\" custom icon" msgstr "" #: plugin-options/customization/style-options.php:352 msgid "" "Upload an icon you'd like to use for the \"Add to cart\" button (suggested " "32px x 32px)" msgstr "" #: plugin-options/customization/style-options.php:364 msgid "Primary button style" msgstr "" #: plugin-options/customization/style-options.php:370 msgid "" "Choose colors for the primary button<br/><small>This style will be applied " "to \"Edit title\" button on Wishlist view, \"Submit Changes\" button on " "Manage view and \"Search wishlist\" button on Search view</small>" msgstr "" #: plugin-options/customization/style-options.php:388 msgid "" "Choose colors for the primary button on hover state<br/><small>This style " "will be applied to \"Edit title\" button on Wishlist view, \"Submit " "Changes\" button on Manage view and \"Search wishlist\" button on Search " "view</small>" msgstr "" #: plugin-options/customization/style-options.php:413 msgid "Secondary button style" msgstr "" #: plugin-options/customization/style-options.php:419 #: plugin-options/customization/style-options.php:437 msgid "" "Choose colors of the secondary button<br/><small>This style will be applied " "to the buttons that allow showing and hiding the Edit title form on Wishlist " "view and \"Create new Wishlist\" button on Manage view</small>" msgstr "" #: plugin-options/customization/style-options.php:462 msgid "Wishlist table style" msgstr "" #: plugin-options/customization/style-options.php:463 msgid "" "Choose the colors for the wishlist table (when set to \"Traditional\" layout)" msgstr "" #: plugin-options/customization/style-options.php:491 msgid "Highlight color" msgstr "" #: plugin-options/customization/style-options.php:492 msgid "" "Choose the color for all sections with background<br/><small>This color will " "be used as background for the wishlist table heading and footer (when set to " "\"Traditional\" layout), and for various form across wishlist views</small>" msgstr "" #: plugin-options/customization/style-options.php:504 msgid "Share button text color" msgstr "" #: plugin-options/customization/style-options.php:505 msgid "Choose colors for share buttons text" msgstr "" #: plugin-options/customization/style-options.php:516 msgid "Text hover" msgstr "" #: plugin-options/customization/style-options.php:524 msgid "Facebook share button icon" msgstr "" #: plugin-options/customization/style-options.php:525 msgid "Select an icon for the Facebook share button" msgstr "" #: plugin-options/customization/style-options.php:531 #: plugin-options/customization/style-options.php:578 #: plugin-options/customization/style-options.php:633 #: plugin-options/customization/style-options.php:727 msgid "Show social label without icon" msgstr "" #: plugin-options/customization/style-options.php:532 #: plugin-options/customization/style-options.php:579 #: plugin-options/customization/style-options.php:634 #: plugin-options/customization/style-options.php:728 #, fuzzy msgid "Social default icon" msgstr "Texto de sociales" #: plugin-options/customization/style-options.php:538 msgid "Facebook share button custom icon" msgstr "" #: plugin-options/customization/style-options.php:539 msgid "" "Upload an icon you'd like to use for Facebook share button (suggested 32px x " "32px)" msgstr "" #: plugin-options/customization/style-options.php:551 msgid "Facebook share button style" msgstr "" #: plugin-options/customization/style-options.php:552 msgid "Choose colors for Facebook share button" msgstr "" #: plugin-options/customization/style-options.php:563 #: plugin-options/customization/style-options.php:610 #: plugin-options/customization/style-options.php:665 #: plugin-options/customization/style-options.php:712 #: plugin-options/customization/style-options.php:759 msgid "Background hover" msgstr "" #: plugin-options/customization/style-options.php:571 msgid "Twitter (X) share button icon" msgstr "" #: plugin-options/customization/style-options.php:572 msgid "Select an icon for the Twitter (X) share button" msgstr "" #: plugin-options/customization/style-options.php:585 msgid "Twitter (X) share button custom icon" msgstr "" #: plugin-options/customization/style-options.php:586 msgid "" "Upload an icon you'd like to use for Twitter (X) share button (suggested " "32px x 32px)" msgstr "" #: plugin-options/customization/style-options.php:598 msgid "Twitter (X) share button style" msgstr "" #: plugin-options/customization/style-options.php:599 msgid "Choose colors for Twitter (X) share button" msgstr "" #: plugin-options/customization/style-options.php:618 #, fuzzy msgid "Pinterest image" msgstr "Compartir en Pinterest" #: plugin-options/customization/style-options.php:619 msgid "Set an image to share the list on Pinterest" msgstr "" #: plugin-options/customization/style-options.php:626 msgid "Pinterest share button icon" msgstr "" #: plugin-options/customization/style-options.php:627 msgid "Select an icon for the Pinterest share button" msgstr "" #: plugin-options/customization/style-options.php:640 msgid "Pinterest share button custom icon" msgstr "" #: plugin-options/customization/style-options.php:641 msgid "" "Upload an icon you'd like to use for Pinterest share button (suggested 32px " "x 32px)" msgstr "" #: plugin-options/customization/style-options.php:653 msgid "Pinterest share button style" msgstr "" #: plugin-options/customization/style-options.php:654 msgid "Choose colors for Pinterest share button" msgstr "" #: plugin-options/customization/style-options.php:673 msgid "Email share button icon" msgstr "" #: plugin-options/customization/style-options.php:674 msgid "Select an icon for the Email share button" msgstr "" #: plugin-options/customization/style-options.php:680 msgid "Show email label without icon" msgstr "" #: plugin-options/customization/style-options.php:681 msgid "Email default icon" msgstr "" #: plugin-options/customization/style-options.php:687 msgid "Email share button custom icon" msgstr "" #: plugin-options/customization/style-options.php:688 msgid "" "Upload an icon you'd like to use for the Email share button (suggested 32px " "x 32px)" msgstr "" #: plugin-options/customization/style-options.php:700 msgid "Email share button style" msgstr "" #: plugin-options/customization/style-options.php:701 msgid "Choose colors for the Email share button" msgstr "" #: plugin-options/customization/style-options.php:720 msgid "WhatsApp share button icon" msgstr "" #: plugin-options/customization/style-options.php:721 msgid "Select an icon for the WhatsApp share button" msgstr "" #: plugin-options/customization/style-options.php:734 msgid "WhatsApp share button custom icon" msgstr "" #: plugin-options/customization/style-options.php:735 msgid "" "Upload an icon you'd like to use for WhatsApp share button (suggested 32px x " "32px)" msgstr "" #: plugin-options/customization/style-options.php:747 msgid "WhatsApp share button style" msgstr "" #: plugin-options/customization/style-options.php:748 msgid "Choose colors for WhatsApp share button" msgstr "" #: plugin-options/icons-list.php:21 msgctxt "[Admin] The icon label show in the select" msgid "Bookmark" msgstr "" #: plugin-options/icons-list.php:28 msgctxt "[Admin] The icon label show in the select" msgid "Bookmark outline" msgstr "" #: plugin-options/icons-list.php:35 msgctxt "[Admin] The icon label show in the select" msgid "Heart" msgstr "" #: plugin-options/icons-list.php:42 msgctxt "[Admin] The icon label show in the select" msgid "Heart outline" msgstr "" #: plugin-options/icons-list.php:49 msgctxt "[Admin] The icon label show in the select" msgid "Heart remove" msgstr "" #: plugin-options/icons-list.php:56 msgctxt "[Admin] The icon label show in the select" msgid "Heart arrows" msgstr "" #: plugin-options/icons-list.php:64 msgctxt "[Admin] The icon label show in the select" msgid "Heart check" msgstr "" #: plugin-options/icons-list.php:71 msgctxt "[Admin] The icon label show in the select" msgid "Star" msgstr "" #: plugin-options/icons-list.php:78 msgctxt "[Admin] The icon label show in the select" msgid "Star outline" msgstr "" #: plugin-options/icons-list.php:85 msgctxt "[Admin] The icon label show in the select" msgid "Plus" msgstr "" #: plugin-options/icons-list.php:91 msgctxt "[Admin] The icon label show in the select" msgid "Plus circle" msgstr "" #: plugin-options/icons-list.php:99 msgctxt "[Admin] The icon label show in the select" msgid "Plus circle outline" msgstr "" #: plugin-options/icons-list.php:107 msgctxt "[Admin] The icon label show in the select" msgid "Shopping bag" msgstr "" #: plugin-options/icons-list.php:113 msgctxt "[Admin] The icon label show in the select" msgid "Shopping bag outline" msgstr "" #: plugin-options/icons-list.php:119 msgctxt "[Admin] The icon label show in the select" msgid "Shopping cart" msgstr "" #: plugin-options/icons-list.php:125 msgctxt "[Admin] The icon label show in the select" msgid "Shopping cart outline" msgstr "" #: plugin-options/icons-list.php:131 msgctxt "[Admin] The icon label show in the select" msgid "Calculator" msgstr "" #: plugin-options/icons-list.php:137 msgctxt "[Admin] The icon label show in the select" msgid "Calculator outline" msgstr "" #: plugin-options/icons-list.php:143 msgctxt "[Admin] The icon label show in the select" msgid "Chat bubble" msgstr "" #: plugin-options/icons-list.php:149 msgctxt "[Admin] The icon label show in the select" msgid "Chat bubble outline" msgstr "" #: plugin-options/icons-list.php:155 msgctxt "[Admin] The icon label show in the select" msgid "Document arrow up" msgstr "" #: plugin-options/icons-list.php:161 msgctxt "[Admin] The icon label show in the select" msgid "Document arrow up outline" msgstr "" #: plugin-options/icons-list.php:167 msgctxt "[Admin] The icon label show in the select" msgid "Document chart bar" msgstr "" #: plugin-options/icons-list.php:173 msgctxt "[Admin] The icon label show in the select" msgid "Document chart bar outline" msgstr "" #: plugin-options/icons-list.php:179 msgctxt "[Admin] The icon label show in the select" msgid "Document text" msgstr "" #: plugin-options/icons-list.php:185 msgctxt "[Admin] The icon label show in the select" msgid "Document text outline" msgstr "" #: plugin-options/icons-list.php:191 msgctxt "[Admin] The icon label show in the select" msgid "Question mark" msgstr "" #: plugin-options/icons-list.php:197 msgctxt "[Admin] The icon label show in the select" msgid "Question mark outline" msgstr "" #: plugin-options/icons-list.php:203 msgctxt "[Admin] The icon label show in the select" msgid "Receipt percent" msgstr "" #: plugin-options/icons-list.php:209 msgctxt "[Admin] The icon label show in the select" msgid "Receipt percent outline" msgstr "" #: plugin-options/lists-options.php:41 msgid "Search list" msgstr "" #: plugin-options/settings-options.php:12 #, fuzzy msgctxt "Tab title in plugin settings panel" msgid "General" msgstr "Configuraciones generales" #: plugin-options/settings-options.php:14 msgctxt "Tab description in plugin settings panel" msgid "Configure the plugin general settings." msgstr "" #: plugin-options/settings-options.php:17 #, fuzzy msgctxt "Tab title in plugin settings panel" msgid "Add to wishlist" msgstr "Ya está en tu lista de deseos!" #: plugin-options/settings-options.php:19 #, fuzzy msgctxt "Tab description in plugin settings panel" msgid "Configure the Add to wishlist settings." msgstr "Ya está en tu lista de deseos!" #: plugin-options/settings-options.php:22 #, fuzzy msgctxt "Tab title in plugin settings panel" msgid "Wishlist page" msgstr "Lista de deseos" #: plugin-options/settings-options.php:24 msgctxt "Tab description in plugin settings panel" msgid "Configure the wishlist page settings." msgstr "" #: plugin-options/settings/add_to_wishlist-options.php:29 #: plugin-options/settings/general-options.php:32 #, fuzzy msgid "General settings" msgstr "Configuraciones generales" #: plugin-options/settings/add_to_wishlist-options.php:36 msgid "After product is added to wishlist" msgstr "" #: plugin-options/settings/add_to_wishlist-options.php:37 msgid "" "Choose the look of the Wishlist button when the product has already been " "added to a wishlist" msgstr "" #: plugin-options/settings/add_to_wishlist-options.php:40 #, fuzzy msgid "Show \"Add to wishlist\" button" msgstr "Ya está en tu lista de deseos!" #: plugin-options/settings/add_to_wishlist-options.php:41 msgid "Show \"View wishlist\" link" msgstr "" #: plugin-options/settings/add_to_wishlist-options.php:42 msgid "Show \"Remove from list\" link" msgstr "" #: plugin-options/settings/add_to_wishlist-options.php:55 msgid "Loop settings" msgstr "" #: plugin-options/settings/add_to_wishlist-options.php:57 msgid "" "Loop options will be visible on Shop page, category pages, product " "shortcodes, products sliders, and all the other places where the WooCommerce " "products' loop is used" msgstr "" #: plugin-options/settings/add_to_wishlist-options.php:62 msgid "Show \"Add to wishlist\" in loop" msgstr "" #: plugin-options/settings/add_to_wishlist-options.php:63 msgid "Enable the \"Add to wishlist\" feature in WooCommerce products' loop" msgstr "" #: plugin-options/settings/add_to_wishlist-options.php:71 msgid "Position of \"Add to wishlist\" in loop" msgstr "" #: plugin-options/settings/add_to_wishlist-options.php:72 msgid "" "Choose where to show \"Add to wishlist\" button or link in WooCommerce " "products' loop. <span class=\"addon\">Copy this shortcode <span " "class=\"code\"><code>[yith_wcwl_add_to_wishlist]</code></span> and paste it " "where you want to show the \"Add to wishlist\" link or button</span>" msgstr "" #: plugin-options/settings/add_to_wishlist-options.php:79 msgid "On top of the image" msgstr "" #: plugin-options/settings/add_to_wishlist-options.php:80 msgid "Before \"Add to cart\" button" msgstr "" #: plugin-options/settings/add_to_wishlist-options.php:81 msgid "After \"Add to cart\" button" msgstr "" #: plugin-options/settings/add_to_wishlist-options.php:82 #: plugin-options/settings/add_to_wishlist-options.php:114 msgid "Use shortcode" msgstr "Usar shortcode" #: plugin-options/settings/add_to_wishlist-options.php:96 msgid "Product page settings" msgstr "" #: plugin-options/settings/add_to_wishlist-options.php:103 msgid "Position of \"Add to wishlist\" on product page" msgstr "" #: plugin-options/settings/add_to_wishlist-options.php:104 msgid "" "Choose where to show \"Add to wishlist\" button or link on the product page. " "<span class=\"addon\">Copy this shortcode <span " "class=\"code\"><code>[yith_wcwl_add_to_wishlist]</code></span> and paste it " "where you want to show the \"Add to wishlist\" link or button</span>" msgstr "" #: plugin-options/settings/add_to_wishlist-options.php:111 msgid "After \"Add to cart\"" msgstr "Después de \"Agregar al carrito\"" #: plugin-options/settings/add_to_wishlist-options.php:112 msgid "After thumbnails" msgstr "Después de las miniaturas" #: plugin-options/settings/add_to_wishlist-options.php:113 msgid "After summary" msgstr "Después del resúmen" #: plugin-options/settings/general-options.php:38 msgid "Enable AJAX loading" msgstr "" #: plugin-options/settings/general-options.php:39 msgid "Load any cacheable wishlist item via AJAX" msgstr "" #: plugin-options/settings/general-options.php:53 msgid "YITH WooCommerce Frequently Bought Together Integration" msgstr "" #: plugin-options/settings/general-options.php:59 msgid "Enable slider in wishlist" msgstr "" #: plugin-options/settings/general-options.php:60 #, fuzzy msgid "Enable the slider with linked products on the Wishlist page." msgstr "" "¡Ups! Ha ocurrido un error al eliminar el producto de tu lista. Intenta " "nuevamente, por favor." #: plugin-options/settings/wishlist_page-options.php:36 msgid "" "Pick a page as the main Wishlist page; make sure you add the <span " "class=\"code\"><code>[yith_wcwl_wishlist]</code></span> shortcode into the " "page content" msgstr "" #: plugin-options/settings/wishlist_page-options.php:49 #, fuzzy msgid "Wishlist detail page" msgstr "Lista de deseos" #: plugin-options/settings/wishlist_page-options.php:56 #: plugin-options/settings/wishlist_page-options.php:65 #: plugin-options/settings/wishlist_page-options.php:74 #: plugin-options/settings/wishlist_page-options.php:83 #: plugin-options/settings/wishlist_page-options.php:92 #: plugin-options/settings/wishlist_page-options.php:101 #: plugin-options/settings/wishlist_page-options.php:110 msgid "In wishlist table show" msgstr "" #: plugin-options/settings/wishlist_page-options.php:57 msgid "Product variations selected by the user (example: size or color)" msgstr "" #: plugin-options/settings/wishlist_page-options.php:66 msgid "Product price" msgstr "" #: plugin-options/settings/wishlist_page-options.php:75 msgid "Product stock (show if the product is available or not)" msgstr "" #: plugin-options/settings/wishlist_page-options.php:84 msgid "Date on which the product was added to the wishlist" msgstr "" #: plugin-options/settings/wishlist_page-options.php:93 msgid "Add to cart option for each product" msgstr "" #: plugin-options/settings/wishlist_page-options.php:102 msgid "" "Icon to remove the product from the wishlist - to the left of the product" msgstr "" #: plugin-options/settings/wishlist_page-options.php:111 msgid "" "Button to remove the product from the wishlist - to the right of the product" msgstr "" #: plugin-options/settings/wishlist_page-options.php:119 msgid "Redirect to cart" msgstr "Redireccionar al carrito" #: plugin-options/settings/wishlist_page-options.php:120 msgid "" "Redirect users to the cart page when they add a product to the cart from the " "wishlist page" msgstr "" #: plugin-options/settings/wishlist_page-options.php:128 #, fuzzy msgid "Remove items when added to the cart" msgstr "Eliminar después de agregar al carrito" #: plugin-options/settings/wishlist_page-options.php:129 msgid "" "Remove the product from the wishlist after it has been added to the cart" msgstr "" #: plugin-options/settings/wishlist_page-options.php:137 msgid "Share wishlist" msgstr "" #: plugin-options/settings/wishlist_page-options.php:138 msgid "Enable this option to let users share their wishlist on social media" msgstr "" #: plugin-options/settings/wishlist_page-options.php:146 #: plugin-options/settings/wishlist_page-options.php:155 #: plugin-options/settings/wishlist_page-options.php:164 #: plugin-options/settings/wishlist_page-options.php:173 #: plugin-options/settings/wishlist_page-options.php:182 msgid "Share on social media" msgstr "" #: plugin-options/settings/wishlist_page-options.php:174 msgid "Share by email" msgstr "" #: plugin-options/settings/wishlist_page-options.php:191 msgid "Share by URL" msgstr "" #: plugin-options/settings/wishlist_page-options.php:192 msgid "Show \"Share URL\" field on wishlist page" msgstr "" #: templates/react-preview-toggle.php:20 msgid "Preview mode" msgstr "" #: templates/react-preview-toggle.php:28 msgid "" "Your site is in preview mode: in this way, you can see how the new React " "Components would work on your site.<br><br>Is everything working smoothly?" msgstr "" #: templates/react-preview-toggle.php:33 msgid "Yes! Convert PHP templates to React" msgstr "" #: templates/react-preview-toggle.php:36 msgid "No, thanks, close the preview" msgstr "" #: templates/share.php:56 templates/share.php:57 msgid "Facebook" msgstr "" #: templates/share.php:64 templates/share.php:65 msgid "Twitter (X)" msgstr "" #: templates/share.php:72 templates/share.php:73 msgid "Pinterest" msgstr "Compartir en Pinterest" #: templates/share.php:102 templates/share.php:103 msgid "Email" msgstr "" #: templates/share.php:110 msgid "WhatsApp" msgstr "" #: templates/share.php:111 msgid "Whatsapp" msgstr "" #: templates/share.php:120 msgid "(Now" msgstr "" #: templates/share.php:120 msgid "copy" msgstr "" #: templates/share.php:120 msgid "this wishlist link and share it anywhere)" msgstr "" #: templates/wishlist-view-footer-mobile.php:55 #: templates/wishlist-view-footer.php:55 msgid "Apply this action to all the selected items:" msgstr "" #: templates/wishlist-view-footer-mobile.php:73 #: templates/wishlist-view-footer.php:73 msgid "Remove from wishlist" msgstr "" #. translators: 1. Wishlist formatted name. #: templates/wishlist-view-footer-mobile.php:93 #: templates/wishlist-view-footer.php:93 #, php-format msgid "Move to %s" msgstr "" #: templates/wishlist-view-footer-mobile.php:99 #: templates/wishlist-view-footer.php:99 msgid "Apply" msgstr "" #: templates/wishlist-view-footer-mobile.php:107 #: templates/wishlist-view-footer.php:107 msgid "Update" msgstr "" #: templates/wishlist-view-footer-mobile.php:113 #: templates/wishlist-view-footer.php:151 msgid "Add all to cart" msgstr "" #: templates/wishlist-view-header.php:86 msgid "Edit title" msgstr "Título de la Lista de deseos" #: templates/wishlist-view-mobile.php:143 msgid "Added on:" msgstr "" #: templates/wishlist-view-mobile.php:154 msgid "Price:" msgstr "" #: templates/wishlist-view-mobile.php:181 msgid "Quantity:" msgstr "" #: templates/wishlist-view-mobile.php:196 msgid "Stock:" msgstr "" #: templates/wishlist-view-mobile.php:199 templates/wishlist-view.php:431 msgid "Out of stock" msgstr "" #: templates/wishlist-view-mobile.php:199 templates/wishlist-view.php:431 msgid "In Stock" msgstr "¡Disponible!" #: templates/wishlist-view-mobile.php:232 templates/wishlist-view.php:544 msgid "Move" msgstr "" #: templates/wishlist-view-mobile.php:263 templates/wishlist-view.php:575 msgid "Move to another list ›" msgstr "" #: templates/wishlist-view-mobile.php:283 templates/wishlist-view.php:250 #: templates/wishlist-view.php:607 msgid "Remove this product" msgstr "Ya no lo quiero" #: templates/wishlist-view-mobile.php:304 templates/wishlist-view.php:649 msgid "No products added to the wishlist" msgstr "" #: templates/wishlist-view.php:102 msgid "Product name" msgstr "" #: templates/wishlist-view.php:122 msgid "Unit price" msgstr "" #: templates/wishlist-view.php:143 msgid "Quantity" msgstr "" #: templates/wishlist-view.php:164 msgid "Stock status" msgstr "" #: templates/wishlist-view.php:206 msgid "Arrange" msgstr "" #. translators: 1. Date product was added to wishlist. #: templates/wishlist-view.php:479 #, php-format msgid "Added on: %s" msgstr "" #: templates/wishlist-view.php:607 msgid "Remove" msgstr "" #: views/rendering-methods/modal/footer.php:14 msgid "Preview your site in a new tab" msgstr "" #: views/rendering-methods/modal/footer.php:17 msgid "Convert PHP templates to React" msgstr "" #: views/rendering-methods/modal/footer.php:20 msgid "No, thanks, I'll wait until the next update" msgstr "" #. translators: %1$s is the placeholder for the HTML opening tag to hyperlink the text; %2$s is the placeholder for the HTML closing tag to hyperlink the text; #: views/rendering-methods/react-only-option-notice.php:14 #, php-format msgid "" "This option is available only in the new React templates. %1$s Convert your " "templates now to unlock all the new features > %2$s" msgstr "" #: assets/js/dist/components/add-to-wishlist/index.js:5167 #: assets/js/dist/components/add-to-wishlist/index.js:3457 msgid "Create a new list" msgstr "" #~ msgid "Social image URL" #~ msgstr "URL de las imágenes sociales" languages/yith-woocommerce-wishlist-zh_CN.mo 0000777 00000003214 15251156646 0015226 0 ustar 00 �� � h i � "