Skip to content

Commit

Permalink
Make variations and coupons endpoints return zero-value items (woocom…
Browse files Browse the repository at this point in the history
…merce#1765)

* Make categories endpoint return zero-value items

* Rename PHP variable to make it more specific

* Remove uneeded lines

* Make variations and coupons endpoints return zero-value items

* Remove second parameter from get_ids_table
  • Loading branch information
Aljullu authored Mar 12, 2019
1 parent e5824f4 commit 47f6c12
Show file tree
Hide file tree
Showing 9 changed files with 282 additions and 83 deletions.
3 changes: 1 addition & 2 deletions client/analytics/report/products/table-variations.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ export default class VariationsReportTable extends Component {
label: __( 'SKU', 'wc-admin' ),
key: 'sku',
hiddenByDefault: true,
isSortable: true,
},
{
label: __( 'Items Sold', 'wc-admin' ),
Expand Down Expand Up @@ -106,7 +105,7 @@ export default class VariationsReportTable extends Component {
value: sku,
},
{
display: items_sold,
display: numberFormat( items_sold ),
value: items_sold,
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ protected function get_sql_query_params( $query_args ) {

// Limit is left out here so that the grouping in code by PHP can be applied correctly.
// This also needs to be put after the term_taxonomy JOIN so that we can match the correct term name.
$sql_query_params = $this->get_order_by_params( $query_args, $sql_query_params, 'outer_from_clause', 'default_results.id' );
$sql_query_params = $this->get_order_by_params( $query_args, $sql_query_params, 'outer_from_clause', 'default_results.category_id' );
} else {
$sql_query_params = $this->get_order_by_params( $query_args, $sql_query_params, 'from_clause', "{$wpdb->prefix}term_taxonomy.term_id" );
}
Expand Down Expand Up @@ -258,13 +258,13 @@ public function get_data( $query_args ) {

if ( count( $included_categories ) > 0 ) {
$fields = $this->get_fields( $query_args );
$join_selections = $this->format_join_selections( array_merge( array( 'category_id' ), $fields ), 'category_id' );
$ids_table = $this->get_ids_table( $included_categories );
$join_selections = $this->format_join_selections( array_merge( array( 'category_id' ), $fields ), array( 'category_id' ) );
$ids_table = $this->get_ids_table( $included_categories, 'category_id' );

$prefix = "SELECT {$join_selections} FROM (";
$suffix = ") AS {$table_name}";
$right_join = "RIGHT JOIN ( {$ids_table} ) AS default_results
ON default_results.id = {$table_name}.category_id";
ON default_results.category_id = {$table_name}.category_id";
} else {
$prefix = '';
$suffix = '';
Expand Down
110 changes: 74 additions & 36 deletions includes/data-stores/class-wc-admin-reports-coupons-data-store.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,19 +58,28 @@ public static function init() {
add_action( 'woocommerce_reports_delete_order_stats', array( __CLASS__, 'sync_on_order_delete' ), 5 );
}

/**
* Returns an array of ids of included coupons, based on query arguments from the user.
*
* @param array $query_args Parameters supplied by the user.
* @return array
*/
protected function get_included_coupons_array( $query_args ) {
if ( isset( $query_args['coupons'] ) && is_array( $query_args['coupons'] ) && count( $query_args['coupons'] ) > 0 ) {
return $query_args['coupons'];
}
return array();
}

/**
* Returns comma separated ids of included coupons, based on query arguments from the user.
*
* @param array $query_args Parameters supplied by the user.
* @return string
*/
protected function get_included_coupons( $query_args ) {
$included_coupons_str = '';

if ( isset( $query_args['coupons'] ) && is_array( $query_args['coupons'] ) && count( $query_args['coupons'] ) > 0 ) {
$included_coupons_str = implode( ',', $query_args['coupons'] );
}
return $included_coupons_str;
$included_coupons = $this->get_included_coupons_array( $query_args );
return implode( ',', $included_coupons );
}

/**
Expand All @@ -85,11 +94,14 @@ protected function get_sql_query_params( $query_args ) {

$sql_query_params = $this->get_time_period_sql_params( $query_args, $order_coupon_lookup_table );
$sql_query_params = array_merge( $sql_query_params, $this->get_limit_sql_params( $query_args ) );
$sql_query_params = array_merge( $sql_query_params, $this->get_order_by_sql_params( $query_args ) );

$included_coupons = $this->get_included_coupons( $query_args );
if ( $included_coupons ) {
$sql_query_params['where_clause'] .= " AND {$order_coupon_lookup_table}.coupon_id IN ({$included_coupons})";

$sql_query_params = array_merge( $sql_query_params, $this->get_order_by_params( $query_args, 'outer_from_clause', 'default_results.coupon_id' ) );
} else {
$sql_query_params = array_merge( $sql_query_params, $this->get_order_by_params( $query_args, 'from_clause', "{$order_coupon_lookup_table}.coupon_id" ) );
}

$order_status_filter = $this->get_status_subquery( $query_args );
Expand All @@ -101,25 +113,27 @@ protected function get_sql_query_params( $query_args ) {
return $sql_query_params;
}


/**
* Fills ORDER BY clause of SQL request based on user supplied parameters.
*
* @param array $query_args Parameters supplied by the user.
* @param array $query_args Parameters supplied by the user.
* @param string $from_arg Name of the FROM sql param.
* @param string $id_cell ID cell identifier, like `table_name.id_column_name`.
* @return array
*/
protected function get_order_by_sql_params( $query_args ) {
protected function get_order_by_params( $query_args, $from_arg, $id_cell ) {
global $wpdb;
$lookup_table = $wpdb->prefix . self::TABLE_NAME;
$sql_query = array();
$sql_query['from_clause'] = '';
$sql_query['order_by_clause'] = '';
$lookup_table = $wpdb->prefix . self::TABLE_NAME;
$sql_query = array();
$sql_query['from_clause'] = '';
$sql_query['outer_from_clause'] = '';
$sql_query['order_by_clause'] = '';
if ( isset( $query_args['orderby'] ) ) {
$sql_query['order_by_clause'] = $this->normalize_order_by( $query_args['orderby'] );
}

if ( false !== strpos( $sql_query['order_by_clause'], '_coupons' ) ) {
$sql_query['from_clause'] .= " JOIN {$wpdb->prefix}posts AS _coupons ON {$lookup_table}.coupon_id = _coupons.ID";
$sql_query[ $from_arg ] .= " JOIN {$wpdb->prefix}posts AS _coupons ON {$id_cell} = _coupons.ID";
}

if ( isset( $query_args['order'] ) ) {
Expand Down Expand Up @@ -236,30 +250,51 @@ public function get_data( $query_args ) {

$selections = $this->selected_columns( $query_args );
$sql_query_params = $this->get_sql_query_params( $query_args );
$included_coupons = $this->get_included_coupons_array( $query_args );

if ( count( $included_coupons ) > 0 ) {
$total_results = count( $included_coupons );
$total_pages = (int) ceil( $total_results / $sql_query_params['per_page'] );

$fields = $this->get_fields( $query_args );
$join_selections = $this->format_join_selections( $fields, array( 'coupon_id' ) );
$ids_table = $this->get_ids_table( $included_coupons, 'coupon_id' );

$prefix = "SELECT {$join_selections} FROM (";
$suffix = ") AS {$table_name}";
$right_join = "RIGHT JOIN ( {$ids_table} ) AS default_results
ON default_results.coupon_id = {$table_name}.coupon_id";
} else {
$db_records_count = (int) $wpdb->get_var(
"SELECT COUNT(*) FROM (
SELECT
coupon_id
FROM
{$table_name}
{$sql_query_params['from_clause']}
WHERE
1=1
{$sql_query_params['where_time_clause']}
{$sql_query_params['where_clause']}
GROUP BY
coupon_id
) AS tt"
); // WPCS: cache ok, DB call ok, unprepared SQL ok.

$total_results = $db_records_count;
$total_pages = (int) ceil( $db_records_count / $sql_query_params['per_page'] );
if ( $query_args['page'] < 1 || $query_args['page'] > $total_pages ) {
return $data;
}

$db_records_count = (int) $wpdb->get_var(
"SELECT COUNT(*) FROM (
SELECT
coupon_id
FROM
{$table_name}
{$sql_query_params['from_clause']}
WHERE
1=1
{$sql_query_params['where_time_clause']}
{$sql_query_params['where_clause']}
GROUP BY
coupon_id
) AS tt"
); // WPCS: cache ok, DB call ok, unprepared SQL ok.

$total_pages = (int) ceil( $db_records_count / $sql_query_params['per_page'] );
if ( $query_args['page'] < 1 || $query_args['page'] > $total_pages ) {
return $data;
$prefix = '';
$suffix = '';
$right_join = '';
}

$coupon_data = $wpdb->get_results(
"SELECT
"${prefix}
SELECT
{$selections}
FROM
{$table_name}
Expand All @@ -270,6 +305,9 @@ public function get_data( $query_args ) {
{$sql_query_params['where_clause']}
GROUP BY
coupon_id
{$suffix}
{$right_join}
{$sql_query_params['outer_from_clause']}
ORDER BY
{$sql_query_params['order_by_clause']}
{$sql_query_params['limit']}
Expand All @@ -286,7 +324,7 @@ public function get_data( $query_args ) {
$coupon_data = array_map( array( $this, 'cast_numbers' ), $coupon_data );
$data = (object) array(
'data' => $coupon_data,
'total' => $db_records_count,
'total' => $total_results,
'pages' => $total_pages,
'page_no' => (int) $query_args['page'],
);
Expand Down
26 changes: 17 additions & 9 deletions includes/data-stores/class-wc-admin-reports-data-store.php
Original file line number Diff line number Diff line change
Expand Up @@ -609,13 +609,19 @@ protected function get_limit_sql_params( $query_args ) {
/**
* Generates a virtual table given a list of IDs.
*
* @param array $ids Array of IDs.
* @param array $ids Array of IDs.
* @param array $id_field Name of the ID field.
* @param array $other_values Other values that must be contained in the virtual table.
* @return array
*/
protected function get_ids_table( $ids ) {
protected function get_ids_table( $ids, $id_field, $other_values = array() ) {
$selects = array();
foreach ( $ids as $id ) {
array_push( $selects, "SELECT {$id} AS id" );
$new_select = "SELECT {$id} AS {$id_field}";
foreach ( $other_values as $key => $value ) {
$new_select .= ", {$value} AS {$key}";
}
array_push( $selects, $new_select );
}
return join( ' UNION ', $selects );
}
Expand All @@ -636,15 +642,17 @@ protected function get_fields( $query_args ) {
/**
* Returns a comma separated list of the field names prepared to be used for a selection after a join with `default_results`.
*
* @param array $fields Array of fields name.
* @param string $id_field Name of the column used as an identifier.
* @param array $outer_selections Array of fields that are not selected in the inner query.
* @param array $fields Array of fields name.
* @param array $default_results_fields Fields to load from `default_results` table.
* @param array $outer_selections Array of fields that are not selected in the inner query.
* @return string
*/
protected function format_join_selections( $fields, $id_field, $outer_selections = array() ) {
protected function format_join_selections( $fields, $default_results_fields, $outer_selections = array() ) {
foreach ( $fields as $i => $field ) {
if ( $field === $id_field ) {
$fields[ $i ] = "default_results.id AS {$field}";
foreach ( $default_results_fields as $default_results_field ) {
if ( $field === $default_results_field ) {
$fields[ $i ] = "default_results.{$field} AS {$field}";
}
}
if ( in_array( $field, $outer_selections, true ) && array_key_exists( $field, $this->report_columns ) ) {
$fields[ $i ] = $this->report_columns[ $field ];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ protected function get_sql_query_params( $query_args ) {

$included_products = $this->get_included_products( $query_args );
if ( $included_products ) {
$sql_query_params = array_merge( $sql_query_params, $this->get_from_sql_params( $query_args, 'outer_from_clause', 'default_results.id' ) );
$sql_query_params = array_merge( $sql_query_params, $this->get_from_sql_params( $query_args, 'outer_from_clause', 'default_results.product_id' ) );
$sql_query_params['where_clause'] .= " AND {$order_product_lookup_table}.product_id IN ({$included_products})";
} else {
$sql_query_params = array_merge( $sql_query_params, $this->get_from_sql_params( $query_args, 'from_clause', "{$order_product_lookup_table}.product_id" ) );
Expand Down Expand Up @@ -287,12 +287,12 @@ public function get_data( $query_args ) {
}

$fields = $this->get_fields( $query_args );
$join_selections = $this->format_join_selections( $fields, 'product_id' );
$join_selections = $this->format_join_selections( $fields, array( 'product_id' ) );
$ids_table = $this->get_ids_table( $included_products, 'product_id' );
$prefix = "SELECT {$join_selections} FROM (";
$suffix = ") AS {$table_name}";
$right_join = "RIGHT JOIN ( {$ids_table} ) AS default_results
ON default_results.id = {$table_name}.product_id";
ON default_results.product_id = {$table_name}.product_id";
} else {
$db_records_count = (int) $wpdb->get_var(
"SELECT COUNT(*) FROM (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ protected function get_from_sql_params( $query_args, $order_status_filter ) {
}

if ( isset( $query_args['taxes'] ) && ! empty( $query_args['taxes'] ) ) {
$sql_query['outer_from_clause'] .= " JOIN {$wpdb->prefix}woocommerce_tax_rates ON default_results.id = {$wpdb->prefix}woocommerce_tax_rates.tax_rate_id";
$sql_query['outer_from_clause'] .= " JOIN {$wpdb->prefix}woocommerce_tax_rates ON default_results.tax_rate_id = {$wpdb->prefix}woocommerce_tax_rates.tax_rate_id";
} else {
$sql_query['from_clause'] .= " JOIN {$wpdb->prefix}woocommerce_tax_rates ON {$table_name}.tax_rate_id = {$wpdb->prefix}woocommerce_tax_rates.tax_rate_id";
}
Expand Down Expand Up @@ -198,12 +198,12 @@ public function get_data( $query_args ) {

$selections = $this->selected_columns( array( 'fields' => $inner_selections ) );
$fields = $this->get_fields( $query_args );
$join_selections = $this->format_join_selections( $fields, 'tax_rate_id', $outer_selections );
$join_selections = $this->format_join_selections( $fields, array( 'tax_rate_id' ), $outer_selections );
$ids_table = $this->get_ids_table( $query_args['taxes'], 'tax_rate_id' );
$prefix = "SELECT {$join_selections} FROM (";
$suffix = ") AS {$table_name}";
$right_join = "RIGHT JOIN ( {$ids_table} ) AS default_results
ON default_results.id = {$table_name}.tax_rate_id";
ON default_results.tax_rate_id = {$table_name}.tax_rate_id";
} else {
$db_records_count = (int) $wpdb->get_var(
"SELECT COUNT(*) FROM (
Expand Down
Loading

0 comments on commit 47f6c12

Please sign in to comment.