Query.php
122 lines
| 1 | <?php |
| 2 | |
| 3 | |
| 4 | namespace WCML\Reports\Products; |
| 5 | |
| 6 | |
| 7 | use WCML\Rest\Functions; |
| 8 | |
| 9 | class Query implements \IWPML_REST_Action { |
| 10 | |
| 11 | public function add_hooks() { |
| 12 | if ( Functions::isAnalyticsRestRequest() ) { |
| 13 | add_filter( 'woocommerce_analytics_products_select_query', [ $this, 'joinProductTranslations' ] ); |
| 14 | add_filter( 'woocommerce_analytics_products_select_query', [ $this, 'translateProductTitles' ] ); |
| 15 | add_filter( 'woocommerce_analytics_variations_select_query', [ $this, 'joinProductTranslations' ] ); |
| 16 | add_filter( 'woocommerce_analytics_variations_select_query', [ $this, 'translateProductTitles' ] ); |
| 17 | } |
| 18 | } |
| 19 | |
| 20 | public function joinProductTranslations( $results ) { |
| 21 | if ( $this->isValidResultsObject( $results ) ) { |
| 22 | $previousCount = count( $results->data ); |
| 23 | $results->data = $this->merge( $results->data ); |
| 24 | if ( isset( $results->total ) ) { |
| 25 | $results->total -= $previousCount - count( $results->data ); |
| 26 | } |
| 27 | } |
| 28 | |
| 29 | return $results; |
| 30 | } |
| 31 | |
| 32 | private function isValidResultsObject( $results ) { |
| 33 | if( empty( $results->data ) || ! is_array( $results->data ) ) { |
| 34 | return false; |
| 35 | } |
| 36 | foreach ( $results->data as $val ) { |
| 37 | if ( ! isset( $val['product_id'] ) ) { |
| 38 | return false; |
| 39 | } |
| 40 | } |
| 41 | return true; |
| 42 | } |
| 43 | |
| 44 | private function merge( $products ) { |
| 45 | $currentLanguage = apply_filters( 'wpml_current_language', null ); |
| 46 | foreach( $products as $index => $product ) { |
| 47 | $productsDetails = $this->getProductLanguageDetails( $product ); |
| 48 | if ( $this->isProductTranslated( $productsDetails, $currentLanguage ) ) { |
| 49 | $products = $this->mergeTranslationIntoDefault( $products, $index, $product, $productsDetails ); |
| 50 | } |
| 51 | } |
| 52 | |
| 53 | return $products; |
| 54 | } |
| 55 | |
| 56 | private function isProductTranslated( $productDetails, $currentLanguage ) { |
| 57 | return isset( $productDetails->language_code ) |
| 58 | && $productDetails->language_code !== $currentLanguage; |
| 59 | } |
| 60 | |
| 61 | private function mergeTranslationIntoDefault( $products, $translatedProductIndex, $translatedProduct, $productsDetails ) { |
| 62 | $originalProductId = apply_filters( 'wpml_object_id', $productsDetails->element_id, 'product' ); |
| 63 | if ( $originalProductId ) { |
| 64 | foreach ( $products as $index => $product ) { |
| 65 | if ( $product['product_id'] === $originalProductId ) { |
| 66 | $products = $this->removeTranslatedProduct( $products, $translatedProductIndex ); |
| 67 | $products = $this->updateOriginalProductFields( $products, $index, $translatedProduct ); |
| 68 | } |
| 69 | } |
| 70 | } |
| 71 | return $products; |
| 72 | } |
| 73 | |
| 74 | private function removeTranslatedProduct( $products, $key ) { |
| 75 | return array_diff_key( $products, [ $key => '' ] ); |
| 76 | } |
| 77 | |
| 78 | private function updateOriginalProductFields( $products, $index, $translatedProduct ) { |
| 79 | $products = $this->sumValues( 'items_sold', $products, $index, $translatedProduct ); |
| 80 | $products = $this->sumValues( 'net_revenue', $products, $index, $translatedProduct ); |
| 81 | $products = $this->sumValues( 'orders_count', $products, $index, $translatedProduct ); |
| 82 | return $products; |
| 83 | } |
| 84 | |
| 85 | private function sumValues( $field, $products, $index, $translatedProduct ) { |
| 86 | if ( isset( $translatedProduct[ $field ], $products[ $index ][ $field ] ) ) { |
| 87 | $products[ $index ][ $field ] += $translatedProduct[ $field ]; |
| 88 | } |
| 89 | return $products; |
| 90 | } |
| 91 | |
| 92 | private function getProductLanguageDetails( $product ) { |
| 93 | $args = [ |
| 94 | 'element_id' => $product['product_id'], |
| 95 | 'element_type' => 'product' |
| 96 | ]; |
| 97 | return apply_filters( 'wpml_element_language_details', null, $args ); |
| 98 | } |
| 99 | |
| 100 | public function translateProductTitles( $results ) { |
| 101 | $results->data = wpml_collect( $results->data ) |
| 102 | ->map( function( $row ) { |
| 103 | if ( $row['extended_info']['name'] ) { |
| 104 | $row['product_id'] = apply_filters( 'wpml_object_id', $row['product_id'], get_post_type( $row['product_id'] ), true ); |
| 105 | $product = wc_get_product( $row['product_id'] ); |
| 106 | if ( $product ) { |
| 107 | $row['extended_info']['name'] = $product->get_title(); |
| 108 | } |
| 109 | if ( isset( $row['extended_info']['category_ids'] ) ) { |
| 110 | $row['extended_info']['category_ids'] = wpml_collect( $row['extended_info']['category_ids'] ) |
| 111 | ->map( function( $id ) { |
| 112 | return apply_filters( 'wpml_object_id', $id, 'product_cat', true ); |
| 113 | } )->toArray(); |
| 114 | } |
| 115 | } |
| 116 | return $row; |
| 117 | } )->toArray(); |
| 118 | |
| 119 | return $results; |
| 120 | } |
| 121 | |
| 122 | } |