. */ if ( ! defined( 'ABSPATH' ) ) { exit; // Don't access directly. } define( 'PLLWC_VERSION', '2.1' ); define( 'PLLWC_MIN_PLL_VERSION', '3.4' ); define( 'PLLWC_FILE', __FILE__ ); // This file. define( 'PLLWC_BASENAME', plugin_basename( PLLWC_FILE ) ); // Plugin name as known by WP. require_once __DIR__ . '/vendor/autoload.php'; require_once __DIR__ . '/include/functions.php'; use Automattic\WooCommerce\Utilities\OrderUtil; /** * Plugin controller. * * @since 0.1 */ class Polylang_Woocommerce { /** * @var PLLWC_Admin_Menus */ public $admin_menus; /** * @var PLLWC_Admin_Products */ public $admin_products; /** * @var PLLWC_Admin_Product_Duplicate */ public $admin_product_duplicate; /** * @var PLLWC_Admin_Orders */ public $admin_orders; /** * @var PLLWC_Admin_Reports */ public $admin_reports; /** * @var PLLWC_Admin_Status_Reports */ public $admin_status_reports; /** * @var PLLWC_Admin_Taxonomies */ public $admin_taxonomies; /** * @var PLLWC_Admin_WC_Install */ public $admin_wc_install; /** * @var PLLWC_Frontend_Cart */ public $cart; /** * @var PLLWC_Coupons */ public $coupons; /** * @var PLLWC_Xdata */ public $data; /** * @var PLLWC_Emails */ public $emails; /** * @var PLLWC_Product_Export */ public $product_export; /** * @var PLLWC_Frontend */ public $frontend; /** * @var PLLWC_Product_Import */ public $product_import; /** * @var PLLWC_Links */ public $links; /** * @var PLLWC_Frontend_Account */ public $my_account; /** * @var PLLWC_Post_Types */ public $post_types; /** * @var PLLWC_Products */ public $products; /** * @var PLLWC_REST_API */ public $rest_api; /** * @var PLLWC_Admin_Site_Health */ public $site_health; /** * @var PLLWC_Stock */ public $stock; /** * @var PLLWC_Strings */ public $strings; /** * @var PLLWC_Sync_Content */ public $sync_content; /** * @var PLLWC_Frontend_WC_Pages */ public $wc_pages; /** * @var PLLWC_Wizard */ public $wizard; /** * @var PLLWC_Translation_Export|null */ public $translation_export; /** * @var PLLWC_Translation_Import|null */ public $translation_import; /** * @var PLLWC_HPOS_Orders_Query|null */ public $hpos_orders_query; /** * @var PLLWC_Feature|null */ public $hpos_feature; /** * @var PLLWC_Store_Blocks */ public $blocks; /** * Singleton. * * @var Polylang_Woocommerce */ protected static $instance; /** * Constructor. * * @since 0.1 */ public function __construct() { // Registers an action when the plugin is activated. add_action( 'activated_plugin', array( $this, 'activated_plugin' ), 10, 2 ); $install = new PLLWC_Install( plugin_basename( __FILE__ ) ); // Stopping here if we are going to deactivate the plugin ( avoids breaking rewrite rules ). if ( $install->is_deactivation() ) { return; } // WC 3.3: Maybe update default product categories after WooCommerce did it. $db_version = get_option( 'woocommerce_db_version' ); if ( is_string( $db_version ) && version_compare( $db_version, '3.3.0', '<' ) ) { add_action( 'add_option_woocommerce_db_version', array( 'PLLWC_Admin_WC_Install', 'update_330_wc_db_version' ), 10, 2 ); } /* * Fix home url when using plain permalinks and the shop is on front. * Added here because the filter is fired before the action 'pll_init'. */ add_filter( 'pll_additional_language_data', array( 'PLLWC_Links', 'set_home_url' ), 20, 2 ); // After Polylang. add_filter( 'pll_is_ajax_on_front', array( $this, 'fix_ajax_product_import' ) ); // The "ajax" request for feature product is indeed a direct link and thus does not include the pll_ajax_backend query var. if ( isset( $_GET['action'] ) && 'woocommerce_feature_product' === $_GET['action'] ) { // phpcs:ignore WordPress.Security.NonceVerification define( 'PLL_ADMIN', true ); } // Before Polylang is loaded. add_action( 'plugins_loaded', array( $this, 'declare_features_compatibility' ), 0 ); add_action( 'pll_init', array( $this, 'init' ) ); PLLWC_Plugins_Compat::instance(); } /** * Get the Polylang for WooCommerce instance. * * @since 0.1 * * @return Polylang_Woocommerce */ public static function instance() { if ( empty( self::$instance ) ) { self::$instance = new self(); } return self::$instance; } /** * Tells Polylang that the product import ajax request is made from the backend. * * @since 1.5.3 * * @param bool $is_ajax_on_front Whether the current request is an ajax request on front. * @return bool */ public function fix_ajax_product_import( $is_ajax_on_front ) { return isset( $_POST['action'] ) && 'woocommerce_do_ajax_product_import' === $_POST['action'] ? false : $is_ajax_on_front; // phpcs:ignore WordPress.Security.NonceVerification } /** * Initializes the plugin. * * @since 0.1 * * @return void */ public function init() { // Silently disable the plugin if WooCommerce are not active. if ( ! defined( 'WOOCOMMERCE_VERSION' ) ) { return; } // If the version of Polylang is too old. if ( version_compare( POLYLANG_VERSION, PLLWC_MIN_PLL_VERSION, '<' ) ) { add_action( 'all_admin_notices', array( $this, 'admin_notices' ) ); return; } if ( PLL() instanceof PLL_Admin_Base ) { new PLL_License( __FILE__, 'Polylang for WooCommerce', PLLWC_VERSION, 'Frédéric Demarle' ); new PLL_T15S( 'polylang-wc', 'https://packages.translationspress.com/wp-syntex/polylang-wc/packages.json' ); } // Instantiate PLL_Wizard before any language test to display the WooCommerce step in the Wizard. if ( PLL() instanceof PLL_Admin_Base ) { if ( class_exists( 'PLL_Wizard' ) && Polylang::is_wizard() && isset( PLL()->wizard ) ) { $this->wizard = new PLLWC_Wizard( PLL()->model, PLL()->wizard ); } $this->admin_status_reports = new PLLWC_Admin_Status_Reports(); load_plugin_textdomain( 'polylang-wc' ); } add_action( 'admin_init', array( $this, 'maybe_install' ) ); // Bail early if no language has been defined yet. if ( ! pll_languages_list() ) { return; } // Custom order tables for WooCommerce (HPOS). if ( ! empty( $this->hpos_feature ) && $this->hpos_feature->is_enabled() ) { $this->hpos_orders_query = ( new PLLWC_HPOS_Orders_Query() )->init(); } add_action( 'admin_init', array( $this, 'maybe_upgrade' ) ); add_action( 'woocommerce_delete_product_transients', array( $this, 'delete_product_transients' ) ); PLLWC_Variation_Data_Store_CPT::init(); $this->post_types = new PLLWC_Post_Types(); $this->links = defined( 'POLYLANG_PRO' ) && POLYLANG_PRO && get_option( 'permalink_structure' ) ? new PLLWC_Links_Pro() : new PLLWC_Links(); $this->stock = new PLLWC_Stock(); $this->emails = new PLLWC_Emails(); $this->strings = new PLLWC_Strings(); $this->data = new PLLWC_Xdata(); $this->product_export = new PLLWC_Product_Export(); $this->product_import = new PLLWC_Product_Import(); $this->products = new PLLWC_Products(); $this->blocks = new PLLWC_Store_Blocks(); $this->blocks->init(); if ( defined( 'POLYLANG_PRO' ) && POLYLANG_PRO ) { $this->rest_api = new PLLWC_REST_API(); $this->sync_content = new PLLWC_Sync_Content(); } /* * We need to load our cart integration on all ajax requests, as WooCommerce does, * but also on REST requests for WooCommerce Blocks 2.5+. */ if ( PLL() instanceof PLL_Frontend || wp_doing_ajax() || PLL() instanceof PLL_REST_Request ) { $this->cart = new PLLWC_Frontend_Cart(); } // Frontend only. if ( PLL() instanceof PLL_Frontend ) { $this->frontend = new PLLWC_Frontend(); $this->my_account = new PLLWC_Frontend_Account(); $this->coupons = new PLLWC_Coupons(); // WC pages on front. if ( 'page' === get_option( 'show_on_front' ) ) { $this->wc_pages = new PLLWC_Frontend_WC_Pages(); } } else { $this->admin_wc_install = new PLLWC_Admin_WC_Install(); // Admin only ( but not useful on Polylang settings pages ). if ( PLL() instanceof PLL_Admin ) { $this->admin_taxonomies = new PLLWC_Admin_Taxonomies(); $this->admin_products = new PLLWC_Admin_Products(); $this->admin_product_duplicate = new PLLWC_Admin_Product_Duplicate(); $this->admin_orders = ! empty( $this->hpos_feature ) && $this->hpos_feature->is_enabled() ? new PLLWC_Admin_Orders_HPOS() : new PLLWC_Admin_Orders_Legacy(); $this->admin_reports = new PLLWC_Admin_Reports(); $this->admin_menus = new PLLWC_Admin_Menus(); $this->coupons = new PLLWC_Admin_Coupons(); $this->site_health = new PLLWC_Admin_Site_Health(); if ( defined( 'POLYLANG_PRO' ) && POLYLANG_PRO ) { $this->translation_export = ( new PLLWC_Translation_Export() )->init(); } add_action( 'woocommerce_system_status_report', array( $this->admin_status_reports, 'status_report' ) ); add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) ); } if ( PLL() instanceof PLL_Settings && defined( 'POLYLANG_PRO' ) && POLYLANG_PRO ) { $this->translation_import = ( new PLLWC_Translation_Import() )->init(); } } /** * Fires after the Polylang for WooCommerce object is initialized. * * @since 0.3.2 * * @param object &$this The Polylang for WooCommerce object. */ do_action_ref_array( 'pllwc_init', array( &$this ) ); } /** * Displays an admin notice if Polylang is not at the right version. * * @since 0.1 * * @return void */ public function admin_notices() { load_plugin_textdomain( 'polylang-wc' ); printf( '
%s
%s