This repository has been archived on 2025-01-19. You can view files and clone it, but cannot push or open issues or pull requests.
oliverdavies.uk-old-sculpin/source/_posts/2018-10-24-debugging-drupal-commerce-promotions-illiminate-collections.md

120 lines
3.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: Debugging Drupal Commerce Promotions and Adjustments using Illuminate Collections (Drupal 8)
excerpt: Using Laravels Illuminate Collections to debug an issue with a Drupal Commerce promotion.
tags:
- drupal
- drupal-8
- drupal-commerce
- drupal-planet
- illuminate-collections
- laravel-collections
- php
promoted: true
---
Today I found another instance where I decided to use [Illuminate Collections][0] within my Drupal 8 code; whilst I was debugging an issue where a [Drupal Commerce][1] promotion was incorrectly being applied to an order.
No adjustments were showing in the Drupal UI for that order, so after some initial investigation and finding that `$order->getAdjustments()` was empty, I determined that I would need to get the adjustments from each order item within the order.
If the order were an array, this is how it would be structured in this situation:
```php
$order = [
'id' => 1,
'items' => [
[
'id' => 1,
'adjustments' => [
['name' => 'Adjustment 1'],
['name' => 'Adjustment 2'],
['name' => 'Adjustment 3'],
]
],
[
'id' => 2,
'adjustments' => [
['name' => 'Adjustment 4'],
]
],
[
'id' => 3,
'adjustments' => [
['name' => 'Adjustment 5'],
['name' => 'Adjustment 6'],
]
],
],
];
```
## Getting the order items
I started by using `$order->getItems()` to load the orders items, converted them into a Collection, and used the Collections `pipe()` method and the `dump()` function provided by the [Devel module][2] to output the order items.
```php
collect($order->getItems())
->pipe(function (Collection $collection) {
dump($collection);
});
```
## Get the order item adjustments
Now we have a Collection of order items, for each item we need to get its adjustments. We can do this with `map()`, then call `getAdjustments()` on the order item.
This would return a Collection of arrays, with each array containing its own adjustments, so we can use `flatten()` to collapse all the adjustments into one single-dimensional array.
```php
collect($order->getItems())
->map(function (OrderItem $order_item) {
return $order_item->getAdjustments();
})
->flatten(1);
```
There are a couple of refactors that we can do here though:
- Use `flatMap()` to comine the `flatten()` and `map()` methods.
- Use [higher order messages][3] to delegate straight to the `getAdjustments()` method on the order, rather than having to create a closure and call the method within it.
```php
collect($order->getItems())
->flatMap->getAdjustments();
```
## Filtering
In this scenario, each order item had three adjustments - the correct promotion, the incorrect one and the standard VAT addition.
I wasnt concerned about the VAT adjustment for debugging, so I used `filter()` to remove it based on the result of the adjustments `getSourceId()` method.
```php
collect($order->getItems())
->flatMap->getAdjustments()
->filter(function (Adjustment $adjustment) {
return $adjustment->getSourceId() != 'vat';
});
```
## Conclusion
Now I have just the relevant adjustments, I want to be able to load each one to load it and check its conditions. To do this, I need just the source IDs.
Again, I can use a higher order message to directly call `getSourceId()` on the adjustment and return its value to `map()`.
```php
collect($order->getItems())
->flatMap->getAdjustments()
->filter(function (Adjustment $adjustment) {
return $adjustment->getSourceId() != 'vat';
})
->map->getSourceId();
```
This returns a Collection containing just the relevant promotion IDs being applied to the order that I can use for debugging.
Now just to find out why the incorrect promotion was applying!
[0]: https://laravel.com/docs/collections
[1]: https://drupalcommerce.org
[2]: https://www.drupal.org/project/devel
[3]: https://laravel-news.com/higher-order-messaging