Open julien-MD opened 9 months ago
Hello @julien-MD,
Thanks for creating the issue and explaining your problem. We will be happy if we can include them. Can you share some examples that you are trying to do?
Hi,
Here is some more data about the request.
I have a Controller which build the data array needed:
$data = [
'customer_note' => $order_comment,
'billing' => [
'first_name' => $customer['billing']->first_name,
'last_name' => $customer['billing']->last_name,
'address_1' => $customer['billing']->address_1,
'address_2' => $customer['billing']->address_2,
'city' => $customer['billing']->city,
'state' => $customer['billing']->state,
'postcode' => $customer['billing']->postcode,
'country' => $customer['billing']->country,
'email' => $customer['billing']->email,
'phone' => $customer['billing']->phone,
],
'shipping' => [
'first_name' => $customer['shipping']->first_name,
'last_name' => $customer['shipping']->last_name,
'address_1' => $customer['shipping']->address_1,
'address_2' => $customer['shipping']->address_2,
'city' => $customer['shipping']->city,
'state' => $customer['shipping']->state,
'postcode' => $customer['shipping']->postcode,
'country' => $customer['shipping']->country,
],
'line_items' => [],
'shipping_lines' => [
[
'method_id' => 'gls_chezvous',
'method_title' => 'GLS',
'total' => '0'
]
]
];
foreach ($order_products as $order_product) {
$product = Products::where('id', $order_product->product_id)->first();
$data['line_items'][] =
[
'product_id' => $product->wc_product_id,
'variation_id' => $product->wc_variation_id,
'quantity' => $order_product->quantity,
'meta_data' => [
['key' => 'Commentaire', 'value' => $order_product->product_comment ?? '']
]
];
}
Here, the thing is my $order_products
array will eventually be quite big because the app is intended to be used by customers who buy a lot of products.
Then I have a Job which process the sending of the order to Woocommerce, it is called in the Controller like so:
ProcessExport::dispatch(['order_data' => $data, 'order_id' => $order->id, 'customer_id' => $customer_id]);
Here is the job:
public function handle(): void
{
$wc_order = Order::create($this->data['order_data']);
if(isset($wc_order['id'])) {
do_things();
}
else{
do_other_things();
}
}
You can see that I need to wait for the Woocommerce response in order to go on with the code. The issue is at this point, because the Woocommerce API default behavior is to send me back the whole order data. If the server is almost idling and the order not to big, it has time to build its response. Otherway, it timeouts (but the order is created on the Woocommerce side).
In order to get around the issue I had to edit the Woocommerce API, forcing it to send me back only the data I need:
File vendor/automattic/woocommerce/src/WooCommerce/HttpClient/HttpClient.php
protected function createRequest($endpoint, $method, $data = [], $parameters = [])
{
$body = '';
$url = $this->url . $endpoint;
$hasData = !empty($data);
$headers = $this->getRequestHeaders($hasData);
// HTTP method override feature which masks PUT and DELETE HTTP methods as POST method with added
// ?_method=PUT query parameter and/or X-HTTP-Method-Override HTTP header.
if (!in_array($method, ['GET', 'POST'])) {
$usePostMethod = false;
if ($this->options->isMethodOverrideQuery()) {
$parameters = array_merge(['_method' => $method], $parameters);
$usePostMethod = true;
}
if ($this->options->isMethodOverrideHeader()) {
$headers['X-HTTP-Method-Override'] = $method;
$usePostMethod = true;
}
if ($usePostMethod) {
$method = 'POST';
}
}
// Setup authentication.
$parameters = $this->authenticate($url, $method, $parameters);
// Setup method.
$this->setupMethod($method);
// Include post fields.
if ($hasData) {
$body = \json_encode($data);
\curl_setopt($this->ch, CURLOPT_POSTFIELDS, $body);
}
/* Start of what I added */
if($method == 'POST' && $endpoint == 'orders')
$parameters = array_merge(['_fields' => 'id'], $parameters);
/* End of what I added */
$this->request = new Request(
$this->buildUrlQuery($url, $parameters),
$method,
$parameters,
$headers,
$body
);
return $this->getRequest();
}
This method allows a $parameters
input which can be used to do a lot of things but in my case it let me tell it that I only needed the id of the created order using the _fields
key.
I did not find a proper way to send this $parameters
parameter using the Order::create()
method within laravel-woocommerce.
Let me know if you need more info.
Hi,
I had an issue where orders created were too big for the Woocommerce server to be able to build a response, the query ending in a server timeout. I asked Woocommerce if it was possible to request the REST API to not send back the whole order data, as I send it in the first place and do not need it. They replied that I could use the query parameters in order to achieve that (see here).
It appears that this library does not allow this possibility (or I didn't find out how it is possible to do it), so I had to edit files for myself.
Is it possible to add this feature in a future release?
Thanks