Last active
April 7, 2021 08:21
-
-
Save FrEaKmAn/70666db78b0cdf3ce5776a0f1aaf79b3 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class WCML_REST_API_Support{ | |
/** @var woocommerce_wpml */ | |
private $woocommerce_wpml; | |
/** @var Sitepress */ | |
private $sitepress; | |
/** @var WCML_REST_API_Query_Filters_Products */ | |
private $query_filters_products; | |
/** @var WCML_REST_API_Query_Filters_Orders */ | |
private $query_filters_orders; | |
/** @var WCML_REST_API_Query_Filters_Terms */ | |
private $query_filters_terms; | |
/** @var WPML_Admin_Post_Actions */ | |
private $wpml_post_translations; | |
/** | |
* WCML_REST_API_Support constructor. | |
* | |
* @param woocommerce_wpml $woocommerce_wpml | |
* @param SitePress $sitepress | |
* @param WCML_REST_API_Query_Filters_Products $query_filters_products | |
* @param WCML_REST_API_Query_Filters_Orders $query_filters_orders | |
* @param WCML_REST_API_Query_Filters_Terms $query_filters_terms | |
* @param WPML_Post_Translation $wpml_post_translations | |
*/ | |
public function __construct( | |
woocommerce_wpml $woocommerce_wpml, | |
SitePress $sitepress, | |
WCML_REST_API_Query_Filters_Products $query_filters_products, | |
WCML_REST_API_Query_Filters_Orders $query_filters_orders, | |
WCML_REST_API_Query_Filters_Terms $query_filters_terms, | |
WPML_Post_Translation $wpml_post_translations | |
) { | |
$this->woocommerce_wpml = $woocommerce_wpml; | |
$this->sitepress = $sitepress; | |
$this->query_filters_products = $query_filters_products; | |
$this->query_filters_orders = $query_filters_orders; | |
$this->query_filters_terms = $query_filters_terms; | |
$this->wpml_post_translations = $wpml_post_translations; | |
$this->prevent_default_lang_url_redirect(); | |
} | |
public function add_hooks(){ | |
add_action( 'rest_api_init', array( $this, 'set_language_for_request' ) ); | |
add_action( 'parse_query', array($this, 'auto_adjust_included_ids') ); | |
// Products | |
add_action( 'woocommerce_rest_prepare_product_object', array( $this, 'append_product_language_and_translations' ) ); | |
add_action( 'woocommerce_rest_prepare_product_object', array( $this, 'append_product_secondary_prices' ) ); | |
add_action( 'woocommerce_rest_insert_product_object', array( $this, 'set_product_language' ), 10, 2 ); | |
add_action( 'woocommerce_rest_insert_product_object', array( $this, 'set_product_custom_prices' ), 10, 2 ); | |
add_action( 'woocommerce_rest_insert_product_object', array( $this, 'set_product_images' ), 10, 2 ); | |
add_action( 'woocommerce_rest_prepare_product_cat', array( $this, 'append_category_language_and_translations' ), 10, 2 ); | |
add_action( 'woocommerce_rest_insert_product_cat', array( $this, 'set_category_language' ), 10, 2 ); | |
add_action( 'woocommerce_rest_update_product_cat', array( $this, 'set_category_language' ), 10, 2 ); | |
add_action( 'woocommerce_rest_prepare_product_tag', array( $this, 'append_tag_language_and_translations' ), 10, 2 ); | |
add_action( 'woocommerce_rest_insert_product_tag', array( $this, 'set_tag_language' ), 10, 2 ); | |
add_action( 'woocommerce_rest_update_product_tag', array( $this, 'set_tag_language' ), 10, 2 ); | |
add_action( 'woocommerce_rest_insert_product_object', array( $this, 'copy_custom_fields_from_original' ), 10, 1 ); | |
add_action( 'woocommerce_rest_prepare_product_object', array( $this, 'copy_product_custom_fields' ), 10 , 3 ); | |
// Orders | |
add_action( 'woocommerce_rest_insert_shop_order_object' , array( $this, 'set_order_language' ), 10, 2 ); | |
$this->add_hooks_specific_for_v1(); | |
$this->query_filters_products->add_hooks(); | |
$this->query_filters_orders->add_hooks(); | |
$this->query_filters_terms->add_hooks(); | |
} | |
private function add_hooks_specific_for_v1(){ | |
if ( 1 === WCML_REST_API::get_api_request_version()){ | |
add_action( 'woocommerce_rest_prepare_product', array( $this, 'append_product_language_and_translations' ) ); | |
add_action( 'woocommerce_rest_prepare_product', array( $this, 'append_product_secondary_prices' ) ); | |
add_action( 'woocommerce_rest_insert_product', array( $this, 'set_product_language' ), 10, 2 ); | |
add_action( 'woocommerce_rest_update_product', array( $this, 'set_product_language' ), 10, 2 ); | |
add_action( 'woocommerce_rest_insert_product', array( $this, 'set_product_custom_prices' ), 10, 2 ); | |
add_action( 'woocommerce_rest_update_product', array( $this, 'set_product_custom_prices' ), 10, 2 ); | |
add_action( 'woocommerce_rest_insert_product', array( $this, 'copy_custom_fields_from_original' ), 10, 1 ); | |
add_action( 'woocommerce_rest_prepare_product', array( $this, 'copy_product_custom_fields' ), 10 , 3 ); | |
add_action( 'woocommerce_rest_insert_shop_order' , array( $this, 'set_order_language' ), 10, 2 ); | |
} | |
} | |
/** | |
* Enforces the language of request as the current language to be able to filter items by language | |
* @param WP_REST_Server $wp_rest_server | |
*/ | |
public function set_language_for_request( $wp_rest_server ){ | |
if( isset( $_GET['lang'] ) ){ | |
$request_language = $_GET['lang']; | |
$active_languages = $this->sitepress->get_active_languages(); | |
if( isset( $active_languages[ $request_language ] ) ){ | |
$this->sitepress->switch_lang( $request_language ); | |
} | |
} | |
} | |
/** | |
* Prevent WPML redirection when using the default language as a parameter in the url | |
*/ | |
private function prevent_default_lang_url_redirect(){ | |
$exp = explode( '?', $_SERVER['REQUEST_URI'] ); | |
if ( ! empty( $exp[1] ) ) { | |
parse_str( $exp[1], $vars ); | |
if ( isset($vars['lang']) && $vars['lang'] === $this->sitepress->get_default_language() ) { | |
unset( $vars['lang'] ); | |
$_SERVER['REQUEST_URI'] = $exp[0] . '?' . http_build_query( $vars ); | |
} | |
} | |
} | |
/** | |
* @param WP_Query $wp_query | |
*/ | |
public function auto_adjust_included_ids( $wp_query ){ | |
$lang = $wp_query->get('lang'); | |
$include = $wp_query->get('post__in'); | |
if( empty( $lang ) && !empty( $include ) ){ | |
$filtered_include = array(); | |
foreach( $include as $id ){ | |
$filtered_include[] = apply_filters( 'translate_object_id', $id, get_post_type($id), true ); | |
} | |
$wp_query->set( 'post__in' , $filtered_include ); | |
} | |
} | |
/** | |
* Appends the language and translation information to the get_product response | |
* | |
* @param $product_data | |
* | |
* @return WP_REST_Response | |
*/ | |
public function append_product_language_and_translations( $product_data ){ | |
$product_data->data['translations'] = array(); | |
$trid = $this->sitepress->get_element_trid( $product_data->data['id'], 'post_product' ); | |
if( $trid ) { | |
$translations = $this->sitepress->get_element_translations( $trid, 'post_product' ); | |
foreach ( $translations as $translation ) { | |
if ( $translation->element_id == $product_data->data['id'] ) { | |
$product_language = $translation->language_code; | |
} else { | |
$product_data->data['translations'][ $translation->language_code ] = $translation->element_id; | |
} | |
} | |
$product_data->data['lang'] = $product_language; | |
} | |
return $product_data; | |
} | |
/** | |
* Appends the language and translation information to the get_categories response | |
* | |
* @param $product_data | |
* | |
* @return WP_REST_Response | |
*/ | |
public function append_category_language_and_translations( $category_data ){ | |
$category_data->data['translations'] = array(); | |
$trid = $this->sitepress->get_element_trid( $category_data->data['id'], 'tax_product_cat' ); | |
if( $trid ) { | |
$translations = $this->sitepress->get_element_translations( $trid, 'tax_product_cat' ); | |
foreach ( $translations as $translation ) { | |
if ( $translation->element_id == $category_data->data['id'] ) { | |
$category_language = $translation->language_code; | |
} else { | |
$category_data->data['translations'][ $translation->language_code ] = $translation->element_id; | |
} | |
} | |
$category_data->data['lang'] = $category_language; | |
} | |
return $category_data; | |
} | |
/** | |
* Appends the language and translation information to the get_tags response | |
* | |
* @param $product_data | |
* | |
* @return WP_REST_Response | |
*/ | |
public function append_tag_language_and_translations( $tag_data ){ | |
$tag_data->data['translations'] = array(); | |
$trid = $this->sitepress->get_element_trid( $tag_data->data['id'], 'tax_product_tag' ); | |
if( $trid ) { | |
$translations = $this->sitepress->get_element_translations( $trid, 'tax_product_tag' ); | |
foreach ( $translations as $translation ) { | |
if ( $translation->element_id == $tag_data->data['id'] ) { | |
$tag_language = $translation->language_code; | |
} else { | |
$tag_data->data['translations'][ $translation->language_code ] = $translation->element_id; | |
} | |
} | |
$tag_data->data['lang'] = $tag_language; | |
} | |
return $tag_data; | |
} | |
/** | |
* Appends the secondary prices information to the get_product response | |
* | |
* @param $product_data | |
* | |
* @return WP_REST_Response | |
*/ | |
public function append_product_secondary_prices( $product_data ){ | |
if( !empty($this->woocommerce_wpml->multi_currency) && !empty($this->woocommerce_wpml->settings['currencies_order']) ){ | |
$product_data->data['multi-currency-prices'] = array(); | |
$custom_prices_on = get_post_meta( $product_data->data['id'], '_wcml_custom_prices_status', true); | |
foreach( $this->woocommerce_wpml->settings['currencies_order'] as $currency ){ | |
if( $currency !== wcml_get_woocommerce_currency_option() ){ | |
if( $custom_prices_on ){ | |
$custom_prices = (array) $this->woocommerce_wpml->multi_currency->custom_prices->get_product_custom_prices( $product_data->data['id'], $currency ); | |
foreach( $custom_prices as $key => $price){ | |
$product_data->data['multi-currency-prices'][$currency][ preg_replace('#^_#', '', $key) ] = $price; | |
} | |
} else { | |
$product_data->data['multi-currency-prices'][$currency]['regular_price'] = | |
$this->woocommerce_wpml->multi_currency->prices->raw_price_filter( $product_data->data['regular_price'], $currency ); | |
if( !empty($product_data->data['sale_price']) ){ | |
$product_data->data['multi-currency-prices'][$currency]['sale_price'] = | |
$this->woocommerce_wpml->multi_currency->prices->raw_price_filter( $product_data->data['sale_price'], $currency ); | |
} | |
} | |
} | |
} | |
} | |
return $product_data; | |
} | |
/** | |
* Sets the product information according to the provided language | |
* | |
* @param WC_Product|WP_Post $product | |
* @param WP_REST_Request $request | |
* | |
* @throws WCML_REST_Invalid_Language_Exception | |
* @throws WCML_REST_Invalid_Product_Exception | |
* @throws WCML_REST_Generic_Exception | |
* | |
*/ | |
public function set_product_language( $product, $request ){ | |
$data = $request->get_params(); | |
if( isset( $data['lang'] ) && in_array( $request->get_method(), array( 'POST', 'PUT' ), true ) ){ | |
$active_languages = $this->sitepress->get_active_languages(); | |
if( !isset( $active_languages[$data['lang']] ) ){ | |
throw new WCML_REST_Invalid_Language_Exception( $data['lang'] ); | |
} | |
if( isset( $data['translation_of'] ) ){ | |
$trid = $this->sitepress->get_element_trid( $data['translation_of'], 'post_product' ); | |
if( empty($trid) ){ | |
throw new WCML_REST_Invalid_Product_Exception( $data['translation_of'] ); | |
} | |
}else{ | |
$trid = null; | |
} | |
$product_id = $this->get_product_id( $product ); | |
$this->sitepress->set_element_language_details( $product_id, 'post_product', $trid, $data['lang'] ); | |
wpml_tm_save_post( $product_id, get_post( $product_id ), ICL_TM_COMPLETE ); | |
}else{ | |
if( isset( $data['translation_of'] ) ){ | |
throw new WCML_REST_Generic_Exception( __( 'Using "translation_of" requires providing a "lang" parameter too', 'woocommerce-multilingual' ) ); | |
} | |
} | |
} | |
/** | |
* Sets the category information according to the provided language | |
* | |
* @param WP_Post $category | |
* @param WP_REST_Request $request | |
* | |
* @throws WCML_REST_Invalid_Language_Exception | |
* @throws WCML_REST_Invalid_Category_Exception | |
* @throws WCML_REST_Generic_Exception | |
* | |
*/ | |
public function set_category_language( $category, $request ){ | |
$data = $request->get_params(); | |
if( isset( $data['lang'] ) && in_array( $request->get_method(), array( 'POST', 'PUT' ), true ) ){ | |
$active_languages = $this->sitepress->get_active_languages(); | |
if( !isset( $active_languages[$data['lang']] ) ){ | |
throw new WCML_REST_Invalid_Language_Exception( $data['lang'] ); | |
} | |
if( isset( $data['translation_of'] ) ){ | |
$trid = $this->sitepress->get_element_trid( $data['translation_of'], 'tax_product_cat' ); | |
if( empty($trid) ){ | |
throw new WCML_REST_Invalid_Category_Exception( $data['translation_of'] ); | |
} | |
}else{ | |
$trid = null; | |
} | |
$category_id = $category->term_id; | |
$this->sitepress->set_element_language_details( $category_id, 'tax_product_cat', $trid, $data['lang'] ); | |
wpml_tm_save_post( $category_id, get_post( $category_id ), ICL_TM_COMPLETE ); | |
}else{ | |
if( isset( $data['translation_of'] ) ){ | |
throw new WCML_REST_Generic_Exception( __( 'Using "translation_of" requires providing a "lang" parameter too', 'woocommerce-multilingual' ) ); | |
} | |
} | |
} | |
/** | |
* Sets the tag information according to the provided language | |
* | |
* @param WP_Post $tag | |
* @param WP_REST_Request $request | |
* | |
* @throws WCML_REST_Invalid_Language_Exception | |
* @throws WCML_REST_Invalid_Tag_Exception | |
* @throws WCML_REST_Generic_Exception | |
* | |
*/ | |
public function set_tag_language( $tag, $request ){ | |
$data = $request->get_params(); | |
if( isset( $data['lang'] ) && in_array( $request->get_method(), array( 'POST', 'PUT' ), true ) ){ | |
$active_languages = $this->sitepress->get_active_languages(); | |
if( !isset( $active_languages[$data['lang']] ) ){ | |
throw new WCML_REST_Invalid_Language_Exception( $data['lang'] ); | |
} | |
if( isset( $data['translation_of'] ) ){ | |
$trid = $this->sitepress->get_element_trid( $data['translation_of'], 'tax_product_tag' ); | |
if( empty($trid) ){ | |
throw new WCML_REST_Invalid_Tag_Exception( $data['translation_of'] ); | |
} | |
}else{ | |
$trid = null; | |
} | |
$tag_id = $tag->term_id; | |
$this->sitepress->set_element_language_details( $tag_id, 'tax_product_tag', $trid, $data['lang'] ); | |
wpml_tm_save_post( $tag_id, get_post( $tag_id ), ICL_TM_COMPLETE ); | |
}else{ | |
if( isset( $data['translation_of'] ) ){ | |
throw new WCML_REST_Generic_Exception( __( 'Using "translation_of" requires providing a "lang" parameter too', 'woocommerce-multilingual' ) ); | |
} | |
} | |
} | |
/** | |
* Sets custom prices in secondary currencies for products | |
* | |
* @param WC_Product|WP_Post $product | |
* @param WP_REST_Request $request | |
* | |
* @throws WC_API_Exception | |
* | |
*/ | |
public function set_product_custom_prices( $product, $request ){ | |
$data = $request->get_params(); | |
if( !empty( $this->woocommerce_wpml->multi_currency ) ){ | |
if( !empty( $data['custom_prices'] ) ){ | |
$product_id = $this->get_product_id( $product ); | |
$original_post_id = $this->sitepress->get_original_element_id_filter( '', $product_id, 'post_product' ); | |
update_post_meta( $original_post_id, '_wcml_custom_prices_status', 1); | |
foreach( $data['custom_prices'] as $currency => $prices ){ | |
$prices_uscore = array(); | |
foreach( $prices as $k => $p){ | |
$prices_uscore['_' . $k] = $p; | |
} | |
$this->woocommerce_wpml->multi_currency->custom_prices->update_custom_prices( $original_post_id, $prices_uscore, $currency ); | |
} | |
} | |
} | |
} | |
/** | |
* Set product images | |
* | |
* @param WC_Product|WP_Post $product | |
* @param WP_REST_Request $request | |
* | |
* @throws WC_API_Exception | |
* | |
*/ | |
public function set_product_images( $product, $request ) { | |
$data = $request->get_params(); | |
if ( isset( $data['translation_of'] ) ) { | |
$product_id = $this->get_product_id( $product ); | |
$this->woocommerce_wpml->media->sync_thumbnail_id( $data['translation_of'], $product_id, $data['lang'] ); | |
$this->woocommerce_wpml->media->sync_product_gallery( $data['translation_of'] ); | |
if ( isset( $data['variations'] ) ) { | |
foreach ( $data['variations'] as $variation_id ) { | |
$this->woocommerce_wpml->media->sync_variation_thumbnail_id( $this->woocommerce_wpml->products->get_original_product_id( $variation_id ), $variation_id, $data['lang'] ); | |
} | |
} | |
} | |
} | |
/** | |
* @param WC_Product|WP_Post $product | |
*/ | |
public function copy_custom_fields_from_original( $product ){ | |
$product_id = $this->get_product_id( $product ); | |
$original_post_id = $this->sitepress->get_original_element_id_filter( '', $product_id, 'post_product' ); | |
if( $original_post_id !== $product_id ){ | |
$this->sitepress->copy_custom_fields( $original_post_id, $product_id ); | |
} | |
} | |
/** | |
* @param WP_REST_Response $response | |
* @param mixed $object | |
* @param WP_REST_Request $request | |
* | |
* Copy custom fields explicitly | |
* | |
* @return WP_REST_Response | |
*/ | |
public function copy_product_custom_fields($response, $object, $request){ | |
$data = $request->get_params(); | |
if( isset( $data['id'] ) ) { | |
$translations = $this->wpml_post_translations->get_element_translations( $data['id'], false, true ); | |
foreach ( $translations as $translation_id ) { | |
$this->sitepress->copy_custom_fields( $data['id'], $translation_id ); | |
} | |
} | |
return $response; | |
} | |
/** | |
* Sets the language for a new order | |
* | |
* @param WC_Order|WP_Post $order | |
* @param WP_REST_Request $request | |
* | |
* @throws WCML_REST_Invalid_Language_Exception | |
*/ | |
public function set_order_language( $order, $request ){ | |
$data = $request->get_params(); | |
if( isset( $data['lang'] ) ){ | |
if( $order instanceof WC_Order ){ | |
$order_id = $order->get_id(); | |
}else{ | |
$order_id = $order->ID; | |
} | |
$active_languages = $this->sitepress->get_active_languages(); | |
if( !isset( $active_languages[$data['lang']] ) ){ | |
throw new WCML_REST_Invalid_Language_Exception( $data['lang'] ); | |
} | |
update_post_meta( $order_id, 'wpml_language', $data['lang'] ); | |
} | |
} | |
/** | |
* @param WC_Order $order | |
* @param WP_REST_Request $request | |
* | |
* @throws WCML_REST_Invalid_Currency_Exception | |
*/ | |
public function set_order_currency( $order, $request ) { | |
$data = $request->get_params(); | |
if ( isset( $data['currency'] ) ) { | |
$order_id = $order->get_id(); | |
$currencies = get_woocommerce_currencies(); | |
if ( ! isset( $currencies[ $data['currency'] ] ) ) { | |
throw new WCML_REST_Invalid_Currency_Exception( $data['currency'] ); | |
} | |
update_post_meta( $order_id, '_order_currency', $data['currency'] ); | |
} | |
} | |
/** | |
* @param WC_Product|WP_Post $product | |
* | |
* @return int | |
*/ | |
private function get_product_id( $product ) { | |
if ( $product instanceof WC_Product ) { | |
return $product->get_id(); | |
} else { | |
return $product->ID; | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class WCML_REST_Invalid_Product_Exception extends WC_REST_Exception { | |
/** | |
* WCML_REST_Invalid_Product_Exception constructor. | |
* | |
* @param int $product_id | |
*/ | |
public function __construct( $product_id ) { | |
parent::__construct( | |
422, | |
sprintf( __( 'Product not found: %d', 'woocommerce-multilingual' ), | |
$product_id ), | |
422 | |
); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class WCML_REST_Invalid_Tag_Exception extends WC_REST_Exception { | |
/** | |
* WCML_REST_Invalid_Tag_Exception constructor. | |
* | |
* @param int $tag_id | |
*/ | |
public function __construct( $tag_id ) { | |
parent::__construct( | |
422, | |
sprintf( __( 'Tag not found: %d', 'woocommerce-multilingual' ), | |
$tag_id ), | |
422 | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment