File: /home/mciraet/www/wp-content/plugins/polylang-wc/src/admin/admin-products.php
<?php
/**
* @package Polylang-WC
*/
/**
* Manages the products on admin side.
*
* @since 0.1
*/
class PLLWC_Admin_Products {
/**
* Product language data store.
*
* @var PLLWC_Product_Language_CPT
*/
protected $data_store;
/**
* Constructor.
* Setups actions and filters.
*
* @since 0.1
*/
public function __construct() {
$this->data_store = PLLWC_Data_Store::load( 'product_language' );
// Ajax.
add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
add_action( 'wp_ajax_product_lang_choice', array( $this, 'product_lang_choice' ) );
// Ajax product ordering.
if ( in_array( 'menu_order', PLL()->options['sync'] ) ) {
add_action( 'woocommerce_after_product_ordering', array( $this, 'product_ordering' ), 10, 2 );
}
// Autocomplete ajax products search.
add_filter( 'woocommerce_json_search_found_products', array( $this, 'search_found_products' ) );
add_filter( 'woocommerce_json_search_found_grouped_products', array( $this, 'search_found_products' ) );
// Search in Products list table.
add_filter( 'pll_filter_query_excluded_query_vars', array( $this, 'fix_products_search' ), 10, 2 ); // Since Polylang 2.3.5.
// Deactivate the German and Danish specific sanitization for product attributes titles.
$specific_locales = array( 'da_DK', 'de_DE', 'de_DE_formal', 'de_CH', 'de_CH_informal' );
if ( array_intersect( PLL()->model->get_languages_list( array( 'fields' => 'locale' ) ), $specific_locales ) ) {
add_action( 'wp_ajax_woocommerce_load_variations', array( $this, 'remove_sanitize_title' ), 5 );
add_action( 'woocommerce_product_write_panel_tabs', array( $this, 'remove_sanitize_title' ), 5 );
add_action( 'woocommerce_product_data_panels', array( $this, 'add_sanitize_title' ), 5 );
}
}
/**
* Setups the our js script (only on the products page).
*
* @since 0.1
*
* @return void
*/
public function admin_enqueue_scripts() {
$screen = get_current_screen();
if ( ! empty( $screen ) && 'post' === $screen->base && 'product' === $screen->post_type ) {
$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
wp_enqueue_script( 'pllwc_product', plugins_url( '/js/build/product' . $suffix . '.js', PLLWC_FILE ), array( 'jquery', 'wp-ajax-response' ), PLLWC_VERSION, true );
}
}
/**
* Ajax response for changing the language in the product language metabox.
*
* @since 0.1
*
* @return void
*/
public function product_lang_choice() {
check_ajax_referer( 'pll_language', '_pll_nonce' );
if ( isset( $_POST['post_id'], $_POST['lang'], $_POST['attributes'] ) && is_array( $_POST['attributes'] ) ) {
$post_id = (int) $_POST['post_id'];
$lang = PLL()->model->get_language( sanitize_key( $_POST['lang'] ) );
$attributes = array_map( 'sanitize_title', wp_unslash( $_POST['attributes'] ) );
$supplemental = array();
$x = new WP_Ajax_Response();
// Attributes (taxonomies of select type).
foreach ( wc_get_attribute_taxonomies() as $a ) {
$taxonomy = wc_attribute_taxonomy_name( $a->attribute_name );
if ( 'select' === $a->attribute_type && false !== $i = array_search( $taxonomy, $attributes ) ) {
$out = '';
$product_terms = get_the_terms( $post_id, $taxonomy );
$term_ids = is_array( $product_terms ) ? wp_list_pluck( $product_terms, 'term_id' ) : array();
$tr_term_ids = array_map( 'pll_get_term', $term_ids );
$all_terms = get_terms( array( 'taxonomy' => $taxonomy, 'orderby' => 'name', 'hide_empty' => 0, 'lang' => $lang->slug ) );
if ( is_array( $all_terms ) ) {
foreach ( $all_terms as $term ) {
$out .= sprintf(
'<option value="%d" %s>%s</option>',
(int) $term->term_id,
selected( in_array( $term->term_id, $tr_term_ids ), true, false ),
esc_html( $term->name )
);
}
}
$supplemental[ 'value-' . $i ] = $out;
}
}
if ( ! empty( $supplemental ) ) {
$x->Add( array( 'what' => 'attributes', 'supplemental' => $supplemental ) );
}
$x->send();
}
}
/**
* Synchronizes the product ordering.
* Hooked to the action 'woocommerce_after_product_ordering'.
*
* @since 1.0
*
* @param int $id Product id.
* @param int[] $menu_orders An array with product ids as key and menu_order as value.
* @return void
*/
public function product_ordering( $id, $menu_orders ) {
$language = $this->data_store->get_language( $id );
foreach ( $menu_orders as $id => $order ) {
if ( $this->data_store->get_language( $id ) === $language ) {
foreach ( $this->data_store->get_translations( $id ) as $tr_id ) {
if ( $id !== $tr_id ) {
$this->data_store->save_product_ordering( $tr_id, $order );
}
}
}
}
}
/**
* Filters the products per language in autocomplete ajax searches.
* Hooked to the filters 'woocommerce_json_search_found_products'
* and 'woocommerce_json_search_found_grouped_products'.
*
* @since 0.1
*
* @param string[] $products array with product ids as keys and names as values.
* @return string[]
*/
public function search_found_products( $products ) {
// Either we are editing a product or an order.
if ( ! isset( $_REQUEST['pll_post_id'] ) || ! $lang = $this->data_store->get_language( (int) $_REQUEST['pll_post_id'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
$lang = PLLWC_Admin::get_preferred_language();
}
foreach ( array_keys( $products ) as $id ) {
if ( $this->data_store->get_language( $id ) !== $lang ) {
unset( $products[ $id ] );
}
}
return $products;
}
/**
* Fixes the search in the Products list table.
* It is necessary since WC 3.3.1 as the query uses 'post__in'
* which is usually excluded from the language filter.
* Hooked to the filter 'pll_filter_query_excluded_query_vars'.
*
* @since 1.0
*
* @param string[] $excludes Query vars excluded from the language filter.
* @param WP_Query $query WP Query object.
* @return string[]
*/
public function fix_products_search( $excludes, $query ) {
if ( ! empty( $query->query['product_search'] ) ) {
$excludes = array_diff( $excludes, array( 'post__in' ) );
}
return $excludes;
}
/**
* Removes the German and Danish specific sanitization for titles.
*
* @since 0.7.1
*
* @return void
*/
public function remove_sanitize_title() {
if ( isset( PLL()->filters_sanitization ) ) {
remove_filter( 'sanitize_title', array( PLL()->filters_sanitization, 'sanitize_title' ) );
}
}
/**
* Restores the German and Danish specific sanitization for titles.
*
* @since 0.7.1
*
* @return void
*/
public function add_sanitize_title() {
if ( isset( PLL()->filters_sanitization ) ) {
add_filter( 'sanitize_title', array( PLL()->filters_sanitization, 'sanitize_title' ), 10, 3 );
}
}
}