Skip to content

Commit b9500d3

Browse files
committed
perf: filter in sql, not php
Previously, this code filtered the order list in PHP-land, which is computationally infeasible once the order list size gets too large. This reworks to filter in SQL instead, which is orders of magnitude more efficient. Additionally, no more memory errors on large databases of orders.
1 parent 2012ea7 commit b9500d3

File tree

1 file changed

+36
-33
lines changed

1 file changed

+36
-33
lines changed

Model/Resolver/GuestOrders.php

Lines changed: 36 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
<?php
2+
23
/**
34
* Copyright © Magento, Inc. All rights reserved.
45
* See COPYING.txt for license details.
56
*/
7+
68
declare(strict_types=1);
79

810
namespace Graycore\GuestOrdersGraphQl\Model\Resolver;
@@ -82,39 +84,37 @@ public function resolve(
8284
array $args = null
8385
) {
8486
return [
85-
'items' => $this->formatOrdersArray($this->getOrdersForCart($args['cartId']))
87+
'items' => $this->formatOrder($this->getOrderForCart($args['cartId']))
8688
];
8789
}
8890

8991
/**
9092
* Format order models for graphql schema.
9193
* Copied from the Magento resolver.
9294
*
93-
* @param OrderInterface[] $orderModels
95+
* @param \Magento\Sales\Model\Order $order
9496
* @return array
9597
*/
96-
private function formatOrdersArray(array $orderModels)
98+
private function formatOrder(\Magento\Sales\Model\Order $order)
9799
{
98-
$ordersArray = [];
99-
foreach ($orderModels as $orderModel) {
100-
$ordersArray[] = [
101-
'created_at' => $orderModel->getCreatedAt(),
102-
'grand_total' => $orderModel->getGrandTotal(),
103-
'id' => base64_encode($orderModel->getEntityId()),
104-
'increment_id' => $orderModel->getIncrementId(),
105-
'number' => $orderModel->getIncrementId(),
106-
'order_date' => $orderModel->getCreatedAt(),
107-
'order_number' => $orderModel->getIncrementId(),
108-
'status' => $orderModel->getStatusLabel(),
109-
'shipping_method' => $orderModel->getShippingDescription(),
110-
'shipping_address' => $this->orderAddress->getOrderShippingAddress($orderModel),
111-
'billing_address' => $this->orderAddress->getOrderBillingAddress($orderModel),
112-
'payment_methods' => $this->orderPayments->getOrderPaymentMethod($orderModel),
113-
'model' => $orderModel,
114-
'email' => $orderModel->getCustomerEmail()
115-
];
116-
}
117-
return $ordersArray;
100+
return [
101+
[
102+
'created_at' => $order->getCreatedAt(),
103+
'grand_total' => $order->getGrandTotal(),
104+
'id' => base64_encode($order->getEntityId() ?? ''),
105+
'increment_id' => $order->getIncrementId(),
106+
'number' => $order->getIncrementId(),
107+
'order_date' => $order->getCreatedAt(),
108+
'order_number' => $order->getIncrementId(),
109+
'status' => $order->getStatusLabel(),
110+
'shipping_method' => $order->getShippingDescription(),
111+
'shipping_address' => $this->orderAddress->getOrderShippingAddress($order),
112+
'billing_address' => $this->orderAddress->getOrderBillingAddress($order),
113+
'payment_methods' => $this->orderPayments->getOrderPaymentMethod($order),
114+
'model' => $order,
115+
'email' => $order->getCustomerEmail()
116+
]
117+
];
118118
}
119119

120120
/**
@@ -137,10 +137,8 @@ private function getCart(string $cartHash)
137137
);
138138
}
139139

140-
$cartCustomerId = (int)$cart->getCustomerId();
141-
142140
/* Not a guest cart, throw */
143-
if (0 !== $cartCustomerId) {
141+
if (!$cart->getCustomerIsGuest()) {
144142
throw new GraphQlAuthorizationException(
145143
__(
146144
'The cart "%masked_cart_id" is not a guest cart',
@@ -158,7 +156,7 @@ private function getCart(string $cartHash)
158156
* @param string $cartHash the hashed cart ID
159157
* @throws GraphQlNoSuchEntityException
160158
*/
161-
private function getOrdersForCart(string $cartHash)
159+
private function getOrderForCart(string $cartHash)
162160
{
163161
$orderId = $this->getCart($cartHash)->getReservedOrderId();
164162

@@ -171,13 +169,18 @@ private function getOrdersForCart(string $cartHash)
171169
);
172170
}
173171

174-
$orders = $this->collectionFactory->create(null)->getItems();
175172

176-
/** @param OrderInterface $order */
177-
$isCartOrder = function ($order) use ($orderId) {
178-
return $order->getIncrementId() === $orderId;
179-
};
180173

181-
return array_values(array_filter($orders, $isCartOrder));
174+
$order = $this->collectionFactory->create()->addFieldToSearchFilter('increment_id', $orderId)->getFirstItem();
175+
176+
if (!$order->getIncrementId()) {
177+
throw new GraphQlNoSuchEntityException(
178+
__(
179+
'Could not find an order associated with cart with ID "%masked_cart_id"',
180+
['masked_cart_id' => $cartHash]
181+
)
182+
);
183+
}
184+
return $order;
182185
}
183186
}

0 commit comments

Comments
 (0)