Skip to content

Commit 70c2a9f

Browse files
fix: Prevent exception when attempting to access a custom line item's purchasable
1 parent 97d5a52 commit 70c2a9f

File tree

2 files changed

+53
-42
lines changed

2 files changed

+53
-42
lines changed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"require": {
1212
"php": "^8.2",
1313
"craftcms/cms": "^5.0.0",
14-
"klaviyo/api": "^7.1"
14+
"klaviyo/api": "^14.0.0"
1515
},
1616
"autoload": {
1717
"psr-4": {

src/services/Track.php

Lines changed: 52 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@
44

55
use Craft;
66
use craft\commerce\elements\Order;
7+
use craft\commerce\enums\LineItemType;
78
use craft\commerce\events\OrderStatusEvent;
89
use craft\commerce\events\RefundTransactionEvent;
910
use craft\commerce\events\TransactionEvent;
11+
use craft\commerce\models\LineItem;
1012
use craft\elements\Address;
1113
use craft\helpers\ArrayHelper;
1214
use DateTime;
@@ -285,54 +287,16 @@ protected function createProfile(array $profile, ?string $eventName = null, mixe
285287

286288
protected function getOrderDetails(Order $order, string $event = ''): array
287289
{
288-
/** @var Settings $settings */
289-
$settings = Plugin::getInstance()->getSettings();
290-
291290
$lineItemsProperties = [];
292291

293292
foreach ($order->lineItems as $lineItem) {
294-
$lineItemProperties = [];
295-
296-
// Add regular Product purchasable properties
297-
$product = $lineItem->purchasable->product ?? [];
298-
if ($product) {
299-
$lineItemProperties = [
300-
'value' => $lineItem->price * $lineItem->qty,
301-
'ProductName' => $product->title,
302-
'Slug' => $product->slug,
303-
'ProductURL' => $product->getUrl(),
304-
'ProductType' => $product->type->name,
305-
'ItemPrice' => $lineItem->price,
306-
'RowTotal' => $lineItem->subtotal,
307-
'Quantity' => $lineItem->qty,
308-
'SKU' => $lineItem->purchasable->sku,
309-
'Options' => $lineItem->getOptions(),
310-
'Adjustments' => collect($lineItem->getAdjustments())
311-
->flatMap(static fn ($adjustment) => [
312-
$adjustment->name => $adjustment->amountAsCurrency,
313-
])
314-
->toArray(),
315-
316-
];
317-
318-
$variant = $lineItem->purchasable;
319-
320-
$productImageField = $settings->productImageField;
321-
322-
if (isset($variant->{$productImageField}) && $variant->{$productImageField}->count()) {
323-
if ($image = $variant->{$productImageField}->one()) {
324-
$lineItemProperties['ImageURL'] = $image->getUrl($settings->productImageFieldTransformation, true);
325-
}
326-
} elseif (isset($product->{$productImageField}) && $product->{$productImageField}->count()) {
327-
if ($image = $product->{$productImageField}->one()) {
328-
$lineItemProperties['ImageURL'] = $image->getUrl($settings->productImageFieldTransformation, true);
329-
}
330-
}
293+
if ($lineItem->type !== LineItemType::Custom) {
294+
$lineItemProperties = $this->populateLineItemProperties($lineItem);
331295
}
332296

333297
// Add any additional user-defined properties
334298
$addLineItemCustomPropertiesEvent = new AddLineItemCustomPropertiesEvent([
335-
'properties' => $lineItemProperties,
299+
'properties' => $lineItemProperties ?? [],
336300
'order' => $order,
337301
'lineItem' => $lineItem,
338302
'event' => $event,
@@ -361,6 +325,53 @@ protected function getOrderDetails(Order $order, string $event = ''): array
361325
return $addOrderCustomPropertiesEvent->properties;
362326
}
363327

328+
private function populateLineItemProperties(LineItem $lineItem): array
329+
{
330+
/** @var Settings $settings */
331+
$settings = Plugin::getInstance()->getSettings();
332+
333+
$lineItemProperties = [];
334+
335+
// Add regular Product purchasable properties
336+
$product = $lineItem->purchasable?->product ?? [];
337+
if ($product !== []) {
338+
$lineItemProperties = [
339+
'value' => $lineItem->price * $lineItem->qty,
340+
'ProductName' => $product->title,
341+
'Slug' => $product->slug,
342+
'ProductURL' => $product->getUrl(),
343+
'ProductType' => $product->type->name,
344+
'ItemPrice' => $lineItem->price,
345+
'RowTotal' => $lineItem->subtotal,
346+
'Quantity' => $lineItem->qty,
347+
'SKU' => $lineItem->purchasable->sku,
348+
'Options' => $lineItem->getOptions(),
349+
'Adjustments' => collect($lineItem->getAdjustments())
350+
->flatMap(static fn ($adjustment) => [
351+
$adjustment->name => $adjustment->amountAsCurrency,
352+
])
353+
->toArray(),
354+
355+
];
356+
357+
$variant = $lineItem->purchasable;
358+
359+
$productImageField = $settings->productImageField;
360+
361+
if (isset($variant->{$productImageField}) && $variant->{$productImageField}->count()) {
362+
if ($image = $variant->{$productImageField}->one()) {
363+
$lineItemProperties['ImageURL'] = $image->getUrl($settings->productImageFieldTransformation, true);
364+
}
365+
} elseif (isset($product->{$productImageField}) && $product->{$productImageField}->count()) {
366+
if ($image = $product->{$productImageField}->one()) {
367+
$lineItemProperties['ImageURL'] = $image->getUrl($settings->productImageFieldTransformation, true);
368+
}
369+
}
370+
}
371+
372+
return $lineItemProperties;
373+
}
374+
364375
private function isInGroup(array $selectedGroups, array $userGroups): bool
365376
{
366377
$groupIds = ArrayHelper::getColumn($userGroups, 'id');

0 commit comments

Comments
 (0)