diff --git a/mailpoet/lib/Automation/Integrations/WooCommerce/Fields/CustomerOrderFieldsFactory.php b/mailpoet/lib/Automation/Integrations/WooCommerce/Fields/CustomerOrderFieldsFactory.php index 7e14212ba6..ba3521735d 100644 --- a/mailpoet/lib/Automation/Integrations/WooCommerce/Fields/CustomerOrderFieldsFactory.php +++ b/mailpoet/lib/Automation/Integrations/WooCommerce/Fields/CustomerOrderFieldsFactory.php @@ -69,9 +69,16 @@ class CustomerOrderFieldsFactory { 'woocommerce:customer:order-count', Field::TYPE_INTEGER, __('Order count', 'mailpoet'), - function (CustomerPayload $payload) { + function (CustomerPayload $payload, array $params = []) { $customer = $payload->getCustomer(); - return $customer ? $customer->get_order_count() : 0; + if (!$customer) { + return 0; + } + + $inTheLastSeconds = isset($params['in_the_last_seconds']) ? (int)$params['in_the_last_seconds'] : null; + return $inTheLastSeconds === null + ? $customer->get_order_count() + : $this->getRecentOrderCount($customer, $inTheLastSeconds); } ), new Field( @@ -163,6 +170,37 @@ class CustomerOrderFieldsFactory { return (float)$wpdb->get_var($statement); } + private function getRecentOrderCount(WC_Customer $customer, int $inTheLastSeconds): int { + $wpdb = $this->wordPress->getWpdb(); + $statuses = array_keys($this->wooCommerce->wcGetOrderStatuses()); + $statusesPlaceholder = implode(',', array_fill(0, count($statuses), '%s')); + + if ($this->wooCommerce->isWooCommerceCustomOrdersTableEnabled()) { + /** @var literal-string $query */ + $query = " + SELECT COUNT(o.id) + FROM {$wpdb->prefix}wc_orders o + WHERE o.customer_id = %d + AND o.status IN ($statusesPlaceholder) + AND o.date_created_gmt >= DATE_SUB(current_timestamp, INTERVAL %d SECOND) + "; + $statement = (string)$wpdb->prepare($query, array_merge([$customer->get_id()], $statuses, [$inTheLastSeconds])); + } else { + /** @var literal-string $query */ + $query = " + SELECT COUNT(p.ID) + FROM {$wpdb->posts} p + LEFT JOIN {$wpdb->postmeta} pm_user ON p.ID = pm_user.post_id AND pm_user.meta_key = '_customer_user' + WHERE p.post_type = 'shop_order' + AND p.post_status IN ($statusesPlaceholder) + AND pm_user.meta_value = %d + AND p.post_date_gmt >= DATE_SUB(current_timestamp, INTERVAL %d SECOND) + "; + $statement = (string)$wpdb->prepare($query, array_merge($statuses, [$customer->get_id(), $inTheLastSeconds])); + } + return (int)$wpdb->get_var($statement); + } + private function getPaidOrderDate(WC_Customer $customer, bool $fetchFirst): ?DateTimeImmutable { $wpdb = $this->wordPress->getWpdb(); $sorting = $fetchFirst ? 'ASC' : 'DESC'; diff --git a/mailpoet/tasks/phpstan/phpstan.neon b/mailpoet/tasks/phpstan/phpstan.neon index 8d101e5793..5c553cebf8 100644 --- a/mailpoet/tasks/phpstan/phpstan.neon +++ b/mailpoet/tasks/phpstan/phpstan.neon @@ -76,7 +76,7 @@ parameters: path: ../../lib/Logging/PluginVersionProcessor.php - message: "#^Cannot cast string|void to string\\.$#" - count: 5 + count: 7 path: ../../lib/Automation/Integrations/WooCommerce/Fields/CustomerOrderFieldsFactory.php - message: "#^Cannot cast string|void to string\\.$#" diff --git a/mailpoet/tests/integration/Automation/Integrations/WooCommerce/Fields/CustomerOrderFieldsFactoryTest.php b/mailpoet/tests/integration/Automation/Integrations/WooCommerce/Fields/CustomerOrderFieldsFactoryTest.php index d6b7a89b17..b365f9c8dc 100644 --- a/mailpoet/tests/integration/Automation/Integrations/WooCommerce/Fields/CustomerOrderFieldsFactoryTest.php +++ b/mailpoet/tests/integration/Automation/Integrations/WooCommerce/Fields/CustomerOrderFieldsFactoryTest.php @@ -75,12 +75,15 @@ class CustomerOrderFieldsFactoryTest extends \MailPoetTest { // 100 years $this->assertSame(162.3, $spentTotalField->getValue($customerPayload, ['in_the_last_seconds' => 100 * YEAR_IN_SECONDS])); + $this->assertSame(3, $orderCountField->getValue($customerPayload, ['in_the_last_seconds' => 100 * YEAR_IN_SECONDS])); // 3 months $this->assertSame(150.0, $spentTotalField->getValue($customerPayload, ['in_the_last_seconds' => 3 * MONTH_IN_SECONDS])); + $this->assertSame(2, $orderCountField->getValue($customerPayload, ['in_the_last_seconds' => 3 * MONTH_IN_SECONDS])); // 3 weeks $this->assertSame(150.0, $spentTotalField->getValue($customerPayload, ['in_the_last_seconds' => 3 * WEEK_IN_SECONDS])); + $this->assertSame(1, $orderCountField->getValue($customerPayload, ['in_the_last_seconds' => 3 * WEEK_IN_SECONDS])); } public function testOrderDateFields(): void {