WCML_REST_API_Support_V1

The WooCommerce Multilingual WCML REST API Support V1 class.

Defined (1)

The class is defined in the following location(s).

/inc/rest-api-support/class-wcml-rest-api-support-v1.php  
  1. class WCML_REST_API_Support_V1{ 
  2.  
  3. /** @var woocommerce_wpml */ 
  4. private $woocommerce_wpml; 
  5. /** @var Sitepress */ 
  6. private $sitepress; 
  7.  
  8. function __construct( &$woocommerce_wpml, &$sitepress ) { 
  9. $this->woocommerce_wpml =& $woocommerce_wpml; 
  10. $this->sitepress =& $sitepress; 
  11.  
  12. /** 
  13. * Adding hooks 
  14. */ 
  15. public function initialize() { 
  16.  
  17. $this->prevent_default_lang_url_redirect(); 
  18.  
  19. add_action( 'rest_api_init', array( $this, 'set_language_for_request' ) ); 
  20.  
  21. add_action( 'parse_query', array($this, 'auto_adjust_included_ids') ); 
  22.  
  23. // Products 
  24. add_action( 'woocommerce_rest_prepare_product', array( $this, 'append_product_language_and_translations' ) ); 
  25. add_action( 'woocommerce_rest_prepare_product', array( $this, 'append_product_secondary_prices' ) ); 
  26.  
  27. add_filter( 'woocommerce_rest_product_query', array( $this, 'filter_products_query' ), 10, 2 ); 
  28.  
  29. add_action( 'woocommerce_rest_insert_product', array( $this, 'set_product_language' ), 10, 2 ); 
  30. add_action( 'woocommerce_rest_update_product', array( $this, 'set_product_language' ), 10, 2 ); 
  31.  
  32. add_action( 'woocommerce_rest_insert_product', array( $this, 'set_product_custom_prices' ), 10, 2 ); 
  33. add_action( 'woocommerce_rest_update_product', array( $this, 'set_product_custom_prices' ), 10, 2 ); 
  34.  
  35. add_action( 'woocommerce_rest_prepare_product', array( $this, 'copy_product_custom_fields' ), 10 , 3 ); 
  36.  
  37. // Orders 
  38. add_filter( 'woocommerce_rest_shop_order_query', array( $this, 'filter_orders_by_language' ), 20, 2 ); 
  39. add_action( 'woocommerce_rest_prepare_shop_order', array( $this, 'filter_order_items_by_language'), 10, 3 ); 
  40. add_action( 'woocommerce_rest_insert_shop_order' , array( $this, 'set_order_language' ), 10, 2 ); 
  41.  
  42. // Terms 
  43. add_action( 'woocommerce_rest_product_cat_query', array($this, 'filter_terms_query' ), 10, 2 ); 
  44. add_action( 'woocommerce_rest_product_tag_query', array($this, 'filter_terms_query' ), 10, 2 ); 
  45.  
  46.  
  47. /** 
  48. * @param WP_REST_Server $wp_rest_server 
  49. * enforces the language of request as the current language to be able to filter items by language 
  50. */ 
  51. public function set_language_for_request( $wp_rest_server ) { 
  52. if( isset( $_GET['lang'] ) ) { 
  53. $request_language = $_GET['lang']; 
  54. $active_languages = $this->sitepress->get_active_languages(); 
  55. if( isset( $active_languages[ $request_language ] ) ) { 
  56. $this->sitepress->switch_lang( $request_language ); 
  57.  
  58. /** 
  59. * Prevent WPML redirection when using the default language as a parameter in the url 
  60. */ 
  61. private function prevent_default_lang_url_redirect() { 
  62. $exp = explode( '?', $_SERVER['REQUEST_URI'] ); 
  63. if ( ! empty( $exp[1] ) ) { 
  64. parse_str( $exp[1], $vars ); 
  65. if ( isset($vars['lang']) && $vars['lang'] === $this->sitepress->get_default_language() ) { 
  66. unset( $vars['lang'] ); 
  67. $_SERVER['REQUEST_URI'] = $exp[0] . '?' . http_build_query( $vars ); 
  68.  
  69. // Use url without the language parameter. Needed for the signature match. 
  70. public static function remove_wpml_global_url_filters() { 
  71. global $wpml_url_filters; 
  72. remove_filter( 'home_url', array( $wpml_url_filters, 'home_url_filter' ), - 10 ); 
  73.  
  74. /** 
  75. * When lang=all don't filter products by language 
  76. * @param array $args 
  77. * @param WP_REST_Request $request 
  78. * @return array 
  79. */ 
  80. public function filter_products_query( $args, $request ) { 
  81. $data = $request->get_params(); 
  82. if( isset( $data['lang'] ) && $data['lang'] === 'all' ) { 
  83. global $wpml_query_filter; 
  84. remove_filter( 'posts_join', array( $wpml_query_filter, 'posts_join_filter' ), 10 ); 
  85. remove_filter( 'posts_where', array( $wpml_query_filter, 'posts_where_filter' ), 10 ); 
  86. return $args; 
  87.  
  88. /** 
  89. * When lang=all don't filter terms by language 
  90. * @param array $args 
  91. * @param WP_REST_Request $request 
  92. * @return array 
  93. */ 
  94. public function filter_terms_query( $args, $request ) { 
  95. $data = $request->get_params(); 
  96. if( isset( $data['lang'] ) && $data['lang'] === 'all' ) { 
  97. remove_filter( 'terms_clauses', array( $this->sitepress, 'terms_clauses' ), 10, 4 ); 
  98. remove_filter( 'get_term', array( $this->sitepress, 'get_term_adjust_id' ), 1, 1 ); 
  99. return $args; 
  100.  
  101. /** 
  102. * @param WP_Query $wp_query 
  103. */ 
  104. public function auto_adjust_included_ids( $wp_query ) { 
  105. $lang = $wp_query->get('lang'); 
  106. $include = $wp_query->get('post__in'); 
  107. if( empty( $lang ) && !empty( $include ) ) { 
  108. $filtered_include = array(); 
  109. foreach( $include as $id ) { 
  110. $filtered_include[] = apply_filters( 'translate_object_id', $id, get_post_type($id), true ); 
  111. $wp_query->set( 'post__in' , $filtered_include ); 
  112.  
  113. /** 
  114. * Appends the language and translation information to the get_product response 
  115. * @param $product_data 
  116. * @return WP_REST_Response 
  117. */ 
  118. public function append_product_language_and_translations( $product_data ) { 
  119.  
  120. $product_data->data['translations'] = array(); 
  121.  
  122. $trid = $this->sitepress->get_element_trid( $product_data->data['id'], 'post_product' ); 
  123.  
  124. if( $trid ) { 
  125. $translations = $this->sitepress->get_element_translations( $trid, 'post_product' ); 
  126. foreach ( $translations as $translation ) { 
  127. if ( $translation->element_id == $product_data->data['id'] ) { 
  128. $product_language = $translation->language_code; 
  129. } else { 
  130. $product_data->data['translations'][ $translation->language_code ] = $translation->element_id; 
  131.  
  132. $product_data->data['lang'] = $product_language; 
  133.  
  134. return $product_data; 
  135.  
  136. /** 
  137. * Appends the secondary prices information to the get_product response 
  138. * @param $product_data 
  139. * @return WP_REST_Response 
  140. */ 
  141. public function append_product_secondary_prices( $product_data ) { 
  142.  
  143. if( !empty($this->woocommerce_wpml->multi_currency) && !empty($this->woocommerce_wpml->settings['currencies_order']) ) { 
  144.  
  145. $product_data->data['multi-currency-prices'] = array(); 
  146.  
  147. $custom_prices_on = get_post_meta( $product_data->data['id'], '_wcml_custom_prices_status', true); 
  148.  
  149. foreach( $this->woocommerce_wpml->settings['currencies_order'] as $currency ) { 
  150.  
  151. if( $currency != get_option('woocommerce_currency') ) { 
  152.  
  153. if( $custom_prices_on ) { 
  154.  
  155. $custom_prices = (array) $this->woocommerce_wpml->multi_currency->custom_prices->get_product_custom_prices( $product_data->data['id'], $currency ); 
  156. foreach( $custom_prices as $key => $price) { 
  157. $product_data->data['multi-currency-prices'][$currency][ preg_replace('#^_#', '', $key) ] = $price; 
  158.  
  159.  
  160. } else { 
  161. $product_data->data['multi-currency-prices'][$currency]['regular_price'] = 
  162. $this->woocommerce_wpml->multi_currency->prices->raw_price_filter( $product_data->data['regular_price'], $currency ); 
  163. if( !empty($product_data->data['sale_price']) ) { 
  164. $product_data->data['multi-currency-prices'][$currency]['sale_price'] = 
  165. $this->woocommerce_wpml->multi_currency->prices->raw_price_filter( $product_data->data['sale_price'], $currency ); 
  166.  
  167.  
  168.  
  169.  
  170. return $product_data; 
  171.  
  172. /** 
  173. * Sets the product information according to the provided language 
  174. * @param WP_Post $post 
  175. * @param WP_REST_Request $request 
  176. * @throws WC_REST_Exception 
  177. */ 
  178. public function set_product_language( $post, $request ) { 
  179.  
  180. $data = $request->get_params(); 
  181.  
  182. if( isset( $data['lang'] )) { 
  183. $active_languages = $this->sitepress->get_active_languages(); 
  184. if( !isset( $active_languages[$data['lang']] ) ) { 
  185. throw new WC_REST_Exception( '404', sprintf( __( 'Invalid language parameter: %s', 'woocommerce-multilingual' ), $data['lang'] ), '404' ); 
  186. if( isset( $data['translation_of'] ) ) { 
  187. $trid = $this->sitepress->get_element_trid( $data['translation_of'], 'post_product' ); 
  188. if( empty($trid) ) { 
  189. throw new WC_REST_Exception( '404', sprintf( __( 'Source product id not found: %s', 'woocommerce-multilingual' ), $data['translation_of'] ), '404' ); 
  190. }else{ 
  191. $trid = null; 
  192.  
  193. $this->sitepress->set_element_language_details( $post->ID, 'post_product', $trid, $data['lang'] ); 
  194. wpml_tm_save_post( $post->ID, $post , ICL_TM_COMPLETE ); 
  195. }else{ 
  196. if( isset( $data['translation_of'] ) ) { 
  197. throw new WC_REST_Exception( '404', __( 'Using "translation_of" requires providing a "lang" parameter too', 'woocommerce-multilingual' ), '404' ); 
  198.  
  199.  
  200. /** 
  201. * Sets custom prices in secondary currencies for products 
  202. * @param WP_Post $post 
  203. * @param WP_REST_Request $request 
  204. * @throws WC_API_Exception 
  205. */ 
  206. public function set_product_custom_prices( $post, $request ) { 
  207.  
  208. $data = $request->get_params(); 
  209.  
  210. if( !empty( $this->woocommerce_wpml->multi_currency ) ) { 
  211.  
  212. if( !empty( $data['custom_prices'] ) ) { 
  213.  
  214. $original_post_id = $this->sitepress->get_original_element_id_filter('', $post->ID, 'post_product' ); 
  215.  
  216. update_post_meta( $original_post_id, '_wcml_custom_prices_status', 1); 
  217.  
  218. foreach( $data['custom_prices'] as $currency => $prices ) { 
  219.  
  220. $prices_uscore = array(); 
  221. foreach( $prices as $k => $p) { 
  222. $prices_uscore['_' . $k] = $p; 
  223. $this->woocommerce_wpml->multi_currency->custom_prices->update_custom_prices( $original_post_id, $prices_uscore, $currency ); 
  224.  
  225.  
  226.  
  227.  
  228. /** 
  229. * @param WP_REST_Response $response 
  230. * @param mixed $object 
  231. * @param WP_REST_Request $request 
  232. * Copy custom fields explicitly 
  233. * @return WP_REST_Response 
  234. */ 
  235. public function copy_product_custom_fields($response, $object, $request) { 
  236. global $wpdb; 
  237. global $wpml_post_translations; 
  238.  
  239. $data = $request->get_params(); 
  240.  
  241. if( isset( $data['id'] ) ) { 
  242. $translations = $wpml_post_translations->get_element_translations ( $data['id'], false, true ); 
  243. foreach ( $translations as $translation_id ) { 
  244. $this->sitepress->copy_custom_fields ( $data['id'], $translation_id ); 
  245.  
  246. return $response; 
  247.  
  248. public function filter_orders_by_language( $args, $request ) { 
  249.  
  250. $lang = $request->get_param( 'lang' ); 
  251.  
  252. if( !is_null( $lang ) && $lang !== 'all' ) { 
  253.  
  254. $args['meta_query'][] = array( 
  255. 'key' => 'wpml_language',  
  256. 'value' => strval( $lang ) 
  257. ); 
  258.  
  259.  
  260. return $args; 
  261.  
  262. /** 
  263. * Filters the items of an order according to a given languages 
  264. * @param WP_REST_Response $response 
  265. * @param WC_Order $order 
  266. * @param WP_REST_Request $request 
  267. * @return WP_REST_Response 
  268. */ 
  269.  
  270. public function filter_order_items_by_language( $response, $order, $request ) { 
  271.  
  272. $lang = get_query_var('lang'); 
  273.  
  274. $order_lang = get_post_meta( $order->ID, 'wpml_language', true ); 
  275.  
  276. if( $order_lang != $lang ) { 
  277.  
  278. foreach( $response->data['line_items'] as $k => $item ) { 
  279.  
  280. global $wpdb; 
  281. $sql = "SELECT meta_value FROM {$wpdb->prefix}woocommerce_order_itemmeta WHERE order_item_id=%d AND meta_key='_product_id'"; 
  282. $product_id = $wpdb->get_var( $wpdb->prepare( $sql, $item['id']) ); 
  283.  
  284. if( $product_id ) { 
  285.  
  286. $translated_product_id = apply_filters( 'translate_object_id', $product_id, 'product', true, $lang ); 
  287.  
  288. if( $translated_product_id ) { 
  289. $translated_product = get_post( $translated_product_id ); 
  290. $response->data['line_items'][$k]['product_id'] = $translated_product_id; 
  291. if( $translated_product->post_type == 'product_variation' ) { 
  292. $post_parent = get_post( $translated_product->post_parent ); 
  293. $post_name = $post_parent->post_title; 
  294. } else { 
  295. $post_name = $translated_product->post_title; 
  296. $response->data['line_items'][$k]['name'] = $post_name; 
  297.  
  298.  
  299.  
  300.  
  301. return $response; 
  302.  
  303. /** 
  304. * Sets the language for a new order 
  305. * @param WP_Post $post 
  306. * @param WP_REST_Request $request 
  307. * @throws WC_REST_Exception 
  308. */ 
  309. public function set_order_language( $post, $request ) { 
  310.  
  311. $data = $request->get_params(); 
  312. if( isset( $data['lang'] ) ) { 
  313. $order_id = $post->ID; 
  314. $active_languages = $this->sitepress->get_active_languages(); 
  315. if( !isset( $active_languages[$data['lang']] ) ) { 
  316. throw new WC_REST_Exception( '404', sprintf( __( 'Invalid language parameter: %s' ), $data['lang'] ), '404' ); 
  317.  
  318. update_post_meta( $order_id, 'wpml_language', $data['lang'] ); 
  319.  
  320.  
  321.  
  322.  
  323.