You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
298 lines
12 KiB
298 lines
12 KiB
<?php
|
|
|
|
use WCML\Utilities\DB;
|
|
|
|
/**
|
|
* This class is responsible for handling legacy WC reports. Legacy WC reports are being phased out in favor of newer WC analytics.
|
|
* Legacy WC reports are not HPOS-compatible: https://github.com/woocommerce/woocommerce/issues/40671
|
|
*
|
|
* @deprecated This class is deprecated and should no longer be used because it's incompatible with HPOS.
|
|
* @link https://onthegosystems.myjetbrains.com/youtrack/issue/wcml-4489
|
|
*/
|
|
class WCML_Reports{
|
|
|
|
public $tab;
|
|
public $report;
|
|
|
|
public function __construct(){
|
|
|
|
add_action('init', array($this, 'init'));
|
|
|
|
}
|
|
|
|
public function init(){
|
|
|
|
if( isset($_GET['page']) && $_GET['page']==='wc-reports' ) {
|
|
|
|
$this->tab = isset( $_GET['tab'] ) ? $_GET['tab'] : 'orders';
|
|
$this->report = isset( $_GET['report'] ) ? $_GET['report'] : '';
|
|
|
|
add_filter( 'woocommerce_reports_get_order_report_query', array( $this, 'filter_reports_query' ), 0 );
|
|
|
|
if ( $this->tab==='orders' && $this->report==='sales_by_product' ) {
|
|
add_filter( 'woocommerce_reports_get_order_report_data', array( $this, 'combine_report_by_languages' ) );
|
|
}
|
|
if ( $this->tab==='orders' && $this->report==='sales_by_category' ) {
|
|
add_filter( 'woocommerce_report_sales_by_category_get_products_in_category', array(
|
|
$this,
|
|
'use_categories_in_all_languages'
|
|
), 10, 2 );
|
|
}
|
|
}
|
|
|
|
add_filter( 'woocommerce_report_most_stocked_query_from', array( $this, 'filter_reports_stock_query' ) );
|
|
add_filter( 'woocommerce_report_out_of_stock_query_from', array( $this, 'filter_reports_stock_query' ) );
|
|
add_filter( 'woocommerce_report_low_in_stock_query_from', array( $this, 'filter_reports_stock_query' ) );
|
|
|
|
}
|
|
|
|
public function filter_reports_query($query){
|
|
global $wpdb, $sitepress;
|
|
|
|
$current_language = $sitepress->get_current_language();
|
|
$active_languages = $sitepress->get_active_languages();
|
|
|
|
if($this->tab==='orders' && $this->report==='sales_by_product'){
|
|
|
|
$sparkline_query = strpos( $query[ 'select'], 'sparkline_value' ) !== false;
|
|
|
|
if(
|
|
|
|
$sparkline_query ||
|
|
isset( $query[ 'order_by' ] ) && ( $query[ 'order_by' ]==='ORDER BY order_item_qty DESC' || $query[ 'order_by' ]==='ORDER BY order_item_total DESC' )
|
|
|
|
){
|
|
|
|
|
|
$query[ 'select' ] .= " , order_language.meta_value AS order_language , translations.trid";
|
|
|
|
$query[ 'join' ] .= " LEFT JOIN {$wpdb->postmeta} order_language ON posts.ID = order_language.post_id";
|
|
$query[ 'where' ] .= " AND order_language.meta_key = 'wpml_language' ";
|
|
|
|
$query[ 'join' ] .= " LEFT JOIN {$wpdb->prefix}icl_translations translations ON translations.element_id = order_item_meta__product_id.meta_value";
|
|
$query[ 'where' ] .= " AND translations.element_type IN ('post_product','post_product_variation') ";
|
|
|
|
if(!$sparkline_query){
|
|
$limit = (int) trim( str_replace( 'LIMIT ', '', $query['limit'] ) );
|
|
$query['limit'] = sprintf( ' LIMIT %d ', $limit * count( $active_languages ) );
|
|
}
|
|
|
|
|
|
if($sparkline_query){
|
|
preg_match("#order_item_meta__product_id\.meta_value = '([0-9]+)'#", $query[ 'where' ], $matches);
|
|
$product_id = $matches[1];
|
|
$post_type = get_post_type($product_id);
|
|
$trid = $sitepress->get_element_trid($product_id, 'post_'.$post_type);
|
|
$translations = $sitepress->get_element_translations($trid, 'post_'.$post_type, true);
|
|
$product_ids = array();
|
|
foreach($translations as $translation){
|
|
$product_ids[] = $translation->element_id;
|
|
}
|
|
|
|
$query[ 'where' ] = str_replace( "order_item_meta__product_id.meta_value = '{$product_id}'", "order_item_meta__product_id.meta_value IN (" . DB::prepareIn( array_filter( $product_ids ), '%d' ) . ")", $query[ 'where' ] );
|
|
}
|
|
|
|
$query[ 'select' ] .= ', translations.language_code AS language_code_' . esc_sql( str_replace('-', '_', $current_language) ); // user for per-language caching.
|
|
|
|
}elseif(
|
|
$query[ 'select' ]==='SELECT SUM( order_item_meta__line_total.meta_value) as order_item_amount' || //sales for the selected items
|
|
$query[ 'select' ]==='SELECT SUM( order_item_meta__qty.meta_value) as order_item_count' || //purchases for the selected items
|
|
$query[ 'select' ]==='SELECT SUM( order_item_meta__qty.meta_value) as order_item_count, posts.post_date as post_date, order_item_meta__product_id.meta_value as product_id' || //Get orders and dates in range - main chart: order_item_counts
|
|
$query[ 'select' ]==='SELECT SUM( order_item_meta__line_total.meta_value) as order_item_amount, posts.post_date as post_date, order_item_meta__product_id.meta_value as product_id' //Get orders and dates in range - main chart: order_item_amounts
|
|
|
|
){
|
|
preg_match("#order_item_meta__product_id_array\.meta_value IN \(([^\)]+)\)#", $query[ 'where' ], $matches);
|
|
$product_ids = array();
|
|
$exp = array_map('trim', explode(',', $matches[1]));
|
|
foreach($exp as $e){
|
|
$product_ids[] = trim($e, "'");
|
|
}
|
|
$all_product_ids = array();
|
|
foreach($product_ids as $product_id){
|
|
$post_type = get_post_type($product_id);
|
|
$trid = $sitepress->get_element_trid($product_id, 'post_'.$post_type);
|
|
$translations = $sitepress->get_element_translations($trid, 'post_'.$post_type, true);
|
|
foreach($translations as $translation){
|
|
$all_product_ids[] = $translation->element_id;
|
|
}
|
|
}
|
|
|
|
$query[ 'where' ] = preg_replace( "#order_item_meta__product_id_array\.meta_value IN \(([^\)]+)\)#", "order_item_meta__product_id_array.meta_value IN (" . DB::prepareIn( array_filter( $all_product_ids ), '%d' ) . ')', $query[ 'where' ] );
|
|
}
|
|
|
|
}
|
|
|
|
return $query;
|
|
}
|
|
|
|
|
|
public function combine_report_by_languages($results){
|
|
global $sitepress, $wpdb;
|
|
|
|
if(is_array($results) && isset($results['0']->order_item_qty)){
|
|
$mode = 'top_sellers';
|
|
}elseif(is_array($results) && isset($results['0']->order_item_total)){
|
|
$mode = 'top_earners';
|
|
}elseif(isset($results['0']->sparkline_value)){
|
|
$mode = 'top_sellers_spark';
|
|
}else{
|
|
return $results;
|
|
}
|
|
|
|
if(!isset($results['0']->trid)) return $results;
|
|
|
|
$current_language = $sitepress->get_current_language();
|
|
|
|
$combined_results = array();
|
|
|
|
foreach($results as $k => $row){
|
|
|
|
switch($mode){
|
|
case 'top_sellers':
|
|
case 'top_earners':
|
|
$key = $row->trid;
|
|
break;
|
|
case 'top_sellers_spark':
|
|
$key = $row->trid . '#' . substr($row->post_date, 0, 10);
|
|
break;
|
|
default:
|
|
$key = null;
|
|
}
|
|
|
|
if($key && $row->order_language===$current_language){
|
|
$combined_results[$key] = $row;
|
|
}
|
|
}
|
|
|
|
foreach($results as $k => $row){
|
|
|
|
if($row->order_language != $current_language){
|
|
|
|
switch($mode){
|
|
case 'top_sellers':
|
|
case 'top_earners':
|
|
$key = $row->trid;
|
|
break;
|
|
case 'top_sellers_spark':
|
|
$key = $row->trid . '#' . substr($row->post_date, 0, 10);
|
|
break;
|
|
default:
|
|
$key = null;
|
|
}
|
|
|
|
if($key && isset($combined_results[$key])){
|
|
|
|
switch($mode){
|
|
case 'top_sellers':
|
|
$combined_results[$key]->order_item_qty += $row->order_item_qty;
|
|
break;
|
|
case 'top_earners':
|
|
$combined_results[$key]->order_item_total += $row->order_item_total;
|
|
break;
|
|
case 'top_sellers_spark':
|
|
$combined_results[$key]->sparkline_value += $row->sparkline_value;
|
|
break;
|
|
|
|
}
|
|
|
|
}else{
|
|
|
|
$default_product_id = apply_filters( 'translate_object_id',$row->product_id, 'product', false, $current_language);
|
|
|
|
if($default_product_id){
|
|
$combined_results[$key] = new stdClass();
|
|
$combined_results[$key]->product_id = $default_product_id;
|
|
|
|
switch($mode){
|
|
case 'top_sellers':
|
|
$combined_results[$key]->order_item_qty = $row->order_item_qty;
|
|
break;
|
|
case 'top_earners':
|
|
$combined_results[$key]->order_item_total = $row->order_item_total;
|
|
break;
|
|
case 'top_sellers_spark':
|
|
$combined_results[$key]->sparkline_value = $row->sparkline_value;
|
|
$combined_results[$key]->post_date = $row->post_date;
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
switch($mode){
|
|
case 'top_sellers':
|
|
usort($combined_results, array(__CLASS__, 'order_by_quantity'));
|
|
array_slice($combined_results, 0, 12);
|
|
break;
|
|
case 'top_earners':
|
|
usort($combined_results, array(__CLASS__, 'order_by_total'));
|
|
array_slice($combined_results, 0, 12);
|
|
break;
|
|
case 'top_sellers_spark':
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
foreach($combined_results as $k => $row){
|
|
unset($combined_results[$k]->trid, $combined_results[$k]->order_language);
|
|
}
|
|
|
|
|
|
return $combined_results;
|
|
}
|
|
|
|
private static function order_by_quantity( $a, $b ) {
|
|
return $b->order_item_qty - $a->order_item_qty;
|
|
}
|
|
|
|
private static function order_by_total( $a, $b ) {
|
|
return $b->order_item_total - $a->order_item_total;
|
|
}
|
|
|
|
public function filter_reports_stock_query( $query_from ){
|
|
global $wpdb, $sitepress;
|
|
|
|
$current_language = $sitepress->get_current_language();
|
|
|
|
if( $current_language !== 'all' ){
|
|
$query_from = preg_replace("/WHERE/",
|
|
"LEFT JOIN {$wpdb->prefix}icl_translations AS t
|
|
ON posts.ID = t.element_id
|
|
WHERE", $query_from);
|
|
|
|
$query_from .= " AND t.element_type IN ( 'post_product', 'post_product_variation' ) AND t.language_code = '".$current_language."'";
|
|
}
|
|
|
|
|
|
return $query_from;
|
|
}
|
|
|
|
public function use_categories_in_all_languages( $product_ids, $category_id ) {
|
|
global $woocommerce_wpml, $sitepress;
|
|
|
|
$category_term = $woocommerce_wpml->terms->wcml_get_term_by_id( $category_id, 'product_cat' );
|
|
|
|
if ( ! is_wp_error( $category_term ) ) {
|
|
$trid = $sitepress->get_element_trid( $category_term->term_taxonomy_id, 'tax_product_cat' );
|
|
$translations = $sitepress->get_element_translations( $trid, 'tax_product_cat', true );
|
|
|
|
foreach ( $translations as $translation ) {
|
|
if ( $translation->term_id != $category_id ) {
|
|
$term_ids = get_term_children( $translation->term_id, 'product_cat' );
|
|
$term_ids[] = $translation->term_id;
|
|
$product_ids = array_merge( array_unique( $product_ids ), get_objects_in_term( $term_ids, 'product_cat' ) );
|
|
}
|
|
}
|
|
}
|
|
|
|
return $product_ids;
|
|
}
|
|
|
|
}
|
|
|