GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( c11669...f9e8ce )
by Jorge
02:15
created

Analytics::setDebug()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
rs 10
cc 1
eloc 3
nc 1
nop 1
1
<?php
2
3
namespace TheIconic\Tracking\GoogleAnalytics;
4
5
use TheIconic\Tracking\GoogleAnalytics\Parameters\SingleParameter;
6
use TheIconic\Tracking\GoogleAnalytics\Parameters\CompoundParameterCollection;
7
use TheIconic\Tracking\GoogleAnalytics\Network\HttpClient;
8
use TheIconic\Tracking\GoogleAnalytics\Exception\InvalidPayloadDataException;
9
10
/**
11
 * Class Analytics
12
 *
13
 * The main interface for the clients, it relies heavily in magic methods exposing
14
 * an interface with method tags.
15
 *
16
 * General
17
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setProtocolVersion($value)
18
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setTrackingId($value)
19
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setAnonymizeIp($value)
20
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setDataSource($value)
21
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setQueueTime($value)
22
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setCacheBuster($value)
23
 *
24
 * User
25
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setClientId($value)
26
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setUserId($value)
27
 *
28
 * Session
29
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setSessionControl($value)
30
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setIpOverride($value)
31
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setUserAgentOverride($value)
32
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setGeographicalOverride($value)
33
 *
34
 * Traffic Sources
35
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setDocumentReferrer($value)
36
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setCampaignName($value)
37
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setCampaignSource($value)
38
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setCampaignMedium($value)
39
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setCampaignKeyword($value)
40
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setCampaignContent($value)
41
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setCampaignId($value)
42
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setGoogleAdwordsId($value)
43
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setGoogleDisplayAdsId($value)
44
 *
45
 * System Info
46
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setScreenResolution($value)
47
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setViewportSize($value)
48
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setDocumentEncoding($value)
49
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setScreenColors($value)
50
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setUserLanguage($value)
51
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setJavaEnabled($value)
52
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setFlashVersion($value)
53
 *
54
 * Hit
55
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setHitType($value)
56
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setNonInteractionHit($value)
57
 * @method \TheIconic\Tracking\GoogleAnalytics\AnalyticsResponse sendPageview()
58
 * @method \TheIconic\Tracking\GoogleAnalytics\AnalyticsResponse sendEvent()
59
 * @method \TheIconic\Tracking\GoogleAnalytics\AnalyticsResponse sendScreenview()
60
 * @method \TheIconic\Tracking\GoogleAnalytics\AnalyticsResponse sendTransaction()
61
 * @method \TheIconic\Tracking\GoogleAnalytics\AnalyticsResponse sendItem()
62
 * @method \TheIconic\Tracking\GoogleAnalytics\AnalyticsResponse sendSocial()
63
 * @method \TheIconic\Tracking\GoogleAnalytics\AnalyticsResponse sendException()
64
 * @method \TheIconic\Tracking\GoogleAnalytics\AnalyticsResponse sendTiming()
65
 *
66
 * Content Information
67
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setDocumentLocationUrl($value)
68
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setDocumentHostName($value)
69
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setDocumentPath($value)
70
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setDocumentTitle($value)
71
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setScreenName($value)
72
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setLinkId($value)
73
 *
74
 * App Tracking
75
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setApplicationName($value)
76
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setApplicationId($value)
77
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setApplicationVersion($value)
78
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setApplicationInstallerId($value)
79
 *
80
 * Event Tracking
81
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setEventCategory($value)
82
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setEventAction($value)
83
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setEventLabel($value)
84
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setEventValue($value)
85
 *
86
 * E-commerce
87
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setItemName($value)
88
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setItemPrice($value)
89
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setItemQuantity($value)
90
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setItemCode($value)
91
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setItemCategory($value)
92
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setCurrencyCode($value)
93
 *
94
 * Enhanced E-Commerce
95
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setTransactionId($value)
96
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setAffiliation($value)
97
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setRevenue($value)
98
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setTax($value)
99
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setShipping($value)
100
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setCouponCode($value)
101
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setProductActionList($value)
102
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setCheckoutStep($value)
103
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setCheckoutStepOption($value)
104
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics addProduct(array $productData)
105
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setProductAction($value)
106
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setProductActionToDetail()
107
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setProductActionToClick()
108
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setProductActionToAdd()
109
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setProductActionToRemove()
110
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setProductActionToCheckout()
111
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setProductActionToCheckoutOption()
112
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setProductActionToPurchase()
113
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setProductActionToRefund()
114
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setProductImpressionListName($value, $index)
115
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics addProductImpression(array $productData, $index)
116
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics addPromotion(array $promotionData)
117
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setPromotionAction($value)
118
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setPromotionActionToClick()
119
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setPromotionActionToView()
120
 *
121
 * Social Interactions
122
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setSocialNetwork($value)
123
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setSocialAction($value)
124
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setSocialActionTarget($value)
125
 *
126
 * Timing
127
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setUserTimingCategory($value)
128
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setUserTimingVariableName($value)
129
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setUserTimingTime($value)
130
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setUserTimingLabel($value)
131
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setPageLoadTime($value)
132
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setDnsTime($value)
133
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setPageDownloadTime($value)
134
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setRedirectResponseTime($value)
135
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setTcpConnectTime($value)
136
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setServerResponseTime($value)
137
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setDomInteractiveTime($value)
138
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setContentLoadTime($value)
139
 *
140
 * Exceptions
141
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setExceptionDescription($value)
142
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setIsExceptionFatal($value)
143
 *
144
 * Custom Dimension / Metrics
145
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setCustomDimension($value, $index)
146
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setCustomMetric($value, $index)
147
 *
148
 * Content Grouping
149
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setContentGroup($value, $index)
150
 *
151
 * Content Experiments
152
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setExperimentId($value)
153
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setExperimentVariant($value)
154
 *
155
 *
156
 * @package TheIconic\Tracking\GoogleAnalytics
157
 */
158
class Analytics
159
{
160
    /**
161
     * URI scheme for the GA API.
162
     *
163
     * @var string
164
     */
165
    private $uriScheme = 'http';
166
167
    /**
168
     * Indicates if the request to GA will be asynchronous (non-blocking).
169
     *
170
     * @var boolean
171
     */
172
    private $isAsyncRequest = false;
173
174
    /**
175
     * Endpoint to connect to when sending data to GA.
176
     *
177
     * @var string
178
     */
179
    private $endpoint = '://www.google-analytics.com/collect';
180
181
    /**
182
     * Endpoint to connect to when validating hits.
183
     * @link https://developers.google.com/analytics/devguides/collection/protocol/v1/validating-hits
184
     *
185
     * @var string
186
     */
187
    private $debugEndpoint = '://www.google-analytics.com/debug/collect';
188
189
    /**
190
     * Indicates if the request is in debug mode(validating hits).
191
     *
192
     * @var boolean
193
     */
194
    private $isDebug = false;
195
196
    /**
197
     * Holds the single parameters added to the hit.
198
     *
199
     * @var SingleParameter[]
200
     */
201
    private $singleParameters = [];
202
203
    /**
204
     * Holds the compound parameters collections added to the hit.
205
     *
206
     * @var  CompoundParameterCollection[]
207
     */
208
    private $compoundParametersCollections = [];
209
210
    /**
211
     * Holds the HTTP client used to connect to GA.
212
     *
213
     * @var HttpClient
214
     */
215
    private $httpClient;
216
217
    /**
218
     * Initializes to a list of all the available parameters to be sent in a hit.
219
     *
220
     * @var array
221
     */
222
    private $availableParameters = [
223
        'ApplicationId' => 'AppTracking\\ApplicationId',
224
        'ApplicationInstallerId' => 'AppTracking\\ApplicationInstallerId',
225
        'ApplicationName' => 'AppTracking\\ApplicationName',
226
        'ApplicationVersion' => 'AppTracking\\ApplicationVersion',
227
        'ExperimentId' => 'ContentExperiments\\ExperimentId',
228
        'ExperimentVariant' => 'ContentExperiments\\ExperimentVariant',
229
        'ContentGroup' => 'ContentGrouping\\ContentGroup',
230
        'DocumentHostName' => 'ContentInformation\\DocumentHostName',
231
        'DocumentLocationUrl' => 'ContentInformation\\DocumentLocationUrl',
232
        'DocumentPath' => 'ContentInformation\\DocumentPath',
233
        'DocumentTitle' => 'ContentInformation\\DocumentTitle',
234
        'LinkId' => 'ContentInformation\\LinkId',
235
        'ScreenName' => 'ContentInformation\\ScreenName',
236
        'CustomDimension' => 'CustomDimensionsMetrics\\CustomDimension',
237
        'CustomMetric' => 'CustomDimensionsMetrics\\CustomMetric',
238
        'CurrencyCode' => 'Ecommerce\\CurrencyCode',
239
        'ItemCategory' => 'Ecommerce\\ItemCategory',
240
        'ItemCode' => 'Ecommerce\\ItemCode',
241
        'ItemName' => 'Ecommerce\\ItemName',
242
        'ItemPrice' => 'Ecommerce\\ItemPrice',
243
        'ItemQuantity' => 'Ecommerce\\ItemQuantity',
244
        'Affiliation' => 'EnhancedEcommerce\\Affiliation',
245
        'CheckoutStep' => 'EnhancedEcommerce\\CheckoutStep',
246
        'CheckoutStepOption' => 'EnhancedEcommerce\\CheckoutStepOption',
247
        'CouponCode' => 'EnhancedEcommerce\\CouponCode',
248
        'Product' => 'EnhancedEcommerce\\Product',
249
        'ProductAction' => 'EnhancedEcommerce\\ProductAction',
250
        'ProductActionList' => 'EnhancedEcommerce\\ProductActionList',
251
        'ProductCollection' => 'EnhancedEcommerce\\ProductCollection',
252
        'ProductImpression' => 'EnhancedEcommerce\\ProductImpression',
253
        'ProductImpressionCollection' => 'EnhancedEcommerce\\ProductImpressionCollection',
254
        'ProductImpressionListName' => 'EnhancedEcommerce\\ProductImpressionListName',
255
        'Promotion' => 'EnhancedEcommerce\\Promotion',
256
        'PromotionAction' => 'EnhancedEcommerce\\PromotionAction',
257
        'PromotionCollection' => 'EnhancedEcommerce\\PromotionCollection',
258
        'Revenue' => 'EnhancedEcommerce\\Revenue',
259
        'Shipping' => 'EnhancedEcommerce\\Shipping',
260
        'Tax' => 'EnhancedEcommerce\\Tax',
261
        'TransactionId' => 'EnhancedEcommerce\\TransactionId',
262
        'EventAction' => 'Event\\EventAction',
263
        'EventCategory' => 'Event\\EventCategory',
264
        'EventLabel' => 'Event\\EventLabel',
265
        'EventValue' => 'Event\\EventValue',
266
        'ExceptionDescription' => 'Exceptions\\ExceptionDescription',
267
        'IsExceptionFatal' => 'Exceptions\\IsExceptionFatal',
268
        'AnonymizeIp' => 'General\\AnonymizeIp',
269
        'CacheBuster' => 'General\\CacheBuster',
270
        'DataSource' => 'General\\DataSource',
271
        'ProtocolVersion' => 'General\\ProtocolVersion',
272
        'QueueTime' => 'General\\QueueTime',
273
        'TrackingId' => 'General\\TrackingId',
274
        'HitType' => 'Hit\\HitType',
275
        'NonInteractionHit' => 'Hit\\NonInteractionHit',
276
        'GeographicalOverride' => 'Session\\GeographicalOverride',
277
        'IpOverride' => 'Session\\IpOverride',
278
        'SessionControl' => 'Session\\SessionControl',
279
        'UserAgentOverride' => 'Session\\UserAgentOverride',
280
        'SocialAction' => 'SocialInteractions\\SocialAction',
281
        'SocialActionTarget' => 'SocialInteractions\\SocialActionTarget',
282
        'SocialNetwork' => 'SocialInteractions\\SocialNetwork',
283
        'DocumentEncoding' => 'SystemInfo\\DocumentEncoding',
284
        'FlashVersion' => 'SystemInfo\\FlashVersion',
285
        'JavaEnabled' => 'SystemInfo\\JavaEnabled',
286
        'ScreenColors' => 'SystemInfo\\ScreenColors',
287
        'ScreenResolution' => 'SystemInfo\\ScreenResolution',
288
        'UserLanguage' => 'SystemInfo\\UserLanguage',
289
        'ViewportSize' => 'SystemInfo\\ViewportSize',
290
        'ContentLoadTime' => 'Timing\\ContentLoadTime',
291
        'DnsTime' => 'Timing\\DnsTime',
292
        'DomInteractiveTime' => 'Timing\\DomInteractiveTime',
293
        'PageDownloadTime' => 'Timing\\PageDownloadTime',
294
        'PageLoadTime' => 'Timing\\PageLoadTime',
295
        'RedirectResponseTime' => 'Timing\\RedirectResponseTime',
296
        'ServerResponseTime' => 'Timing\\ServerResponseTime',
297
        'TcpConnectTime' => 'Timing\\TcpConnectTime',
298
        'UserTimingCategory' => 'Timing\\UserTimingCategory',
299
        'UserTimingLabel' => 'Timing\\UserTimingLabel',
300
        'UserTimingTime' => 'Timing\\UserTimingTime',
301
        'UserTimingVariableName' => 'Timing\\UserTimingVariableName',
302
        'CampaignContent' => 'TrafficSources\\CampaignContent',
303
        'CampaignId' => 'TrafficSources\\CampaignId',
304
        'CampaignKeyword' => 'TrafficSources\\CampaignKeyword',
305
        'CampaignMedium' => 'TrafficSources\\CampaignMedium',
306
        'CampaignName' => 'TrafficSources\\CampaignName',
307
        'CampaignSource' => 'TrafficSources\\CampaignSource',
308
        'DocumentReferrer' => 'TrafficSources\\DocumentReferrer',
309
        'GoogleAdwordsId' => 'TrafficSources\\GoogleAdwordsId',
310
        'GoogleDisplayAdsId' => 'TrafficSources\\GoogleDisplayAdsId',
311
        'ClientId' => 'User\\ClientId',
312
        'UserId' => 'User\\UserId',
313
    ];
314
315
    /**
316
     * When passed with an argument of TRUE, it will send the hit using HTTPS instead of plain HTTP.
317
     * It parses the available parameters.
318
     *
319
     * @param bool $isSsl
320
     * @throws \InvalidArgumentException
321
     */
322
    public function __construct($isSsl = false)
323
    {
324
        if (!is_bool($isSsl)) {
325
            throw new \InvalidArgumentException('First constructor argument "isSSL" must be boolean');
326
        }
327
328
        if ($isSsl) {
329
            $this->uriScheme .= 's';
330
            $this->endpoint = str_replace('www', 'ssl', $this->endpoint);
331
        }
332
    }
333
334
    /**
335
     * Sets a request to be either synchronous or asynchronous (non-blocking).
336
     *
337
     * @param boolean $isAsyncRequest
338
     * @return $this
339
     */
340
    public function setAsyncRequest($isAsyncRequest)
341
    {
342
        $this->isAsyncRequest = $isAsyncRequest;
343
344
        return $this;
345
    }
346
347
    /**
348
     * Makes the request to GA asynchronous (non-blocking).
349
     *
350
     * @deprecated Use setAsyncRequest(boolean $isAsyncRequest) instead. To be removed in next major version.
351
     *
352
     * @return $this
353
     */
354
    public function makeNonBlocking()
355
    {
356
        $this->isAsyncRequest = true;
357
358
        return $this;
359
    }
360
361
    /**
362
     * Sets the HttpClient.
363
     *
364
     * @param HttpClient $httpClient
365
     * @return $this
366
     */
367
    public function setHttpClient(HttpClient $httpClient)
368
    {
369
        $this->httpClient = $httpClient;
370
371
        return $this;
372
    }
373
374
    /**
375
     * Gets the HttpClient.
376
     *
377
     * @return HttpClient
378
     */
379
    private function getHttpClient()
380
    {
381
        if ($this->httpClient === null) {
382
            // @codeCoverageIgnoreStart
383
            $this->setHttpClient(new HttpClient());
384
        }
385
        // @codeCoverageIgnoreEnd
386
387
        return $this->httpClient;
388
    }
389
390
    /**
391
     * Gets the full endpoint to GA.
392
     *
393
     * @return string
394
     */
395
    private function getEndpoint()
396
    {
397
        return ($this->isDebug)?$this->uriScheme . $this->debugEndpoint:$this->uriScheme . $this->endpoint;
398
    }
399
400
    /**
401
    * Set debug mode true or false
402
    *
403
    */
404
    public function setDebug($value) {
405
      $this->isDebug = $value;
406
      return $this;
407
    }
408
    
409
    /**
410
     * Sends a hit to GA. The hit will contain in the payload all the parameters added before.
411
     *
412
     * @param $methodName
413
     * @return AnalyticsResponse
414
     * @throws Exception\InvalidPayloadDataException
415
     */
416
    private function sendHit($methodName)
417
    {
418
        $hitType = strtoupper(substr($methodName, 4));
419
420
        $hitConstant = $this->getParameterClassConstant(
421
            'TheIconic\Tracking\GoogleAnalytics\Parameters\Hit\HitType::HIT_TYPE_' . $hitType,
422
            'Hit type ' . $hitType . ' is not defined, check spelling'
423
        );
424
425
        $this->setHitType($hitConstant);
426
427
        if (!$this->hasMinimumRequiredParameters()) {
428
            throw new InvalidPayloadDataException();
429
        }
430
431
        return $this->getHttpClient()->post(
432
            $this->getEndpoint(),
433
            $this->singleParameters,
434
            $this->compoundParametersCollections,
435
            $this->isAsyncRequest
436
        );
437
    }
438
439
    /**
440
     * Validates the minimum required parameters for every GA hit are being sent.
441
     *
442
     * @SuppressWarnings(PHPMD.LongVariable)
443
     *
444
     * @return bool
445
     */
446
    private function hasMinimumRequiredParameters()
447
    {
448
        $minimumRequiredParameters = [
449
            'v' => false,
450
            'tid' => false,
451
            'cid' => false,
452
            't' => false,
453
        ];
454
455
        foreach ($minimumRequiredParameters as $parameterName => $isParamPresent) {
456
            if (in_array($parameterName, array_keys($this->singleParameters))) {
457
                $minimumRequiredParameters[$parameterName] = true;
458
            }
459
        }
460
461
        return !in_array(false, $minimumRequiredParameters, true);
462
    }
463
464
    /**
465
     * Sets a parameter action to the value specified by the method call.
466
     *
467
     * @param $parameter
468
     * @param $action
469
     * @return $this
470
     */
471
    private function setParameterActionTo($parameter, $action)
472
    {
473
        $actionConstant = $this->getParameterClassConstant(
474
            'TheIconic\Tracking\GoogleAnalytics\Parameters\EnhancedEcommerce\\'
475
            . $parameter . 'Action::ACTION_' . strtoupper($action),
476
            $parameter . ' action ' . $action . ' does not exist, check spelling'
477
        );
478
479
        $function = 'set' . $parameter . 'Action';
480
481
        $this->$function($actionConstant);
482
483
        return $this;
484
    }
485
486
    /**
487
     * Gets a contant from a class dynamically.
488
     *
489
     * @param $constant
490
     * @param $exceptionMsg
491
     * @return mixed
492
     * @throws \BadMethodCallException
493
     */
494
    private function getParameterClassConstant($constant, $exceptionMsg)
495
    {
496
        if (defined($constant)) {
497
            return constant($constant);
498
        } else {
499
            throw new \BadMethodCallException($exceptionMsg);
500
        }
501
    }
502
503
    /**
504
     * Sets the value for a parameter.
505
     *
506
     * @param $methodName
507
     * @param array $methodArguments
508
     * @return $this
509
     * @throws \InvalidArgumentException
510
     */
511
    private function setParameter($methodName, array $methodArguments)
512
    {
513
        $parameterClass = substr($methodName, 3);
514
515
        $fullParameterClass = $this->getFullParameterClass($parameterClass, $methodName);
516
517
        $parameterIndex = $this->getIndexFromArguments($methodArguments);
518
519
        /** @var SingleParameter $parameterObject */
520
        $parameterObject = new $fullParameterClass($parameterIndex);
521
522
        if (!isset($methodArguments[0])) {
523
            throw new \InvalidArgumentException(
524
                'For Analytics object, you must specify a value to be set for ' . $methodName
525
            );
526
        } else {
527
            $parameterObject->setValue($methodArguments[0]);
528
        }
529
530
        $this->singleParameters[$parameterObject->getName()] = $parameterObject;
531
532
        return $this;
533
    }
534
535
    /**
536
     * Adds an item to a compund parameter collection.
537
     *
538
     * @SuppressWarnings(PHPMD.LongVariable)
539
     *
540
     * @param $methodName
541
     * @param array $methodArguments
542
     * @return $this
543
     * @throws \InvalidArgumentException
544
     */
545
    private function addItem($methodName, array $methodArguments)
546
    {
547
        $parameterClass = substr($methodName, 3);
548
549
        $fullParameterClass = $this->getFullParameterClass($parameterClass, $methodName);
550
551
        if (!isset($methodArguments[0])) {
552
            throw new \InvalidArgumentException(
553
                'You must specify a ' . $parameterClass . ' to be add for ' . $methodName
554
            );
555
        } else {
556
            $parameterObject = new $fullParameterClass($methodArguments[0]);
557
        }
558
559
        $collectionIndex = $this->getIndexFromArguments($methodArguments);
560
561
        if (isset($this->compoundParametersCollections[$parameterClass . $collectionIndex])) {
562
            $this->compoundParametersCollections[$parameterClass . $collectionIndex]->add($parameterObject);
563
        } else {
564
            $fullParameterCollectionClass = $fullParameterClass . 'Collection';
565
566
            /** @var CompoundParameterCollection $parameterObjectCollection */
567
            $parameterObjectCollection = new $fullParameterCollectionClass($collectionIndex);
568
569
            $parameterObjectCollection->add($parameterObject);
570
571
            $this->compoundParametersCollections[$parameterClass . $collectionIndex] = $parameterObjectCollection;
572
        }
573
574
        return $this;
575
    }
576
577
    /**
578
     * Gets the index value from the arguments.
579
     *
580
     * @param $methodArguments
581
     * @return string
582
     */
583
    private function getIndexFromArguments($methodArguments)
584
    {
585
        $index = '';
586
        if (isset($methodArguments[1]) && is_numeric($methodArguments[1])) {
587
            $index = $methodArguments[1];
588
        }
589
590
        return $index;
591
    }
592
593
    /**
594
     * Gets the fully qualified name for a parameter.
595
     *
596
     * @param $parameterClass
597
     * @param $methodName
598
     * @return string
599
     * @throws \BadMethodCallException
600
     */
601
    private function getFullParameterClass($parameterClass, $methodName)
602
    {
603
        if (empty($this->availableParameters[$parameterClass])) {
604
            throw new \BadMethodCallException('Method ' . $methodName . ' not defined for Analytics class');
605
        } else {
606
            return '\\TheIconic\\Tracking\\GoogleAnalytics\\Parameters\\' . $this->availableParameters[$parameterClass];
607
        }
608
    }
609
610
    /**
611
     * Routes the method call to the adequate private method.
612
     *
613
     * @param $methodName
614
     * @param array $methodArguments
615
     * @return $this|AnalyticsResponse
616
     * @throws \BadMethodCallException
617
     */
618
    public function __call($methodName, array $methodArguments)
619
    {
620
        $methodName = $this->fixTypos($methodName);
621
622
        if (preg_match('/^set(Product|Promotion)ActionTo(\w+)/', $methodName, $matches)) {
623
            return $this->setParameterActionTo($matches[1], $matches[2]);
624
        }
625
626
        if (preg_match('/^(set)(\w+)/', $methodName, $matches)) {
627
            return $this->setParameter($methodName, $methodArguments);
628
        }
629
630
        if (preg_match('/^(add)(\w+)/', $methodName, $matches)) {
631
            return $this->addItem($methodName, $methodArguments);
632
        }
633
634
        if (preg_match('/^(send)(\w+)/', $methodName, $matches)) {
635
            return $this->sendHit($methodName);
636
        }
637
638
        throw new \BadMethodCallException('Method ' . $methodName . ' not defined for Analytics class');
639
    }
640
641
    /**
642
     * Fix typos that went into releases, this way we ensure we don't break scripts in production.
643
     *
644
     * @param string $methodName
645
     * @return string
646
     */
647
    private function fixTypos($methodName)
648
    {
649
        // deprecated in v2, to be removed in v3
650
        if ($methodName === 'setUserTiminCategory') {
651
            $methodName = 'setUserTimingCategory';
652
        }
653
654
        return $methodName;
655
    }
656
}
657