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
Pull Request — master (#41)
by John
04:24
created

Analytics::getHttpClientOptions()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

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

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
805
        } else {
806
            $fullParameterCollectionClass = $fullParameterClass . 'Collection';
807
808
            // Test if the class Collection exist
809
            if (class_exists($fullParameterCollectionClass)) {
810
                return null;
811
            }
812
            // If not, it's a SingleParameter Object, continue the magic
813
        }
814
815
        /** @var SingleParameter $parameterObject */
816
        $parameterObject = new $fullParameterClass($parameterIndex);
817
818
        if (!array_key_exists($parameterObject->getName(), $this->singleParameters)) {
819
            return null;
820
        }
821
822
        $currentParameterObject = $this->singleParameters[$parameterObject->getName()];
823
824
        return $currentParameterObject->getValue();
825
826
    }
827
828
    /**
829
     * Gets the index value from the arguments.
830
     *
831
     * @param $methodArguments
832
     * @return string
833
     */
834
    protected function getIndexFromArguments($methodArguments)
835
    {
836
        $index = '';
837
        if (isset($methodArguments[1]) && is_numeric($methodArguments[1])) {
838
            $index = $methodArguments[1];
839
        }
840
841
        return $index;
842
    }
843
844
    /**
845
     * Gets the fully qualified name for a parameter.
846
     *
847
     * @param $parameterClass
848
     * @param $methodName
849
     * @return string
850
     * @throws \BadMethodCallException
851
     */
852
    protected function getFullParameterClass($parameterClass, $methodName)
853
    {
854
        if (empty($this->availableParameters[$parameterClass])) {
855
            throw new \BadMethodCallException('Method ' . $methodName . ' not defined for Analytics class');
856
        } else {
857
            return '\\TheIconic\\Tracking\\GoogleAnalytics\\Parameters\\' . $this->availableParameters[$parameterClass];
858
        }
859
    }
860
861
    /**
862
     * Routes the method call to the adequate protected method.
863
     *
864
     * @param $methodName
865
     * @param array $methodArguments
866
     * @return mixed
867
     * @throws \BadMethodCallException
868
     */
869
    public function __call($methodName, array $methodArguments)
870
    {
871
        $methodName = $this->fixTypos($methodName);
872
873
        if (preg_match('/^set(Product|Promotion)ActionTo(\w+)/', $methodName, $matches)) {
874
            return $this->setParameterActionTo($matches[1], $matches[2]);
875
        }
876
877
        if (preg_match('/^(set)(\w+)/', $methodName, $matches)) {
878
            return $this->setParameter($methodName, $methodArguments);
879
        }
880
881
        if (preg_match('/^(add)(\w+)/', $methodName, $matches)) {
882
            return $this->addItem($methodName, $methodArguments);
883
        }
884
885
        if (preg_match('/^(send)(\w+)/', $methodName, $matches)) {
886
            return $this->sendHit($methodName);
887
        }
888
889
        // Get Parameters
890
        if (preg_match('/^(get)(\w+)/', $methodName, $matches)) {
891
            return $this->getParameter($methodName, $methodArguments);
892
        }
893
894
        throw new \BadMethodCallException('Method ' . $methodName . ' not defined for Analytics class');
895
    }
896
897
    /**
898
     * Fix typos that went into releases, this way we ensure we don't break scripts in production.
899
     *
900
     * @param string $methodName
901
     * @return string
902
     */
903
    protected function fixTypos($methodName)
904
    {
905
        // @TODO deprecated in v2, to be removed in v3
906
        if ($methodName === 'setUserTiminCategory') {
907
            $methodName = 'setUserTimingCategory';
908
        }
909
910
        return $methodName;
911
    }
912
}
913