Analytics::getIndexFromArguments()   A
last analyzed

Complexity

Conditions 3
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 4
c 0
b 0
f 0
dl 0
loc 8
rs 10
cc 3
nc 2
nop 1
1
<?php
2
3
namespace TheIconic\Tracking\GoogleAnalytics;
4
5
use BadMethodCallException;
6
use TheIconic\Tracking\GoogleAnalytics\Exception\EnqueueUrlsOverflowException;
7
use TheIconic\Tracking\GoogleAnalytics\Exception\InvalidPayloadDataException;
8
use TheIconic\Tracking\GoogleAnalytics\Network\HttpClient;
9
use TheIconic\Tracking\GoogleAnalytics\Network\PrepareUrl;
10
use TheIconic\Tracking\GoogleAnalytics\Parameters\CompoundParameterCollection;
11
use TheIconic\Tracking\GoogleAnalytics\Parameters\SingleParameter;
12
13
/**
14
 * Class Analytics
15
 *
16
 * The main interface for the clients, it relies heavily in magic methods exposing
17
 * an interface with method tags.
18
 *
19
 * ==== SETTERS ====
20
 * General
21
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setProtocolVersion($value)
22
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setTrackingId($value)
23
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setAnonymizeIp($value)
24
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setDataSource($value)
25
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setQueueTime($value)
26
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setCacheBuster($value)
27
 *
28
 * User
29
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setClientId($value)
30
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setUserId($value)
31
 *
32
 * Session
33
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setSessionControl($value)
34
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setIpOverride($value)
35
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setUserAgentOverride($value)
36
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setGeographicalOverride($value)
37
 *
38
 * Traffic Sources
39
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setDocumentReferrer($value)
40
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setCampaignName($value)
41
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setCampaignSource($value)
42
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setCampaignMedium($value)
43
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setCampaignKeyword($value)
44
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setCampaignContent($value)
45
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setCampaignId($value)
46
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setGoogleAdwordsId($value)
47
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setGoogleDisplayAdsId($value)
48
 *
49
 * System Info
50
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setScreenResolution($value)
51
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setViewportSize($value)
52
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setDocumentEncoding($value)
53
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setScreenColors($value)
54
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setUserLanguage($value)
55
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setJavaEnabled($value)
56
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setFlashVersion($value)
57
 *
58
 * Hit
59
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setHitType($value)
60
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setNonInteractionHit($value)
61
 * @method \TheIconic\Tracking\GoogleAnalytics\AnalyticsResponse sendPageview()
62
 * @method \TheIconic\Tracking\GoogleAnalytics\AnalyticsResponse sendEvent()
63
 * @method \TheIconic\Tracking\GoogleAnalytics\AnalyticsResponse sendScreenview()
64
 * @method \TheIconic\Tracking\GoogleAnalytics\AnalyticsResponse sendTransaction()
65
 * @method \TheIconic\Tracking\GoogleAnalytics\AnalyticsResponse sendItem()
66
 * @method \TheIconic\Tracking\GoogleAnalytics\AnalyticsResponse sendSocial()
67
 * @method \TheIconic\Tracking\GoogleAnalytics\AnalyticsResponse sendException()
68
 * @method \TheIconic\Tracking\GoogleAnalytics\AnalyticsResponse sendTiming()
69
 *
70
 * Content Information
71
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setDocumentLocationUrl($value)
72
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setDocumentHostName($value)
73
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setDocumentPath($value)
74
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setDocumentTitle($value)
75
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setScreenName($value)
76
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setLinkId($value)
77
 *
78
 * App Tracking
79
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setApplicationName($value)
80
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setApplicationId($value)
81
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setApplicationVersion($value)
82
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setApplicationInstallerId($value)
83
 *
84
 * Event Tracking
85
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setEventCategory($value)
86
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setEventAction($value)
87
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setEventLabel($value)
88
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setEventValue($value)
89
 *
90
 * E-commerce
91
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setItemName($value)
92
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setItemPrice($value)
93
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setItemQuantity($value)
94
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setItemCode($value)
95
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setItemCategory($value)
96
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setCurrencyCode($value)
97
 *
98
 * Enhanced E-Commerce
99
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setTransactionId($value)
100
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setAffiliation($value)
101
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setRevenue($value)
102
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setTax($value)
103
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setShipping($value)
104
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setCouponCode($value)
105
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setProductActionList($value)
106
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setCheckoutStep($value)
107
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setCheckoutStepOption($value)
108
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics addProduct(array $productData)
109
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setProductAction($value)
110
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setProductActionToDetail()
111
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setProductActionToClick()
112
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setProductActionToAdd()
113
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setProductActionToRemove()
114
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setProductActionToCheckout()
115
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setProductActionToCheckoutOption()
116
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setProductActionToPurchase()
117
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setProductActionToRefund()
118
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setProductImpressionListName($value, $index)
119
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics addProductImpression(array $productData, $index)
120
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics addPromotion(array $promotionData)
121
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setPromotionAction($value)
122
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setPromotionActionToClick()
123
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setPromotionActionToView()
124
 *
125
 * Social Interactions
126
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setSocialNetwork($value)
127
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setSocialAction($value)
128
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setSocialActionTarget($value)
129
 *
130
 * Timing
131
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setUserTimingCategory($value)
132
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setUserTimingVariableName($value)
133
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setUserTimingTime($value)
134
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setUserTimingLabel($value)
135
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setPageLoadTime($value)
136
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setDnsTime($value)
137
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setPageDownloadTime($value)
138
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setRedirectResponseTime($value)
139
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setTcpConnectTime($value)
140
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setServerResponseTime($value)
141
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setDomInteractiveTime($value)
142
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setContentLoadTime($value)
143
 *
144
 * Exceptions
145
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setExceptionDescription($value)
146
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setIsExceptionFatal($value)
147
 *
148
 * Custom Dimension / Metrics
149
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setCustomDimension($value, $index)
150
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setCustomMetric($value, $index)
151
 *
152
 * Content Grouping
153
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setContentGroup($value, $index)
154
 *
155
 * Content Experiments
156
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setExperimentId($value)
157
 * @method \TheIconic\Tracking\GoogleAnalytics\Analytics setExperimentVariant($value)
158
 *
159
 * ==== GETTERS ====
160
 * General
161
 * @method string|int|null getProtocolVersion()
162
 * @method string|int|null getTrackingId()
163
 * @method string|int|null getAnonymizeIp()
164
 * @method string|int|null getDataSource()
165
 * @method string|int|null getQueueTime()
166
 * @method string|int|null getCacheBuster()
167
 *
168
 * User
169
 * @method string|int|null getClientId()
170
 * @method string|int|null getUserId()
171
 *
172
 * Session
173
 * @method string|int|null getSessionControl()
174
 * @method string|int|null getIpOverride()
175
 * @method string|int|null getUserAgentOverride()
176
 * @method string|int|null getGeographicalOverride()
177
 *
178
 * Traffic Sources
179
 * @method string|int|null getDocumentReferrer()
180
 * @method string|int|null getCampaignName()
181
 * @method string|int|null getCampaignSource()
182
 * @method string|int|null getCampaignMedium()
183
 * @method string|int|null getCampaignKeyword()
184
 * @method string|int|null getCampaignContent()
185
 * @method string|int|null getCampaignId()
186
 * @method string|int|null getGoogleAdwordsId()
187
 * @method string|int|null getGoogleDisplayAdsId()
188
 *
189
 * System Info
190
 * @method string|int|null getScreenResolution()
191
 * @method string|int|null getViewportSize()
192
 * @method string|int|null getDocumentEncoding()
193
 * @method string|int|null getScreenColors()
194
 * @method string|int|null getUserLanguage()
195
 * @method string|int|null getJavaEnabled()
196
 * @method string|int|null getFlashVersion()
197
 *
198
 * Hit
199
 * @method string|int|null getHitType()
200
 * @method string|int|null getNonInteractionHit()
201
 *
202
 * Content Information
203
 * @method string|int|null getDocumentLocationUrl()
204
 * @method string|int|null getDocumentHostName()
205
 * @method string|int|null getDocumentPath()
206
 * @method string|int|null getDocumentTitle()
207
 * @method string|int|null getScreenName()
208
 * @method string|int|null getLinkId()
209
 *
210
 * App Tracking
211
 * @method string|int|null getApplicationName()
212
 * @method string|int|null getApplicationId()
213
 * @method string|int|null getApplicationVersion()
214
 * @method string|int|null getApplicationInstallerId()
215
 *
216
 * Event Tracking
217
 * @method string|int|null getEventCategory()
218
 * @method string|int|null getEventAction()
219
 * @method string|int|null getEventLabel()
220
 * @method string|int|null getEventValue()
221
 *
222
 * E-commerce
223
 * @method string|int|null getItemName()
224
 * @method string|int|null getItemPrice()
225
 * @method string|int|null getItemQuantity()
226
 * @method string|int|null getItemCode()
227
 * @method string|int|null getItemCategory()
228
 * @method string|int|null getCurrencyCode()
229
 *
230
 * Enhanced E-Commerce
231
 * @method string|int|null getTransactionId()
232
 * @method string|int|null getAffiliation()
233
 * @method string|int|null getRevenue()
234
 * @method string|int|null getTax()
235
 * @method string|int|null getShipping()
236
 * @method string|int|null getCouponCode()
237
 * @method string|int|null getProductActionList()
238
 * @method string|int|null getCheckoutStep()
239
 * @method string|int|null getCheckoutStepOption()
240
 * @method string|int|null getProduct()
241
 * @method string|int|null getProductAction()
242
 * @method string|int|null getProductActionToDetail()
243
 * @method string|int|null getProductActionToClick()
244
 * @method string|int|null getProductActionToAdd()
245
 * @method string|int|null getProductActionToRemove()
246
 * @method string|int|null getProductActionToCheckout()
247
 * @method string|int|null getProductActionToCheckoutOption()
248
 * @method string|int|null getProductActionToPurchase()
249
 * @method string|int|null getProductActionToRefund()
250
 * @method string|int|null getProductImpressionListName($index)
251
 * @method string|int|null getProductImpression($listIndex)
252
 * @method string|int|null getPromotion()
253
 * @method string|int|null getPromotionAction()
254
 * @method string|int|null getPromotionActionToClick()
255
 * @method string|int|null getPromotionActionToView()
256
 *
257
 * Social Interactions
258
 * @method string|int|null getSocialNetwork()
259
 * @method string|int|null getSocialAction()
260
 * @method string|int|null getSocialActionTarget()
261
 *
262
 * Timing
263
 * @method string|int|null getUserTimingCategory()
264
 * @method string|int|null getUserTimingVariableName()
265
 * @method string|int|null getUserTimingTime()
266
 * @method string|int|null getUserTimingLabel()
267
 * @method string|int|null getPageLoadTime()
268
 * @method string|int|null getDnsTime()
269
 * @method string|int|null getPageDownloadTime()
270
 * @method string|int|null getRedirectResponseTime()
271
 * @method string|int|null getTcpConnectTime()
272
 * @method string|int|null getServerResponseTime()
273
 * @method string|int|null getDomInteractiveTime()
274
 * @method string|int|null getContentLoadTime()
275
 *
276
 * Exceptions
277
 * @method string|int|null getExceptionDescription()
278
 * @method string|int|null getIsExceptionFatal()
279
 *
280
 * Custom Dimension / Metrics
281
 * @method string|int|null getCustomDimension($index)
282
 * @method string|int|null getCustomMetric($index)
283
 *
284
 * Content Grouping
285
 * @method string|int|null getContentGroup($index)
286
 *
287
 * Content Experiments
288
 * @method string|int|null getExperimentId()
289
 * @method string|int|null getExperimentVariant()
290
 *
291
 * @package TheIconic\Tracking\GoogleAnalytics
292
 */
293
class Analytics
294
{
295
    /**
296
     * URI scheme for the GA API.
297
     *
298
     * @var string
299
     */
300
    protected $uriScheme = 'http';
301
302
    /**
303
     * Indicates if the request to GA will be asynchronous (non-blocking).
304
     *
305
     * @var boolean
306
     */
307
    protected $isAsyncRequest = false;
308
309
    /**
310
     * Endpoint to connect to when sending data to GA.
311
     *
312
     * @var string
313
     */
314
    protected $endpoint = '://www.google-analytics.com/collect';
315
316
    /**
317
     * Endpoint to connect to when validating hits.
318
     * @link https://developers.google.com/analytics/devguides/collection/protocol/v1/validating-hits
319
     *
320
     * @var string
321
     */
322
    protected $debugEndpoint = '://www.google-analytics.com/debug/collect';
323
324
    /**
325
     * Endpoint to connect to when sending batch data to GA.
326
     *
327
     * @var string
328
     */
329
    protected $batchEndpoint = '://www.google-analytics.com/batch';
330
     
331
332
    /**
333
     * Indicates if the request is in debug mode(validating hits).
334
     *
335
     * @var boolean
336
     */
337
    protected $isDebug = false;
338
339
    /**
340
     * Holds the single parameters added to the hit.
341
     *
342
     * @var SingleParameter[]
343
     */
344
    protected $singleParameters = [];
345
346
    /**
347
     * Holds the compound parameters collections added to the hit.
348
     *
349
     * @var  CompoundParameterCollection[]
350
     */
351
    protected $compoundParametersCollections = [];
352
353
    /**
354
     * Holds the HTTP client used to connect to GA.
355
     *
356
     * @var HttpClient
357
     */
358
    protected $httpClient;
359
360
    /**
361
     * Indicates if the request to GA will be executed (by default) or not.
362
     *
363
     * @var boolean
364
     */
365
    protected $isDisabled = false;
366
367
    /**
368
     * @var array
369
     */
370
    protected $enqueuedUrls = [];
371
372
    /**
373
     * @var array
374
     */
375
    protected $options = [];
376
    
377
    /**
378
     * Initializes to a list of all the available parameters to be sent in a hit.
379
     *
380
     * @var array
381
     */
382
    protected $availableParameters = [
383
        'ApplicationId' => 'AppTracking\\ApplicationId',
384
        'ApplicationInstallerId' => 'AppTracking\\ApplicationInstallerId',
385
        'ApplicationName' => 'AppTracking\\ApplicationName',
386
        'ApplicationVersion' => 'AppTracking\\ApplicationVersion',
387
        'ExperimentId' => 'ContentExperiments\\ExperimentId',
388
        'ExperimentVariant' => 'ContentExperiments\\ExperimentVariant',
389
        'ContentGroup' => 'ContentGrouping\\ContentGroup',
390
        'DocumentHostName' => 'ContentInformation\\DocumentHostName',
391
        'DocumentLocationUrl' => 'ContentInformation\\DocumentLocationUrl',
392
        'DocumentPath' => 'ContentInformation\\DocumentPath',
393
        'DocumentTitle' => 'ContentInformation\\DocumentTitle',
394
        'LinkId' => 'ContentInformation\\LinkId',
395
        'ScreenName' => 'ContentInformation\\ScreenName',
396
        'CustomDimension' => 'CustomDimensionsMetrics\\CustomDimension',
397
        'CustomMetric' => 'CustomDimensionsMetrics\\CustomMetric',
398
        'CurrencyCode' => 'Ecommerce\\CurrencyCode',
399
        'ItemCategory' => 'Ecommerce\\ItemCategory',
400
        'ItemCode' => 'Ecommerce\\ItemCode',
401
        'ItemName' => 'Ecommerce\\ItemName',
402
        'ItemPrice' => 'Ecommerce\\ItemPrice',
403
        'ItemQuantity' => 'Ecommerce\\ItemQuantity',
404
        'Affiliation' => 'EnhancedEcommerce\\Affiliation',
405
        'CheckoutStep' => 'EnhancedEcommerce\\CheckoutStep',
406
        'CheckoutStepOption' => 'EnhancedEcommerce\\CheckoutStepOption',
407
        'CouponCode' => 'EnhancedEcommerce\\CouponCode',
408
        'Product' => 'EnhancedEcommerce\\Product',
409
        'ProductAction' => 'EnhancedEcommerce\\ProductAction',
410
        'ProductActionList' => 'EnhancedEcommerce\\ProductActionList',
411
        'ProductCollection' => 'EnhancedEcommerce\\ProductCollection',
412
        'ProductImpression' => 'EnhancedEcommerce\\ProductImpression',
413
        'ProductImpressionCollection' => 'EnhancedEcommerce\\ProductImpressionCollection',
414
        'ProductImpressionListName' => 'EnhancedEcommerce\\ProductImpressionListName',
415
        'Promotion' => 'EnhancedEcommerce\\Promotion',
416
        'PromotionAction' => 'EnhancedEcommerce\\PromotionAction',
417
        'PromotionCollection' => 'EnhancedEcommerce\\PromotionCollection',
418
        'Revenue' => 'EnhancedEcommerce\\Revenue',
419
        'Shipping' => 'EnhancedEcommerce\\Shipping',
420
        'Tax' => 'EnhancedEcommerce\\Tax',
421
        'TransactionId' => 'EnhancedEcommerce\\TransactionId',
422
        'EventAction' => 'Event\\EventAction',
423
        'EventCategory' => 'Event\\EventCategory',
424
        'EventLabel' => 'Event\\EventLabel',
425
        'EventValue' => 'Event\\EventValue',
426
        'ExceptionDescription' => 'Exceptions\\ExceptionDescription',
427
        'IsExceptionFatal' => 'Exceptions\\IsExceptionFatal',
428
        'AnonymizeIp' => 'General\\AnonymizeIp',
429
        'CacheBuster' => 'General\\CacheBuster',
430
        'DataSource' => 'General\\DataSource',
431
        'ProtocolVersion' => 'General\\ProtocolVersion',
432
        'QueueTime' => 'General\\QueueTime',
433
        'TrackingId' => 'General\\TrackingId',
434
        'HitType' => 'Hit\\HitType',
435
        'NonInteractionHit' => 'Hit\\NonInteractionHit',
436
        'GeographicalOverride' => 'Session\\GeographicalOverride',
437
        'IpOverride' => 'Session\\IpOverride',
438
        'SessionControl' => 'Session\\SessionControl',
439
        'UserAgentOverride' => 'Session\\UserAgentOverride',
440
        'SocialAction' => 'SocialInteractions\\SocialAction',
441
        'SocialActionTarget' => 'SocialInteractions\\SocialActionTarget',
442
        'SocialNetwork' => 'SocialInteractions\\SocialNetwork',
443
        'DocumentEncoding' => 'SystemInfo\\DocumentEncoding',
444
        'FlashVersion' => 'SystemInfo\\FlashVersion',
445
        'JavaEnabled' => 'SystemInfo\\JavaEnabled',
446
        'ScreenColors' => 'SystemInfo\\ScreenColors',
447
        'ScreenResolution' => 'SystemInfo\\ScreenResolution',
448
        'UserLanguage' => 'SystemInfo\\UserLanguage',
449
        'ViewportSize' => 'SystemInfo\\ViewportSize',
450
        'ContentLoadTime' => 'Timing\\ContentLoadTime',
451
        'DnsTime' => 'Timing\\DnsTime',
452
        'DomInteractiveTime' => 'Timing\\DomInteractiveTime',
453
        'PageDownloadTime' => 'Timing\\PageDownloadTime',
454
        'PageLoadTime' => 'Timing\\PageLoadTime',
455
        'RedirectResponseTime' => 'Timing\\RedirectResponseTime',
456
        'ServerResponseTime' => 'Timing\\ServerResponseTime',
457
        'TcpConnectTime' => 'Timing\\TcpConnectTime',
458
        'UserTimingCategory' => 'Timing\\UserTimingCategory',
459
        'UserTimingLabel' => 'Timing\\UserTimingLabel',
460
        'UserTimingTime' => 'Timing\\UserTimingTime',
461
        'UserTimingVariableName' => 'Timing\\UserTimingVariableName',
462
        'CampaignContent' => 'TrafficSources\\CampaignContent',
463
        'CampaignId' => 'TrafficSources\\CampaignId',
464
        'CampaignKeyword' => 'TrafficSources\\CampaignKeyword',
465
        'CampaignMedium' => 'TrafficSources\\CampaignMedium',
466
        'CampaignName' => 'TrafficSources\\CampaignName',
467
        'CampaignSource' => 'TrafficSources\\CampaignSource',
468
        'DocumentReferrer' => 'TrafficSources\\DocumentReferrer',
469
        'GoogleAdwordsId' => 'TrafficSources\\GoogleAdwordsId',
470
        'GoogleDisplayAdsId' => 'TrafficSources\\GoogleDisplayAdsId',
471
        'ClientId' => 'User\\ClientId',
472
        'UserId' => 'User\\UserId',
473
    ];
474
475
    /**
476
     * When passed with an argument of TRUE, it will send the hit using HTTPS instead of plain HTTP.
477
     * It parses the available parameters.
478
     *
479
     * @param bool $isSsl
480
     * @param bool $isDisabled
481
     * @param array $options
482
     * @throws \InvalidArgumentException
483
     */
484
    public function __construct($isSsl = false, $isDisabled = false, array $options = [])
485
    {
486
        if (!is_bool($isSsl)) {
0 ignored issues
show
introduced by
The condition is_bool($isSsl) is always true.
Loading history...
487
            throw new \InvalidArgumentException('First constructor argument "isSSL" must be boolean');
488
        }
489
490
        if (!is_bool($isDisabled)) {
0 ignored issues
show
introduced by
The condition is_bool($isDisabled) is always true.
Loading history...
491
            throw new \InvalidArgumentException('Second constructor argument "isDisabled" must be boolean');
492
        }
493
494
        if ($isSsl) {
495
            $this->uriScheme .= 's';
496
            $this->endpoint = str_replace('www', 'ssl', $this->endpoint);
497
        }
498
499
        $this->isDisabled = $isDisabled;
500
        $this->options = $options;
501
    }
502
503
    /**
504
     * Sets a request to be either synchronous or asynchronous (non-blocking).
505
     *
506
     * @api
507
     * @param boolean $isAsyncRequest
508
     * @return $this
509
     */
510
    public function setAsyncRequest($isAsyncRequest)
511
    {
512
        $this->isAsyncRequest = $isAsyncRequest;
513
514
        return $this;
515
    }
516
517
    /**
518
     * Makes the request to GA asynchronous (non-blocking).
519
     *
520
     * @deprecated Use setAsyncRequest(boolean $isAsyncRequest) instead. To be removed in next major version.
521
     *
522
     * @return $this
523
     */
524
    public function makeNonBlocking()
525
    {
526
        $this->isAsyncRequest = true;
527
528
        return $this;
529
    }
530
531
    /**
532
     * Sets the HttpClient.
533
     *
534
     * @internal
535
     * @param HttpClient $httpClient
536
     * @return $this
537
     */
538
    public function setHttpClient(HttpClient $httpClient)
539
    {
540
        $this->httpClient = $httpClient;
541
542
        return $this;
543
    }
544
545
    /**
546
     * Gets the HttpClient.
547
     *
548
     * @return HttpClient
549
     */
550
    protected function getHttpClient()
551
    {
552
        if ($this->httpClient === null) {
553
            // @codeCoverageIgnoreStart
554
            $this->setHttpClient(new HttpClient());
555
        }
556
        // @codeCoverageIgnoreEnd
557
558
        return $this->httpClient;
559
    }
560
561
    /**
562
     * Gets the full endpoint to GA.
563
     *
564
     * @return string
565
     */
566
    protected function getEndpoint()
567
    {
568
        return ($this->isDebug) ? $this->uriScheme . $this->debugEndpoint : $this->uriScheme . $this->endpoint;
569
    }
570
571
    /**
572
     * Gets the full batch endpoint to GA.
573
     *
574
     * @return string
575
     */
576
    protected function getBatchEndpoint()
577
    {
578
        return $this->uriScheme . $this->batchEndpoint;
579
    }
580
581
    /**
582
     * Sets debug mode to true or false.
583
     *
584
     * @api
585
     * @param bool $value
586
     * @return \TheIconic\Tracking\GoogleAnalytics\Analytics
587
     */
588
    public function setDebug($value)
589
    {
590
        $this->isDebug = $value;
591
592
        return $this;
593
    }
594
595
    /**
596
     * Sends a hit to GA. The hit will contain in the payload all the parameters added before.
597
     *
598
     * @param $methodName
599
     * @return AnalyticsResponseInterface
600
     * @throws Exception\InvalidPayloadDataException
601
     */
602
    protected function sendHit($methodName)
603
    {
604
        $hitType = strtoupper(substr($methodName, 4));
605
606
        $this->setAndValidateHit($hitType);
607
608
        if ($this->isDisabled) {
609
            return new NullAnalyticsResponse();
610
        }
611
612
        return $this->getHttpClient()->post($this->getUrl(), $this->getHttpClientOptions());
613
    }
614
615
    /**
616
     * Enqueue a hit to GA. The hit will contain in the payload all the parameters added before.
617
     *
618
     * @param $methodName
619
     * @return $this
620
     * @throws Exception\InvalidPayloadDataException
621
     */
622
    protected function enqueueHit($methodName)
623
    {
624
625
        if(count($this->enqueuedUrls) == 20) {
626
            throw new EnqueueUrlsOverflowException();
627
        }
628
629
        $hitType = strtoupper(substr($methodName, 7));
630
631
        $this->setAndValidateHit($hitType);
632
        $this->enqueuedUrls[] = $this->getUrl(true);
633
634
        return $this;
635
    }
636
637
    /**
638
     * Validate and set hitType
639
     *
640
     * @param $methodName
641
     * @return void
642
     * @throws Exception\InvalidPayloadDataException
643
     */
644
    protected function setAndValidateHit($hitType)
645
    {
646
        
647
        $hitConstant = $this->getParameterClassConstant(
648
            'TheIconic\Tracking\GoogleAnalytics\Parameters\Hit\HitType::HIT_TYPE_' . $hitType,
649
            'Hit type ' . $hitType . ' is not defined, check spelling'
650
        );
651
652
        $this->setHitType($hitConstant);
653
654
        if (!$this->hasMinimumRequiredParameters()) {
655
            throw new InvalidPayloadDataException();
656
        }
657
    }
658
659
    /**
660
     * Sends enqueued hits to GA. These hits will contain in the payload all the parameters added before.
661
     *
662
     * @return AnalyticsResponseInterface
663
     */
664
    public function sendEnqueuedHits()
665
    {
666
        if ($this->isDisabled) {
667
            return new NullAnalyticsResponse();
668
        }
669
670
        $response = $this->getHttpClient()->batch($this->getBatchEndpoint(), $this->enqueuedUrls, $this->getHttpClientOptions());
671
672
        $this->emptyQueue();
673
674
        return $response;
675
    }
676
677
    /**
678
     * Build the options array for the http client based on the Analytics object options.
679
     *
680
     * @return array
681
     */
682
    protected function getHttpClientOptions()
683
    {
684
        $options = ['async' => $this->isAsyncRequest];
685
686
        if (isset($this->options['timeout'])) {
687
            $options['timeout'] = $this->options['timeout'];
688
        }
689
690
        return $options;
691
    }
692
693
    /**
694
     * Build and returns URL used to send to Google Analytics.
695
     *
696
     * @api
697
     * @return string
698
     */
699
    public function getUrl($onlyQuery = false)
700
    {
701
        $prepareUrl = new PrepareUrl;
702
703
        return $prepareUrl->build(
704
            $this->getEndpoint(),
705
            $this->singleParameters,
706
            $this->compoundParametersCollections,
707
            $onlyQuery
708
        );
709
    }
710
711
    /**
712
     * Validates the minimum required parameters for every GA hit are being sent.
713
     *
714
     * @SuppressWarnings(PHPMD.LongVariable)
715
     *
716
     * @return bool
717
     */
718
    protected function hasMinimumRequiredParameters()
719
    {
720
        $minimumRequiredParameters = [
721
            'v' => false,
722
            'tid' => false,
723
            'cid' => false,
724
            'uid' => false,
725
            't' => false,
726
        ];
727
728
        foreach ($minimumRequiredParameters as $parameterName => $isParamPresent) {
729
            if (array_key_exists($parameterName, $this->singleParameters)) {
730
                $minimumRequiredParameters[$parameterName] = true;
731
            }
732
        }
733
734
        if (!$minimumRequiredParameters['cid'] && $minimumRequiredParameters['uid']) {
735
            $minimumRequiredParameters['cid'] = true;
736
        }
737
738
        if (!$minimumRequiredParameters['uid'] && $minimumRequiredParameters['cid']) {
739
            $minimumRequiredParameters['uid'] = true;
740
        }
741
742
        return !in_array(false, $minimumRequiredParameters, true);
743
    }
744
745
    /**
746
     * Sets a parameter action to the value specified by the method call.
747
     *
748
     * @param $parameter
749
     * @param $action
750
     * @return $this
751
     */
752
    protected function setParameterActionTo($parameter, $action)
753
    {
754
        $actionConstant = $this->getParameterClassConstant(
755
            'TheIconic\Tracking\GoogleAnalytics\Parameters\EnhancedEcommerce\\'
756
            . $parameter . 'Action::ACTION_' . strtoupper($action),
757
            $parameter . ' action ' . $action . ' does not exist, check spelling'
758
        );
759
760
        $function = 'set' . $parameter . 'Action';
761
762
        $this->$function($actionConstant);
763
764
        return $this;
765
    }
766
767
    /**
768
     * Gets a contant from a class dynamically.
769
     *
770
     * @param $constant
771
     * @param $exceptionMsg
772
     * @return mixed
773
     * @throws BadMethodCallException
774
     */
775
    protected function getParameterClassConstant($constant, $exceptionMsg)
776
    {
777
        if (defined($constant)) {
778
            return constant($constant);
779
        } else {
780
            throw new BadMethodCallException($exceptionMsg);
781
        }
782
    }
783
784
    /**
785
     * Sets the value for a parameter.
786
     *
787
     * @param $methodName
788
     * @param array $methodArguments
789
     * @return $this
790
     * @throws \InvalidArgumentException
791
     */
792
    protected function setParameter($methodName, array $methodArguments)
793
    {
794
        $parameterClass = substr($methodName, 3);
795
796
        $fullParameterClass = $this->getFullParameterClass($parameterClass, $methodName);
797
798
        $parameterIndex = $this->getIndexFromArguments($methodArguments);
799
800
        /** @var SingleParameter $parameterObject */
801
        $parameterObject = new $fullParameterClass($parameterIndex);
802
803
        if (!isset($methodArguments[0])) {
804
            throw new \InvalidArgumentException(
805
                'For Analytics object, you must specify a value to be set for ' . $methodName
806
            );
807
        } else {
808
            $parameterObject->setValue($methodArguments[0]);
809
        }
810
811
        $this->singleParameters[$parameterObject->getName()] = $parameterObject;
812
813
        return $this;
814
    }
815
816
    /**
817
     * Adds an item to a compund parameter collection.
818
     *
819
     * @SuppressWarnings(PHPMD.LongVariable)
820
     *
821
     * @param $methodName
822
     * @param array $methodArguments
823
     * @return $this
824
     * @throws \InvalidArgumentException
825
     */
826
    protected function addItem($methodName, array $methodArguments)
827
    {
828
        $parameterClass = substr($methodName, 3);
829
830
        $fullParameterClass = $this->getFullParameterClass($parameterClass, $methodName);
831
832
        if (!isset($methodArguments[0])) {
833
            throw new \InvalidArgumentException(
834
                'You must specify a ' . $parameterClass . ' to be add for ' . $methodName
835
            );
836
        } else {
837
            $parameterObject = new $fullParameterClass($methodArguments[0]);
838
        }
839
840
        $collectionIndex = $this->getIndexFromArguments($methodArguments);
841
842
        $parameterIndex = $parameterClass . $collectionIndex;
843
        if (isset($this->compoundParametersCollections[$parameterIndex])) {
844
            $this->compoundParametersCollections[$parameterIndex]->add($parameterObject);
845
        } else {
846
            $fullParameterCollectionClass = $fullParameterClass . 'Collection';
847
848
            /** @var CompoundParameterCollection $parameterObjectCollection */
849
            $parameterObjectCollection = new $fullParameterCollectionClass($collectionIndex);
850
851
            $parameterObjectCollection->add($parameterObject);
852
853
            $this->compoundParametersCollections[$parameterIndex] = $parameterObjectCollection;
854
        }
855
856
        return $this;
857
    }
858
859
    /**
860
     * Gets the value for a parameter.
861
     *
862
     * @SuppressWarnings(PHPMD.LongVariable)
863
     *
864
     * @param $methodName
865
     * @param array $methodArguments
866
     * @return string
867
     * @throws \InvalidArgumentException
868
     */
869
    protected function getParameter($methodName, array $methodArguments)
870
    {
871
        $parameterClass = substr($methodName, 3);
872
873
        $fullParameterClass = $this->getFullParameterClass($parameterClass, $methodName);
874
875
        // Handle index arguments
876
        $parameterIndex = '';
877
        if (isset($methodArguments[0]) && is_numeric($methodArguments[0])) {
878
            $parameterIndex = $methodArguments[0];
879
        }
880
881
        // Handle compoundParametersCollections
882
        if (isset($this->compoundParametersCollections[$parameterClass . $parameterIndex])) {
883
            // If compoundParametersCollections contains our Objects, return them well-formatted
884
            return $this->compoundParametersCollections[$parameterClass . $parameterIndex]->getReadableItems();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->compoundPa...ex]->getReadableItems() returns the type array which is incompatible with the documented return type string.
Loading history...
885
        } else {
886
            $fullParameterCollectionClass = $fullParameterClass . 'Collection';
887
888
            // Test if the class Collection exist
889
            if (class_exists($fullParameterCollectionClass, false)) {
890
                return null;
891
            }
892
            // If not, it's a SingleParameter Object, continue the magic
893
        }
894
895
        /** @var SingleParameter $parameterObject */
896
        $parameterObject = new $fullParameterClass($parameterIndex);
897
898
        if (!array_key_exists($parameterObject->getName(), $this->singleParameters)) {
899
            return null;
900
        }
901
902
        $currentParameterObject = $this->singleParameters[$parameterObject->getName()];
903
904
        return $currentParameterObject->getValue();
905
906
    }
907
908
    /**
909
     * Gets the index value from the arguments.
910
     *
911
     * @param $methodArguments
912
     * @return string
913
     */
914
    protected function getIndexFromArguments($methodArguments)
915
    {
916
        $index = '';
917
        if (isset($methodArguments[1]) && is_numeric($methodArguments[1])) {
918
            $index = $methodArguments[1];
919
        }
920
921
        return $index;
922
    }
923
924
    /**
925
     * Gets the fully qualified name for a parameter.
926
     *
927
     * @param $parameterClass
928
     * @param $methodName
929
     * @return string
930
     * @throws BadMethodCallException
931
     */
932
    protected function getFullParameterClass($parameterClass, $methodName)
933
    {
934
        if (empty($this->availableParameters[$parameterClass])) {
935
            throw new BadMethodCallException('Method ' . $methodName . ' not defined for Analytics class');
936
        }
937
938
        return '\\TheIconic\\Tracking\\GoogleAnalytics\\Parameters\\' . $this->availableParameters[$parameterClass];
939
    }
940
941
    /**
942
     * Empty batch queue
943
     *
944
     * @return $this
945
     */
946
    public function emptyQueue()
947
    {
948
        $this->enqueuedUrls = [];
949
950
        return $this;
951
    }
952
953
    /**
954
     * Routes the method call to the adequate protected method.
955
     *
956
     * @param $methodName
957
     * @param array $methodArguments
958
     * @return mixed
959
     * @throws BadMethodCallException
960
     */
961
    public function __call($methodName, array $methodArguments)
962
    {
963
        $methodName = $this->fixTypos($methodName);
964
965
        if (preg_match('/^set(Product|Promotion)ActionTo(\w+)/', $methodName, $matches)) {
966
            return $this->setParameterActionTo($matches[1], $matches[2]);
967
        }
968
969
        if (preg_match('/^(set)(\w+)/', $methodName, $matches)) {
970
            return $this->setParameter($methodName, $methodArguments);
971
        }
972
973
        if (preg_match('/^(add)(\w+)/', $methodName, $matches)) {
974
            return $this->addItem($methodName, $methodArguments);
975
        }
976
977
        if (preg_match('/^(send)(\w+)/', $methodName, $matches)) {
978
            return $this->sendHit($methodName);
979
        }
980
981
        if (preg_match('/^(enqueue)(\w+)/', $methodName, $matches)) {
982
            return $this->enqueueHit($methodName);
983
        }
984
985
        // Get Parameters
986
        if (preg_match('/^(get)(\w+)/', $methodName, $matches)) {
987
            return $this->getParameter($methodName, $methodArguments);
988
        }
989
990
        throw new BadMethodCallException('Method ' . $methodName . ' not defined for Analytics class');
991
    }
992
993
    /**
994
     * Fix typos that went into releases, this way we ensure we don't break scripts in production.
995
     *
996
     * @param string $methodName
997
     * @return string
998
     */
999
    protected function fixTypos($methodName)
1000
    {
1001
        // @TODO deprecated in v2, to be removed in v3
1002
        if ($methodName === 'setUserTiminCategory') {
1003
            $methodName = 'setUserTimingCategory';
1004
        }
1005
1006
        return $methodName;
1007
    }
1008
}
1009