From c4ddaef3bce9414d8c23a9f19143d62060d8d486 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9stor=20Soriano?= Date: Thu, 11 Jul 2024 09:14:24 +0200 Subject: [PATCH] Optimize the method that gets the downloads count for a given download (#49008) The old code was retrieving all the existing download entries from the database and then counting them locally. Now a SQL COUNT query is used instead. --------- Co-authored-by: Naman Malhotra --- plugins/woocommerce/changelog/pr-49008 | 4 ++ .../includes/class-wc-customer-download.php | 9 +---- ...ss-wc-customer-download-log-data-store.php | 38 ++++++++++++++++--- 3 files changed, 39 insertions(+), 12 deletions(-) create mode 100644 plugins/woocommerce/changelog/pr-49008 diff --git a/plugins/woocommerce/changelog/pr-49008 b/plugins/woocommerce/changelog/pr-49008 new file mode 100644 index 00000000000..a93421e55fe --- /dev/null +++ b/plugins/woocommerce/changelog/pr-49008 @@ -0,0 +1,4 @@ +Significance: patch +Type: update + +Optimize the method that gets the downloads count for a given download diff --git a/plugins/woocommerce/includes/class-wc-customer-download.php b/plugins/woocommerce/includes/class-wc-customer-download.php index 43d5a2101af..7d879b7801b 100644 --- a/plugins/woocommerce/includes/class-wc-customer-download.php +++ b/plugins/woocommerce/includes/class-wc-customer-download.php @@ -171,13 +171,8 @@ class WC_Customer_Download extends WC_Data implements ArrayAccess { */ public function get_download_count( $context = 'view' ) { // Check for count of download logs. - $data_store = WC_Data_Store::load( 'customer-download-log' ); - $download_log_ids = $data_store->get_download_logs_for_permission( $this->get_id() ); - - $download_log_count = 0; - if ( ! empty( $download_log_ids ) ) { - $download_log_count = count( $download_log_ids ); - } + $data_store = WC_Data_Store::load( 'customer-download-log' ); + $download_log_count = $data_store->get_download_logs_count_for_permission( $this->get_id() ); // Check download count in prop. $download_count_prop = $this->get_prop( 'download_count', $context ); diff --git a/plugins/woocommerce/includes/data-stores/class-wc-customer-download-log-data-store.php b/plugins/woocommerce/includes/data-stores/class-wc-customer-download-log-data-store.php index 1001e7001ab..2f56df7666e 100644 --- a/plugins/woocommerce/includes/data-stores/class-wc-customer-download-log-data-store.php +++ b/plugins/woocommerce/includes/data-stores/class-wc-customer-download-log-data-store.php @@ -149,10 +149,10 @@ class WC_Customer_Download_Log_Data_Store implements WC_Customer_Download_Log_Da } /** - * Get array of download log ids by specified args. + * Get array of download logs, or the count of existing logs, by specified args. * - * @param array $args Arguments to define download logs to retrieve. - * @return array + * @param array $args Arguments to define download logs to retrieve. If $args['return'] is 'count' then the count of existing logs will be returned. + * @return array|int */ public function get_download_logs( $args = array() ) { global $wpdb; @@ -171,9 +171,11 @@ class WC_Customer_Download_Log_Data_Store implements WC_Customer_Download_Log_Da ) ); + $is_count = 'count' === $args['return']; + $query = array(); $table = $wpdb->prefix . self::get_table_name(); - $query[] = "SELECT * FROM {$table} WHERE 1=1"; + $query[] = 'SELECT ' . ( $is_count ? 'COUNT(1)' : '*' ) . " FROM {$table} WHERE 1=1"; if ( $args['permission_id'] ) { $query[] = $wpdb->prepare( 'AND permission_id = %d', $args['permission_id'] ); @@ -197,7 +199,13 @@ class WC_Customer_Download_Log_Data_Store implements WC_Customer_Download_Log_Da $query[] = $wpdb->prepare( 'LIMIT %d, %d', absint( $args['limit'] ) * absint( $args['page'] - 1 ), absint( $args['limit'] ) ); } - $raw_download_logs = $wpdb->get_results( implode( ' ', $query ) ); // WPCS: unprepared SQL ok. + // phpcs:disable WordPress.DB.PreparedSQL.NotPrepared + if ( $is_count ) { + return absint( $wpdb->get_var( implode( ' ', $query ) ) ); + } + + $raw_download_logs = $wpdb->get_results( implode( ' ', $query ) ); + // phpcs:enable WordPress.DB.PreparedSQL.NotPrepared switch ( $args['return'] ) { case 'ids': @@ -226,6 +234,26 @@ class WC_Customer_Download_Log_Data_Store implements WC_Customer_Download_Log_Da ); } + /** + * Get the count of download logs for a given download permission. + * + * @param int $permission_id Permission to get logs count for. + * @return int + */ + public function get_download_logs_count_for_permission( $permission_id ) { + // If no permission_id is passed, return an empty array. + if ( empty( $permission_id ) ) { + return 0; + } + + return $this->get_download_logs( + array( + 'permission_id' => $permission_id, + 'return' => 'count', + ) + ); + } + /** * Method to delete download logs for a given permission ID. *