get_row( $wpdb->prepare( "SELECT COUNT(*) as total_orders, SUM(total_amount) as total_sales, SUM(tax_amount) as total_tax FROM {$wpdb->prefix}storeengine_orders WHERE date_created_gmt BETWEEN %s AND %s AND type = %s AND status IN {$this->get_paid_statuses()}", $start, $end, 'order' ) ); // phpcs:enable PluginCheck.Security.DirectDB.UnescapedDBParameter, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared } public function get_total_refunds( string $start, string $end ) { global $wpdb; // phpcs:disable PluginCheck.Security.DirectDB.UnescapedDBParameter, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared return $wpdb->get_row( $wpdb->prepare( "SELECT ABS(SUM(o.total_amount)) as total_refunds FROM {$wpdb->prefix}storeengine_orders o JOIN {$wpdb->prefix}storeengine_orders co ON o.parent_order_id = co.id WHERE co.date_created_gmt BETWEEN %s AND %s AND o.type = %s AND co.status in {$this->get_paid_statuses()}", $start, $end, 'refund_order' ) ); // phpcs:enable PluginCheck.Security.DirectDB.UnescapedDBParameter, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared } public function get_product_sold( string $start, string $end ) { global $wpdb; // phpcs:disable PluginCheck.Security.DirectDB.UnescapedDBParameter, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared return $wpdb->get_row( $wpdb->prepare( "SELECT SUM(p.product_qty) as total_products_sold FROM {$wpdb->prefix}storeengine_orders o JOIN {$wpdb->prefix}storeengine_order_product_lookup p ON p.order_id = o.id WHERE o.date_created_gmt BETWEEN %s AND %s AND o.type = %s AND o.status IN {$this->get_paid_statuses()}", $start, $end, 'order' ) ); // phpcs:enable PluginCheck.Security.DirectDB.UnescapedDBParameter, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared } public function get_top_products(): array { global $wpdb; // phpcs:disable PluginCheck.Security.DirectDB.UnescapedDBParameter, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared $products = $wpdb->get_results( "SELECT op.product_id, SUM(op.product_qty) AS total_sales, p.post_title AS product_name, pm1.meta_value AS thumbnail, pm2.meta_value AS gallery, SUM(op.product_net_revenue) AS total_net_revenue FROM {$wpdb->prefix}storeengine_order_product_lookup op INNER JOIN {$wpdb->prefix}storeengine_orders o ON o.id = op.order_id AND o.status IN {$this->get_paid_statuses()} INNER JOIN $wpdb->posts p ON p.ID = op.product_id LEFT JOIN $wpdb->postmeta pm1 ON pm1.post_id = op.product_id AND pm1.meta_key = '_thumbnail_id' LEFT JOIN $wpdb->postmeta pm2 ON pm2.post_id = op.product_id AND pm2.meta_key = '_storeengine_product_gallery_ids' GROUP BY op.product_id, p.post_title ORDER BY total_sales DESC LIMIT 5" ); // phpcs:enable PluginCheck.Security.DirectDB.UnescapedDBParameter, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared $top_products = []; foreach ( $products as $product ) { if ( ! $product->thumbnail && $product->gallery ) { $gallery = maybe_unserialize( $product->gallery ); if ( ! empty( $gallery ) && is_array( $gallery ) ) { $product->thumbnail = $gallery[0]; } } $top_products[] = [ 'product_id' => (int) $product->product_id, 'product_name' => $product->product_name, 'product_image' => $product->thumbnail ? wp_get_attachment_image_url( $product->thumbnail ) : null, 'total_sales' => (int) $product->total_sales, 'total_net_revenue' => (float) $product->total_net_revenue, ]; } return $top_products; } /** * @return string */ private function get_paid_statuses(): string { global $wpdb; $paid_statuses = Helper::get_order_paid_statuses(); $placeholders = array_fill(0, count($paid_statuses), '%s'); $placeholders = '(' . implode(',', $placeholders) . ')'; // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQL.NotPrepared -- Sanitizing dynamic range of value. return $wpdb->prepare($placeholders, $paid_statuses); } }