Passed
Push — develop-v3 ( f53ba7...7f8e2f )
by Andrew
17:44
created

Commerce   C

Complexity

Total Complexity 56

Size/Duplication

Total Lines 419
Duplicated Lines 0 %

Importance

Changes 8
Bugs 2 Features 0
Metric Value
eloc 169
dl 0
loc 419
rs 5.5199
c 8
b 2
f 0
wmc 56

12 Methods

Rating   Name   Duplication   Size   Complexity  
A triggerOrderCompleteEvent() 0 12 2
A triggerAddToCartEvent() 0 10 1
A triggerRemoveFromCartEvent() 0 10 1
A triggerBeginCheckoutEvent() 0 21 3
A addCommerceProductListImpression() 0 14 3
B pullDataFromField() 0 30 9
A addCommerceOrderToEvent() 0 21 3
A getDataFromElements() 0 28 5
A addCommerceProductImpression() 0 14 4
C addProductDataFromProductOrVariant() 0 69 12
A getNewItemParameter() 0 7 1
C addProductDataFromLineItem() 0 72 12

How to fix   Complexity   

Complex Class

Complex classes like Commerce often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Commerce, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * Instant Analytics plugin for Craft CMS
4
 *
5
 * Instant Analytics brings full Google Analytics support to your Twig templates
6
 *
7
 * @link      https://nystudio107.com
0 ignored issues
show
Coding Style introduced by
The tag in position 1 should be the @copyright tag
Loading history...
8
 * @copyright Copyright (c) 2017 nystudio107
0 ignored issues
show
Coding Style introduced by
@copyright tag must contain a year and the name of the copyright holder
Loading history...
9
 */
0 ignored issues
show
Coding Style introduced by
PHP version not specified
Loading history...
Coding Style introduced by
Missing @category tag in file comment
Loading history...
Coding Style introduced by
Missing @package tag in file comment
Loading history...
Coding Style introduced by
Missing @author tag in file comment
Loading history...
Coding Style introduced by
Missing @license tag in file comment
Loading history...
10
11
namespace nystudio107\instantanalyticsGa4\services;
12
13
use Br33f\Ga4\MeasurementProtocol\Dto\Event\ItemBaseEvent;
14
use Br33f\Ga4\MeasurementProtocol\Dto\Event\PurchaseEvent;
15
use Br33f\Ga4\MeasurementProtocol\Dto\Parameter\ItemParameter;
16
use craft\base\Component;
17
use craft\commerce\elements\Order;
0 ignored issues
show
Bug introduced by
The type craft\commerce\elements\Order was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
18
use craft\commerce\elements\Product;
0 ignored issues
show
Bug introduced by
The type craft\commerce\elements\Product was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
19
use craft\commerce\elements\Variant;
0 ignored issues
show
Bug introduced by
The type craft\commerce\elements\Variant was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
20
use craft\commerce\models\LineItem;
0 ignored issues
show
Bug introduced by
The type craft\commerce\models\LineItem was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
21
use craft\commerce\Plugin as CommercePlugin;
0 ignored issues
show
Bug introduced by
The type craft\commerce\Plugin was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
22
use craft\elements\db\CategoryQuery;
23
use craft\elements\db\EntryQuery;
24
use craft\elements\db\MatrixBlockQuery;
25
use craft\elements\db\TagQuery;
26
use nystudio107\instantanalyticsGa4\InstantAnalytics;
27
use yii\base\InvalidConfigException;
28
use function get_class;
29
30
/**
31
 * Commerce Service
32
 *
33
 * @author    nystudio107
0 ignored issues
show
Coding Style introduced by
The tag in position 1 should be the @package tag
Loading history...
Coding Style introduced by
Content of the @author tag must be in the form "Display Name <[email protected]>"
Loading history...
Coding Style introduced by
Tag value for @author tag indented incorrectly; expected 2 spaces but found 4
Loading history...
34
 * @package   InstantAnalytics
0 ignored issues
show
Coding Style introduced by
Tag value for @package tag indented incorrectly; expected 1 spaces but found 3
Loading history...
35
 * @since     1.0.0
0 ignored issues
show
Coding Style introduced by
The tag in position 3 should be the @author tag
Loading history...
Coding Style introduced by
Tag value for @since tag indented incorrectly; expected 3 spaces but found 5
Loading history...
36
 */
0 ignored issues
show
Coding Style introduced by
Missing @category tag in class comment
Loading history...
Coding Style introduced by
Missing @license tag in class comment
Loading history...
Coding Style introduced by
Missing @link tag in class comment
Loading history...
37
class Commerce extends Component
38
{
39
    // Public Methods
40
    // =========================================================================
41
42
    /**
43
     * Enqueue analytics information for the completed order
44
     *
45
     * @param ?Order $order the Product or Variant
46
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
47
    public function triggerOrderCompleteEvent(Order $order = null)
48
    {
49
        if ($order) {
50
            $event = InstantAnalytics::$plugin->ga4->getAnalytics()->create()->PurchaseEvent();
51
            $this->addCommerceOrderToEvent($event, $order);
52
53
            InstantAnalytics::$plugin->ga4->getAnalytics()->addEvent($event);
54
55
            InstantAnalytics::$plugin->logAnalyticsEvent(
0 ignored issues
show
Bug introduced by
The method logAnalyticsEvent() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

55
            InstantAnalytics::$plugin->/** @scrutinizer ignore-call */ 
56
                                       logAnalyticsEvent(

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
56
                'Adding `Commerce - Order Complete event`: `{reference}` => `{price}`',
57
                ['reference' => $order->reference, 'price' => $order->totalPrice],
58
                __METHOD__
59
            );
60
        }
61
    }
62
63
    /**
64
     * Enqueue analytics information for a new checkout flow
65
     *
66
     * @param ?Order $order
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
67
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
68
    public function triggerBeginCheckoutEvent(Order $order = null)
69
    {
70
        if ($order) {
71
            $event = InstantAnalytics::$plugin->ga4->getAnalytics()->create()->BeginCheckoutEvent();
72
            // First, include the transaction data
73
            $event->setCurrency($order->getPaymentCurrency())
74
                ->setValue($order->getTotalPrice());
75
76
            // Add each line item in the cart
77
            $index = 1;
78
            foreach ($order->lineItems as $lineItem) {
79
                $this->addProductDataFromLineItem($event, $lineItem, $index);
80
                $index++;
81
            }
82
83
            InstantAnalytics::$plugin->ga4->getAnalytics()->addEvent($event);
84
85
            InstantAnalytics::$plugin->logAnalyticsEvent(
86
                'Adding `Commerce - Begin Checkout event``',
87
                [],
88
                __METHOD__
89
            );
90
        }
91
    }
92
93
    /**
94
     * Send analytics information for the item added to the cart
95
     *
96
     * @param LineItem $lineItem the line item that was added
97
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
98
    public function triggerAddToCartEvent(LineItem $lineItem): void
99
    {
100
        $event = InstantAnalytics::$plugin->ga4->getAnalytics()->create()->AddToCartEvent();
101
        $this->addProductDataFromLineItem($event, $lineItem);
102
        InstantAnalytics::$plugin->ga4->getAnalytics()->addEvent($event);
103
104
        InstantAnalytics::$plugin->logAnalyticsEvent(
105
            'Adding `Commerce - Add to Cart event`: `{title}` => `{quantity}`',
106
            ['title' => $lineItem->purchasable->title ?? $lineItem->getDescription(), 'quantity' => $lineItem->qty],
107
            __METHOD__
108
        );
109
    }
110
111
    /**
112
     * Send analytics information for the item removed from the cart
113
     *
114
     * @param LineItem $lineItem
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
115
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
116
    public function triggerRemoveFromCartEvent(LineItem $lineItem)
117
    {
118
        $event = InstantAnalytics::$plugin->ga4->getAnalytics()->create()->RemoveFromCartEvent();
119
        $this->addProductDataFromLineItem($event, $lineItem);
120
        InstantAnalytics::$plugin->ga4->getAnalytics()->addEvent($event);
121
122
        InstantAnalytics::$plugin->logAnalyticsEvent(
123
            'Adding `Commerce - Remove from Cart event`: `{title}` => `{quantity}`',
124
            ['title' => $lineItem->purchasable->title ?? $lineItem->getDescription(), 'quantity' => $lineItem->qty],
125
            __METHOD__
126
        );
127
    }
128
129
    /**
130
     * Add a product impression from a Craft Commerce Product or Variant
131
     *
132
     * @param Product|Variant|null $productVariant the Product or Variant
0 ignored issues
show
Coding Style introduced by
Tag value for @param tag indented incorrectly; expected 2 spaces but found 1
Loading history...
133
     * @throws InvalidConfigException
0 ignored issues
show
Coding Style introduced by
Tag @throws cannot be grouped with parameter tags in a doc comment
Loading history...
134
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
135
    public function addCommerceProductImpression($productVariant): void
136
    {
137
        if ($productVariant) {
138
            $event = InstantAnalytics::$plugin->ga4->getAnalytics()->create()->ViewItemEvent();
139
            $this->addProductDataFromProductOrVariant($event, $productVariant);
140
141
            InstantAnalytics::$plugin->ga4->getAnalytics()->addEvent($event);
142
143
            $sku = $productVariant instanceof Product ? $productVariant->getDefaultVariant()->sku : $productVariant->sku;
144
            $name = $productVariant instanceof Product ? $productVariant->getName() : $productVariant->getProduct()->getName();
0 ignored issues
show
Bug introduced by
The method getProduct() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

144
            $name = $productVariant instanceof Product ? $productVariant->getName() : $productVariant->/** @scrutinizer ignore-call */ getProduct()->getName();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
145
            InstantAnalytics::$plugin->logAnalyticsEvent(
146
                'Adding view item event for `{sku}` - `{name}` - `{name}` - `{index}`',
147
                ['sku' => $sku, 'name' => $name],
148
                __METHOD__
149
            );
150
        }
151
    }
152
153
    /**
154
     * Add a product list impression from a Craft Commerce Product or Variant list
155
     *
156
     * @param Product[]|Variant[] $products
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
157
     * @param string $listName
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Expected 14 spaces after parameter type; 1 found
Loading history...
158
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
159
    public function addCommerceProductListImpression(array $products, string $listName = 'default'): void
160
    {
161
        if (!empty($products)) {
162
            $event = InstantAnalytics::$plugin->ga4->getAnalytics()->create()->ViewItemListEvent();
163
            foreach ($products as $index => $productVariant) {
164
                $this->addProductDataFromProductOrVariant($event, $productVariant, $index, $listName);
165
            }
166
167
            InstantAnalytics::$plugin->ga4->getAnalytics()->addEvent($event);
168
169
            InstantAnalytics::$plugin->logAnalyticsEvent(
170
                'Adding view item list event. Listing {number} of items from the `{listName}` list.',
171
                ['number' => count($products), 'listName' => $listName],
172
                __METHOD__
173
            );
174
        }
175
    }
176
177
    /**
178
     * Add a Craft Commerce OrderModel to a Purchase Event
179
     *
180
     * @param PurchaseEvent $event The PurchaseEvent
181
     * @param Order $order
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Expected 9 spaces after parameter type; 1 found
Loading history...
182
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
183
    protected function addCommerceOrderToEvent(PurchaseEvent $event, Order $order)
184
    {
185
        // First, include the transaction data
186
        $event->setCurrency($order->getPaymentCurrency())
187
            ->setTransactionId($order->reference)
188
            ->setValue($order->getTotalPrice())
189
            ->setTax($order->getTotalTax())
190
            ->setShipping($order->getTotalShippingCost());
191
192
        // Coupon code
193
        if ($order->couponCode) {
194
            $event->setCoupon($order->couponCode);
195
        }
196
197
        // Add each line item in the transaction
198
        // Two cases - variant and non variant products
199
        $index = 1;
200
201
        foreach ($order->lineItems as $lineItem) {
202
            $this->addProductDataFromLineItem($event, $lineItem, $index);
203
            $index++;
204
        }
205
    }
206
207
    /**
208
     * Add a Craft Commerce LineItem to an Analytics object
209
     *
210
     * @param ItemBaseEvent $event
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
211
     * @param LineItem $lineItem
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Expected 6 spaces after parameter type; 1 found
Loading history...
212
     * @param int $index
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Expected 11 spaces after parameter type; 1 found
Loading history...
213
     * @param string $listName
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Expected 8 spaces after parameter type; 1 found
Loading history...
214
     *
215
     * @return string the title of the product
216
     * @throws InvalidConfigException
217
     */
218
    protected function addProductDataFromLineItem(ItemBaseEvent $event, LineItem $lineItem, int $index = 0, string $listName = ''): string
219
    {
220
        $eventItem = $this->getNewItemParameter();
221
222
        $product = null;
223
        $purchasable = $lineItem->purchasable;
224
225
        /** @phpstan-ignore-next-line */
0 ignored issues
show
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
Missing short description in doc comment
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
226
        if ($purchasable === null) {
227
            $eventItem->setItemName($lineItem->getDescription());
228
            $eventItem->setItemId($lineItem->getSku());
229
        } else {
230
            $eventItem->setItemName($purchasable->title ?? $lineItem->getDescription());
231
            $eventItem->setItemId($purchasable->getSku());
232
        }
233
        $eventItem->setPrice($lineItem->salePrice);
234
        $eventItem->setQuantity($lineItem->qty);
235
236
        // Handle this purchasable being a Variant
237
        if (is_a($purchasable, Variant::class)) {
238
            /** @var Variant $purchasable */
0 ignored issues
show
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
Missing short description in doc comment
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
239
            $product = $purchasable->getProduct();
240
            $variant = $purchasable;
241
            // Product with variants
242
            $eventItem->setItemName($product->title);
243
            $eventItem->setItemVariant($variant->title);
244
            $eventItem->setItemCategory($product->getType());
245
        }
246
247
        // Handle this purchasable being a Product
248
        if (is_a($purchasable, Product::class)) {
249
            /** @var Product $purchasable */
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
250
            $product = $purchasable;
251
            $eventItem->setItemName($product->title);
252
            $eventItem->setItemVariant($product->title);
253
            $eventItem->setItemCategory($product->getType());
254
        }
255
256
        // Handle product lists
257
        if ($index) {
258
            $eventItem->setIndex($index);
259
        }
260
261
        if ($listName) {
262
            $eventItem->setItemListName($listName);
263
        }
264
265
        // Add in any custom categories/brands that might be set
266
        if (InstantAnalytics::$settings && $product) {
267
            if (isset(InstantAnalytics::$settings['productCategoryField'])
268
                && !empty(InstantAnalytics::$settings['productCategoryField'])) {
0 ignored issues
show
Coding Style introduced by
Closing parenthesis of a multi-line IF statement must be on a new line
Loading history...
269
                $category = $this->pullDataFromField(
270
                    $product,
271
                    InstantAnalytics::$settings['productCategoryField']
272
                );
273
                $eventItem->setItemCategory($category);
274
            }
275
            if (isset(InstantAnalytics::$settings['productBrandField'])
276
                && !empty(InstantAnalytics::$settings['productBrandField'])) {
0 ignored issues
show
Coding Style introduced by
Closing parenthesis of a multi-line IF statement must be on a new line
Loading history...
277
                $brand = $this->pullDataFromField(
278
                    $product,
279
                    InstantAnalytics::$settings['productBrandField']
280
                );
281
282
                $eventItem->setItemBrand($brand);
283
            }
284
        }
285
286
        //Add each product to the hit to be sent
287
        $event->addItem($eventItem);
288
289
        return $eventItem->getItemName();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $eventItem->getItemName() could return the type null which is incompatible with the type-hinted return string. Consider adding an additional type-check to rule them out.
Loading history...
290
    }
291
292
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $event should have a doc-comment as per coding-style.
Loading history...
Coding Style introduced by
Parameter $index should have a doc-comment as per coding-style.
Loading history...
Coding Style introduced by
Parameter $listName should have a doc-comment as per coding-style.
Loading history...
293
     * Extract product data from a Craft Commerce Product or Variant
294
     *
295
     * @param Product|Variant|null $productVariant the Product or Variant
0 ignored issues
show
Coding Style introduced by
Doc comment for parameter $productVariant does not match actual variable name $event
Loading history...
296
     *
297
     * @throws InvalidConfigException
298
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
299
    protected function addProductDataFromProductOrVariant(ItemBaseEvent $event, $productVariant = null, $index = null, $listName = ''): void
300
    {
301
        if ($productVariant === null) {
302
            return;
303
        }
304
305
        $eventItem = $this->getNewItemParameter();
306
307
        $isVariant = $productVariant instanceof Variant;
308
        $variant = $isVariant ? $productVariant : $productVariant->getDefaultVariant();
309
310
        if (!$variant) {
311
            return;
312
        }
313
314
        $eventItem->setItemId($variant->sku);
315
        $eventItem->setItemName($variant->title);
316
        $eventItem->setPrice((float)number_format($variant->price, 2, '.', ''));
317
318
        $category = ($isVariant ? $variant->getProduct() : $productVariant)->getType()['name'];
319
320
        if (InstantAnalytics::$settings) {
321
            if (isset(InstantAnalytics::$settings['productCategoryField'])
322
                && !empty(InstantAnalytics::$settings['productCategoryField'])) {
0 ignored issues
show
Coding Style introduced by
Closing parenthesis of a multi-line IF statement must be on a new line
Loading history...
323
                $category = $this->pullDataFromField(
324
                    $productVariant,
325
                    InstantAnalytics::$settings['productCategoryField']
326
                );
327
                /* -- @TODO unclear what this even does
328
                if (empty($productData['category']) && $isVariant) {
329
                    $category = $this->pullDataFromField(
330
                        $productVariant->product,
331
                        InstantAnalytics::$settings['productCategoryField']
332
                    );
333
                }
334
                */
335
            }
336
            $eventItem->setItemCategory($category);
337
338
            if (isset(InstantAnalytics::$settings['productBrandField'])
339
                && !empty(InstantAnalytics::$settings['productBrandField'])) {
0 ignored issues
show
Coding Style introduced by
Closing parenthesis of a multi-line IF statement must be on a new line
Loading history...
340
                $brand = $this->pullDataFromField(
341
                    $productVariant,
342
                    InstantAnalytics::$settings['productBrandField'],
343
                    true
344
                );
345
                /* -- @TODO unclear what this even does
346
                if (empty($productData['brand']) && $isVariant) {
347
                    $brand = $this->pullDataFromField(
348
                        $productVariant,
349
                        InstantAnalytics::$settings['productBrandField'],
350
                        true
351
                    );
352
                }
353
                */
354
                $eventItem->setItemBrand($brand);
355
            }
356
        }
357
358
        if ($index !== null) {
359
            $eventItem->setIndex($index);
360
        }
361
362
        if (!empty($listName)) {
363
            $eventItem->setItemListName($listName);
364
        }
365
366
        // Add item info to the event
367
        $event->addItem($eventItem);
368
    }
369
370
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
371
     * @param Product|Variant|null $productVariant
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
372
     * @param string $fieldHandle
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Expected 15 spaces after parameter type; 1 found
Loading history...
373
     * @param bool $isBrand
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Expected 17 spaces after parameter type; 1 found
Loading history...
374
     *
375
     * @return string
376
     */
377
    protected function pullDataFromField($productVariant, $fieldHandle, $isBrand = false): string
378
    {
379
        $result = '';
380
        if ($productVariant && $fieldHandle) {
381
            $srcField = $productVariant[$fieldHandle] ?? $productVariant->product[$fieldHandle] ?? null;
382
            // Handle eager loaded elements
383
            if (is_array($srcField)) {
384
                return $this->getDataFromElements($isBrand, $srcField);
385
            }
386
            // If the source field isn't an object, return nothing
387
            if (!is_object($srcField)) {
388
                return $result;
389
            }
390
            switch (get_class($srcField)) {
391
                case MatrixBlockQuery::class:
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
392
                case TagQuery::class:
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
393
                    break;
394
                case CategoryQuery::class:
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
395
                case EntryQuery::class:
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
396
                    $result = $this->getDataFromElements($isBrand, $srcField->all());
397
                    break;
398
399
400
                default:
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
401
                    $result = strip_tags($srcField->__toString());
402
                    break;
403
            }
404
        }
405
406
        return $result;
407
    }
408
409
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
410
     * @param bool $isBrand
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Expected 2 spaces after parameter type; 1 found
Loading history...
Coding Style introduced by
Tag value for @param tag indented incorrectly; expected 2 spaces but found 1
Loading history...
411
     * @param array $elements
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Tag value for @param tag indented incorrectly; expected 2 spaces but found 1
Loading history...
412
     * @return string
0 ignored issues
show
Coding Style introduced by
Tag @return cannot be grouped with parameter tags in a doc comment
Loading history...
413
     */
414
    protected function getDataFromElements(bool $isBrand, array $elements): string
415
    {
416
        $cats = [];
417
418
        if ($isBrand) {
419
            // Because we can only have one brand, we'll get
420
            // the very last category. This means if our
421
            // brand is a sub-category, we'll get the child
422
            // not the parent.
423
            foreach ($elements as $cat) {
424
                $cats = [$cat->title];
425
            }
426
        } else {
427
            // For every category, show its ancestors
428
            // delimited by a slash.
429
            foreach ($elements as $cat) {
430
                $name = $cat->title;
431
432
                while ($cat = $cat->parent) {
433
                    $name = $cat->title . '/' . $name;
434
                }
435
436
                $cats[] = $name;
437
            }
438
        }
439
440
        // Join separate categories with a pipe.
441
        return implode('|', $cats);
442
    }
443
444
    /**
445
     * Create an item parameter and set affiliation on it, if any exists.
446
     *
447
     * @return ItemParameter
448
     */
449
    protected function getNewItemParameter(): ItemParameter
450
    {
451
        $parameter = new ItemParameter();
452
        $parameter->setAffiliation(InstantAnalytics::$plugin->ga4->getAnalytics()->getAffiliation());
453
        $parameter->setCurrency(CommercePlugin::getInstance()->getPaymentCurrencies()->getPrimaryPaymentCurrencyIso());
454
455
        return $parameter;
456
    }
457
}
458