├── .editorconfig
├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── composer.json
├── phpunit.xml
├── src
├── Ipunkt
│ └── LaravelAnalytics
│ │ ├── AnalyticsFacade.php
│ │ ├── AnalyticsServiceProvider.php
│ │ ├── Contracts
│ │ ├── AnalyticsProviderInterface.php
│ │ └── TrackingBagInterface.php
│ │ ├── Data
│ │ ├── Campaign.php
│ │ ├── Event.php
│ │ └── Renderer
│ │ │ ├── CampaignRenderer.php
│ │ │ └── Renderer.php
│ │ ├── Providers
│ │ ├── GoogleAnalytics.php
│ │ └── NoAnalytics.php
│ │ └── TrackingBag.php
└── config
│ └── analytics.php
└── tests
└── .gitkeep
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | end_of_line = lf
6 | insert_final_newline = true
7 | indent_style = space
8 | indent_size = 4
9 | trim_trailing_whitespace = true
10 |
11 | [*.md]
12 | trim_trailing_whitespace = false
13 |
14 | [*.{yml,yaml}]
15 | indent_size = 2
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /vendor
2 | composer.phar
3 | composer.lock
4 | .DS_Store
5 | .idea
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: php
2 |
3 | php:
4 | - 7.2
5 | - 7.3
6 | - 7.4
7 |
8 | before_script:
9 | - composer install --prefer-dist --no-ansi --no-interaction --no-progress --no-scripts --no-suggest
10 |
11 | script: phpunit
12 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Robert Kummer
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Analytics tracking package for Laravel
2 |
3 | [](https://packagist.org/packages/ipunkt/laravel-analytics) [](https://packagist.org/packages/ipunkt/laravel-analytics) [](https://packagist.org/packages/ipunkt/laravel-analytics) [](https://packagist.org/packages/ipunkt/laravel-analytics) [](https://travis-ci.org/ipunkt/laravel-analytics)
4 |
5 | ## Quickstart
6 |
7 | ```
8 | composer require ipunkt/laravel-analytics
9 | ```
10 |
11 | You can use the facade `Analytics`.
12 |
13 | To your `.env` add these variables and set them to your liking:
14 |
15 | ```
16 | ANALYTICS_PROVIDER=GoogleAnalytics
17 | ANALYTICS_TRACKING_ID=your-tracking-id
18 | ```
19 | We support the whole configuration as environment variables. Please see Configuration section.
20 |
21 | Finally, just above your `` closing tag place, this code:
22 |
23 | ```
24 | {!! Analytics::render() !!}
25 | ```
26 |
27 | **You now have Google Analytics working. Enjoy!**
28 |
29 |
30 | ## Installation
31 |
32 | Add to your composer.json following lines
33 |
34 | "require": {
35 | "ipunkt/laravel-analytics": "~3.0"
36 | }
37 |
38 | Add `Ipunkt\LaravelAnalytics\AnalyticsServiceProvider::class,` to `providers` in `app/config/app.php`.
39 |
40 | Optional: Add `'Analytics' => Ipunkt\LaravelAnalytics\AnalyticsFacade::class,` to `aliases` in `app/config/app.php`.
41 |
42 | Run `php artisan vendor:publish --provider="Ipunkt\LaravelAnalytics\AnalyticsServiceProvider"`
43 |
44 | Then edit `analytics.php` in `config` to your needs. We do config merge in the service provider, so your local settings
45 | will stay the same.
46 |
47 | For laravel 7.x please use the 3.x release.
48 |
49 | "require": {
50 | "ipunkt/laravel-analytics": "~3.0"
51 | }
52 |
53 | For laravel 6.x please use the 2.x release.
54 |
55 | "require": {
56 | "ipunkt/laravel-analytics": "~2.0"
57 | }
58 |
59 | For php < 7.2 or laravel < 6.0 please use the 1.x release.
60 |
61 | "require": {
62 | "ipunkt/laravel-analytics": "~1.0"
63 | }
64 |
65 | ## Configuration
66 |
67 |
68 | - provider
- Provider to use, possible Providers are:
GoogleAnalytics
, NoAnalytics
69 |
70 |
71 | ### Google Analytics
72 |
73 |
74 | - tracking_id
- Tracking ID, Your tracking id for Google Analytics
75 | - tracking_domain
- Tracking domain, unset or set to "
auto
" for automatic fallback
76 | - tracker_name
- Tracker name
77 | - display_features
- enabling the display features plugin, possible values:
(true|false)
78 | - anonymize_ip
- anonymize users ip, possible values:
(true|false)
79 | - auto_track
- auto tracking current pageview, possible values:
(true|false)
80 | - debug
- enabling the debug mode, possible values:
(true|false)
81 | - optimize_id
- enabling the optimze feature of [Google Analytics](https://support.google.com/optimize/answer/6262084)
82 |
83 |
84 | ### Environment-based Configuration
85 |
86 | You can configure the whole settings by changing/setting environment variables in your .env file. (Or .env.dusk file if you use Laravel Dusk).
87 |
88 | Here is the mapping of configuration value and the environment-based names:
89 |
90 | - tracking_id
- ANALYTICS_TRACKING_ID
91 | - tracking_domain
- ANALYTICS_TRACKING_DOMAIN (auto)
92 | - tracker_name
- ANALYTICS_TRACKER_NAME (t0)
93 | - display_features
- ANALYTICS_DISPLAY_FEATURES (false)
94 | - anonymize_ip
- ANALYTICS_ANONYMIZE_IP (true)
95 | - auto_track
- ANALYTICS_AUTO_TRACK (true)
96 | - debug
- ANALYTICS_DEBUG (true on local environment)
97 | - optimize_id
- ANALYTICS_OPTIMIZE_ID
98 |
99 |
100 | This behaviour was integrated with version 1.3.2.
101 |
102 | ### Other
103 |
104 |
105 | - disable_script_block
- You can disable script block generation by configuration value, possible values:
(true|false)
, false by default.
106 |
107 |
108 | ## Usage
109 |
110 | In controller action (or anywhere else) use following statement to track an event or page view:
111 |
112 | // tracking the current page view
113 | Analytics::trackPage(); // only necessary if `auto_track` is false or Analytics::disableAutoTracking() was called before
114 |
115 | // tracking an event
116 | Analytics::trackEvent('category', 'action');
117 |
118 | // tracking a custom line
119 | Analytics::trackCustom("ga('send', ......"); // this line will be added within the tracking script
120 |
121 | You can set an optional campaign for the tracking:
122 |
123 | // creating a campaign
124 | $campaign = new \Ipunkt\LaravelAnalytics\Data\Campaign('Sales2016');
125 | $campaign->setMedium('web')->setSource('IT Magazine')->setKeyword('Hot stuff');
126 | Analytics::setCampaign($campaign);
127 |
128 | You can set an user id for the tracking:
129 |
130 | // creating a campaign
131 | Analytics::setUserId($userIdentificationHash);
132 |
133 | In your view or layout template (e.g. a blade template) use the following statement:
134 |
135 | {!! Analytics::render() !!}
136 |
137 | For Google Analytics you should place the statement right below the `body` tag
138 |
139 | {!! Analytics::render() !!}
140 |
141 | ### Dependency Injection
142 |
143 | You can inject the analytics provider by referencing the interface:
144 |
145 | class PageController extends Controller
146 | {
147 | public function show(\Ipunkt\LaravelAnalytics\Contracts\AnalyticsProviderInterface $analytics)
148 | {
149 | $analytics->setUserId(md5(\Auth::user()->id)); // identical to Analytics::setUserId(md5(\Auth::user()->id));
150 | return view('welcome');
151 | }
152 | }
153 |
154 | ## How to use
155 |
156 | The `GoogleAnalytics` Provider automatically controls the [local environment](https://developers.google.com/analytics/devguides/collection/analyticsjs/advanced#localhost) behaviour for testing purposes.
157 |
158 | There is a builtin provider called `NoAnalytics`. This is for testing environments and tracks nothing. So you do
159 | not have to rewrite your code, simple select this `provider` in `analytics` configuration for your special environment
160 | configurations.
161 |
162 | ### Track a measurement without having javascript
163 |
164 | 1. Log in to Google Analytics and create custom definition. There you create a custom metrics.
165 | For example: Email opens, Integer type, min: 0 and max: 1
166 | This will be available as `metric1`.
167 |
168 | 2. Within your mail template (or page template) you have to create a tracking image
169 |
170 | `
`
171 |
172 | 3. That's it
173 |
174 | ## Content Security Policy
175 |
176 | Since version 1.3 is a support for Content Security Policy integrated.
177 |
178 | Please call the `withCSP()` on the provider interface instance.
179 |
180 | Then use an additional package (or implement on your own) `martijnc/php-csp` and use the following code in your middleware or your javascript sending controller:
181 | ```php
182 | use Phpcsp\Security\ContentSecurityPolicyHeaderBuilder;
183 |
184 | $policy = new ContentSecurityPolicyHeaderBuilder();
185 |
186 | // Set the default-src directive to 'none'
187 | $policy->addSourceExpression(ContentSecurityPolicyHeaderBuilder::DIRECTIVE_DEFAULT_SRC, 'none');
188 |
189 | // Add the nonce to the script-src directive
190 | $policy->addNonce(ContentSecurityPolicyHeaderBuilder::DIRECTIVE_SCRIPT_SRC, $analytics->withCSP()->cspNonce());
191 |
192 | foreach ($policy->getHeaders(true) as $header) {
193 | header(sprintf('%s: %s', $header['name'], $header['value']));
194 | }
195 | ```
196 |
197 | The result looks like this:
198 | ```php
199 | array (size=1)
200 | 0 =>
201 | array (size=2)
202 | 'name' => string 'Content-Security-Policy' (length=23)
203 | 'value' => string 'default-src 'none'; script-src 'nonce-RandomNonceStringFromAnalyticsProvider';' (length=58)
204 | ```
205 |
206 | On rendering your analytics script the `nonce` attribute will be automatically added on your script tag.
207 |
208 | ## API Documentation
209 |
210 | For the correct usage methods look at the `Ipunkt\LaravelAnalytics\Contracts\AnalyticsProviderInterface.php`
211 |
212 | ### Analytics::render()
213 |
214 | Context: Blade Templates, View
215 |
216 | For rendering the correct javascript code. It is necessary to have it in all layout files to track your actions and page calls.
217 |
218 | /**
219 | * returns the javascript code for embedding the analytics stuff
220 | *
221 | * @return string
222 | */
223 | public function render();
224 |
225 |
226 | ### Analytics::trackPage()
227 |
228 | Context: Controller, Action code
229 |
230 | For tracking a page view.
231 |
232 | /**
233 | * track an page view
234 | *
235 | * @param null|string $page
236 | * @param null|string $title
237 | * @param null|string $hittype
238 | * @return void
239 | */
240 | public function trackPage($page, $title, $hittype);
241 |
242 |
243 | ### Analytics::trackEvent()
244 |
245 | Context: Controller, Action code
246 |
247 | For tracking an event
248 |
249 | /**
250 | * track an event
251 | *
252 | * @param string $category
253 | * @param string $action
254 | * @param null|string $label
255 | * @param null|int $value
256 | * @return void
257 | */
258 | public function trackEvent($category, $action, $label, $value);
259 |
260 |
261 | ### Analytics::trackCustom()
262 |
263 | Context: Controller, Action code
264 |
265 | For tracking a custom script line within the embedded analytics code.
266 |
267 | /**
268 | * track any custom code
269 | *
270 | * @param string $customCode
271 | * @return void
272 | */
273 | public function trackCustom($customCode);
274 |
275 |
276 | ### Analytics::enableDisplayFeatures()
277 |
278 | Context: Controller, Action code
279 |
280 | Enabling display features, overriding the configuration setting `display_features`.
281 |
282 | /**
283 | * enable display features
284 | *
285 | * @return GoogleAnalytics
286 | */
287 | public function enableDisplayFeatures();
288 |
289 |
290 | ### Analytics::disableDisplayFeatures()
291 |
292 | Context: Controller, Action code
293 |
294 | Disabling display features, overriding the configuration setting `display_features`.
295 |
296 | /**
297 | * disable display features
298 | *
299 | * @return GoogleAnalytics
300 | */
301 | public function disableDisplayFeatures();
302 |
303 | ### Analytics::enableAutoTracking()
304 |
305 | Context: Controller, Action code
306 |
307 | Enabling the auto tracking, overriding the configuration setting `auto_track`.
308 |
309 | /**
310 | * enable auto tracking
311 | *
312 | * @return GoogleAnalytics
313 | */
314 | public function enableAutoTracking();
315 |
316 |
317 | ### Analytics::disableAutoTracking()
318 |
319 | Context: Controller, Action code
320 |
321 | Disabling the auto tracking, overriding the configuration setting `auto_track`.
322 |
323 | /**
324 | * disable auto tracking
325 | *
326 | * @return GoogleAnalytics
327 | */
328 | public function disableAutoTracking();
329 |
330 | ### Analytics::trackMeasurementUrl()
331 |
332 | Context: Blade Template, View
333 |
334 | Sometimes you have to track measurements, e.g. opening an email newsletter. There you have no javascript at all.
335 |
336 | /**
337 | * assembles an url for tracking measurement without javascript
338 | *
339 | * e.g. for tracking email open events within a newsletter
340 | *
341 | * @param string $metricName
342 | * @param mixed $metricValue
343 | * @param \Ipunkt\LaravelAnalytics\Data\Event $event
344 | * @param \Ipunkt\LaravelAnalytics\Data\Campaign $campaign
345 | * @param string|null $clientId
346 | * @param array $params
347 | * @return string
348 | */
349 | public function trackMeasurementUrl($metricName, $metricValue, Event $event, Campaign $campaign, $clientId = null, array $params = array());
350 |
351 | ### Analytics::setUserId($userId)
352 |
353 | Context: Controller, Action code
354 |
355 | Adding an user id to analytics tracking. This user id is a user-dependent unique id. But be careful, you should have no
356 | direct relation to the special user itself - it should be unique per user for analyzing.
357 |
358 | This user tracking is implemented at [Google Analytics](https://developers.google.com/analytics/devguides/collection/analyticsjs/cookies-user-id).
359 |
360 | /**
361 | * sets an user id for user tracking
362 | *
363 | * @param string $userId
364 | * @return AnalyticsProviderInterface
365 | */
366 | public function setUserId($userId);
367 |
368 | ### Analytics::unsetUserId()
369 |
370 | Context: Controller, Action code
371 |
372 | Removing of an user id is also possible.
373 |
374 | /**
375 | * unset an user id
376 | *
377 | * @return AnalyticsProviderInterface
378 | */
379 | public function unsetUserId();
380 |
381 | ### Analytics::setCampaign($campaign)
382 |
383 | Context: Controller, Action code
384 |
385 | Adding a campaign to the current tracking.
386 |
387 | This campaign tracking is documented for [Google Analytics](https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#campaignName).
388 |
389 | /**
390 | * sets a campaign
391 | *
392 | * @param Campaign $campaign
393 | * @return AnalyticsProviderInterface
394 | */
395 | public function setCampaign(Campaign $campaign);
396 |
397 | ### Analytics::unsetCampaign()
398 |
399 | Context: Controller, Action code
400 |
401 | Removing of a campaign is also possible.
402 |
403 | /**
404 | * unset a possible given campaign
405 | *
406 | * @return AnalyticsProviderInterface
407 | */
408 | public function unsetCampaign();
409 |
410 | ### Analytics::enableScriptBlock()
411 |
412 | Context: Controller, Action code
413 |
414 | Enabling the rendering of the `` block tags. Is enabled by default, so you do not have to call this.
415 |
416 | /**
417 | * render script block
418 | *
419 | * @return GoogleAnalytics
420 | */
421 | public function enableScriptBlock();
422 |
423 | ### Analytics::disableScriptBlock()
424 |
425 | Context: Controller, Action code
426 |
427 | Disabling the rendering of the `` block tags.
428 |
429 | /**
430 | * do not render script block
431 | *
432 | * @return GoogleAnalytics
433 | */
434 | public function disableScriptBlock();
435 |
436 | ### Analytics::enableEcommerceTracking()
437 |
438 | Context: Controller, Action code
439 |
440 | Enabling ecommerce tracking.
441 |
442 | /**
443 | * enable ecommerce tracking
444 | *
445 | * @return AnalyticsProviderInterface
446 | */
447 | public function enableEcommerceTracking();
448 |
449 | ### Analytics::disableEcommerceTracking()
450 |
451 | Context: Controller, Action code
452 |
453 | Disabling ecommerce tracking.
454 |
455 | /**
456 | * disable ecommerce tracking
457 | *
458 | * @return AnalyticsProviderInterface
459 | */
460 | public function disableEcommerceTracking();
461 |
462 | ### Analytics::ecommerceAddTransaction()
463 |
464 | Context: Controller, Action code
465 |
466 | Add ecommerce transaction to tracking code.
467 |
468 | /**
469 | * ecommerce tracking - add transaction
470 | *
471 | * @param string $id
472 | * @param null|string $affiliation
473 | * @param null|float $revenue
474 | * @param null|float $shipping
475 | * @param null|float $tax
476 | * @param null|string $currency
477 | *
478 | * @return AnalyticsProviderInterface
479 | */
480 | public function ecommerceAddTransaction($id, $affiliation = null, $revenue = null, $shipping = null, $tax = null, $currency = null);
481 |
482 | The [multi currency](https://developers.google.com/analytics/devguides/collection/analyticsjs/ecommerce#multicurrency) tracking is supported with currency values defined [here](https://support.google.com/analytics/answer/6205902#supported-currencies).
483 |
484 | ### Analytics::ecommerceAddItem()
485 |
486 | Context: Controller, Action code
487 |
488 | Add ecommerce item to tracking code.
489 |
490 | /**
491 | * ecommerce tracking - add item
492 | *
493 | * @param string $id
494 | * @param string $name
495 | * @param null|string $sku
496 | * @param null|string $category
497 | * @param null|float $price
498 | * @param null|int $quantity
499 | * @param null|string $currency
500 | *
501 | * @return AnalyticsProviderInterface
502 | */
503 | public function ecommerceAddItem($id, $name, $sku = null, $category = null, $price = null, $quantity = null, $currency = null);
504 |
505 | The [multi currency](https://developers.google.com/analytics/devguides/collection/analyticsjs/ecommerce#multicurrency) tracking is supported with currency values defined [here](https://support.google.com/analytics/answer/6205902#supported-currencies).
506 |
507 | ### Analytics::setCustom()
508 |
509 | Context: Controller, Action code
510 |
511 | Adds custom settings.
512 |
513 | /**
514 | * sets custom dimensions
515 | *
516 | * @param string|array $dimension
517 | * @param null|string $value
518 | * @return AnalyticsProviderInterface
519 | */
520 | public function setCustom($dimension, $value = null)
521 |
522 | ### Analytics::withCSP()
523 |
524 | Context: Controller, Action code
525 |
526 | Enabling the Content Security Policy feature.
527 |
528 | /**
529 | * enables Content Security Polity and sets nonce
530 | *
531 | * @return AnalyticsProviderInterface
532 | */
533 | public function withCSP();
534 |
535 | ### Analytics::withoutCSP()
536 |
537 | Context: Controller, Action code
538 |
539 | Disabling the Content Security Policy feature.
540 |
541 | /**
542 | * disables Content Security Polity
543 | *
544 | * @return AnalyticsProviderInterface
545 | */
546 | public function withoutCSP();
547 |
548 | ### Analytics::cspNonce()
549 |
550 | Context: Controller, Action code
551 |
552 | Returns the nonce generated for the Content Security Policy Header.
553 |
554 | /**
555 | * returns the current Content Security Policy nonce
556 | *
557 | * @return string|null
558 | */
559 | public function cspNonce();
560 |
561 | ### Analytics::setOptimizeId()
562 |
563 | /**
564 | * set a custom optimize ID (the GTM-XXXXXX code)
565 | *
566 | * @param string $optimizeId
567 | *
568 | * @return AnalyticsProviderInterface
569 | */
570 | public function setOptimizeId($optimizeId);
571 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ipunkt/laravel-analytics",
3 | "type": "library",
4 | "description": "Analytics tracking for Laravel",
5 | "keywords": ["analytics", "google analytics", "laravel", "statistics", "javascript", "php"],
6 | "license": "MIT",
7 | "authors": [
8 | {
9 | "name": "Robert Kummer",
10 | "email": "r.kummer@ipunkt.biz"
11 | }
12 | ],
13 | "require": {
14 | "php": "^7.2 || ^8.0",
15 | "illuminate/config": "~5.0 || ^6.20 || ^7.24 || ^8.40",
16 | "illuminate/session": "~5.0 || ^6.20 || ^7.24 || ^8.40",
17 | "illuminate/support": "~5.0 || ^6.20 || ^7.24 || ^8.40"
18 | },
19 | "require-dev": {
20 | "laravel/framework": "~5.0 || ^6.20 || ^7.24 || ^8.40"
21 | },
22 | "autoload": {
23 | "psr-0": {
24 | "Ipunkt\\LaravelAnalytics\\": "src/"
25 | }
26 | },
27 | "minimum-stability": "stable",
28 | "suggest": {
29 | "martijnc/php-csp": "For handling Content Security Policy matters"
30 | },
31 | "support": {
32 | "issues": "https://github.com/ipunkt/laravel-analytics/issues",
33 | "source": "https://github.com/ipunkt/laravel-analytics/archive/master.zip"
34 | },
35 | "extra": {
36 | "laravel": {
37 | "providers": [
38 | "Ipunkt\\LaravelAnalytics\\AnalyticsServiceProvider"
39 | ],
40 | "aliases": {
41 | "Analytics": "Ipunkt\\LaravelAnalytics\\AnalyticsFacade"
42 | }
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/phpunit.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
14 | ./tests/
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/Ipunkt/LaravelAnalytics/AnalyticsFacade.php:
--------------------------------------------------------------------------------
1 | mergeConfigFrom($config, 'analytics');
27 |
28 | $this->publishes([
29 | $config => config_path('analytics.php'),
30 | ]);
31 | }
32 |
33 | /**
34 | * Register the service provider.
35 | *
36 | * @return void
37 | */
38 | public function register()
39 | {
40 | $this->app->singleton('Ipunkt\LaravelAnalytics\Contracts\AnalyticsProviderInterface',
41 | function () {
42 | // get analytics provider name
43 | $provider = Config::get('analytics.provider');
44 |
45 | // make it a class
46 | $providerClass = 'Ipunkt\LaravelAnalytics\Providers\\' . $provider;
47 |
48 | // getting the config
49 | $providerConfig = [];
50 | if (Config::has('analytics.configurations.' . $provider)) {
51 | $providerConfig = Config::get('analytics.configurations.' . $provider);
52 | }
53 |
54 | // make provider instance
55 | $instance = new $providerClass($providerConfig);
56 |
57 | // check if we want to prematurely disable the script block
58 | if (Config::get('analytics.disable_script_block', false)) {
59 | $instance->disableScriptBlock();
60 | }
61 |
62 | return $instance;
63 | });
64 | }
65 |
66 | /**
67 | * Get the services provided by the provider.
68 | *
69 | * @return array
70 | */
71 | public function provides()
72 | {
73 | return [];
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/src/Ipunkt/LaravelAnalytics/Contracts/AnalyticsProviderInterface.php:
--------------------------------------------------------------------------------
1 | nonInteraction(true)->render();
123 | * getting: if ($this->nonInteraction()) echo 'non-interaction set';
124 | *
125 | * @param boolean|null $value
126 | *
127 | * @return bool|AnalyticsProviderInterface
128 | */
129 | public function nonInteraction($value = null);
130 |
131 | /**
132 | * sets an user id for user tracking
133 | *
134 | * @param string $userId
135 | *
136 | * @return AnalyticsProviderInterface
137 | *
138 | * @see https://developers.google.com/analytics/devguides/collection/analyticsjs/cookies-user-id
139 | */
140 | public function setUserId($userId);
141 |
142 | /**
143 | * unsets a possible given user id
144 | *
145 | * @return AnalyticsProviderInterface
146 | */
147 | public function unsetUserId();
148 |
149 | /**
150 | * sets a campaign
151 | *
152 | * @param Campaign $campaign
153 | *
154 | * @return AnalyticsProviderInterface
155 | */
156 | public function setCampaign(Campaign $campaign);
157 |
158 | /**
159 | * unsets a possible given campaign
160 | *
161 | * @return AnalyticsProviderInterface
162 | */
163 | public function unsetCampaign();
164 |
165 | /**
166 | * enable ecommerce tracking
167 | *
168 | * @return AnalyticsProviderInterface
169 | */
170 | public function enableEcommerceTracking();
171 |
172 | /**
173 | * disable ecommerce tracking
174 | *
175 | * @return AnalyticsProviderInterface
176 | */
177 | public function disableEcommerceTracking();
178 |
179 | /**
180 | * ecommerce tracking - add transaction
181 | *
182 | * @param string $id
183 | * @param null|string $affiliation
184 | * @param null|float $revenue
185 | * @param null|float $shipping
186 | * @param null|float $tax
187 | * @param null|string $currency
188 | *
189 | * @return AnalyticsProviderInterface
190 | */
191 | public function ecommerceAddTransaction(
192 | $id,
193 | $affiliation = null,
194 | $revenue = null,
195 | $shipping = null,
196 | $tax = null,
197 | $currency = null
198 | );
199 |
200 | /**
201 | * ecommerce tracking - add item
202 | *
203 | * @param string $id
204 | * @param string $name
205 | * @param null|string $sku
206 | * @param null|string $category
207 | * @param null|float $price
208 | * @param null|int $quantity
209 | * @param null|string $currency
210 | *
211 | * @return AnalyticsProviderInterface
212 | */
213 | public function ecommerceAddItem(
214 | $id,
215 | $name,
216 | $sku = null,
217 | $category = null,
218 | $price = null,
219 | $quantity = null,
220 | $currency = null
221 | );
222 |
223 | /**
224 | * sets custom dimensions
225 | *
226 | * @param string|array $dimension
227 | * @param null|string $value
228 | * @return AnalyticsProviderInterface
229 | */
230 | public function setCustom($dimension, $value = null);
231 |
232 | /**
233 | * set a custom tracking ID (the UA-XXXXXXXX-1 code)
234 | *
235 | * @param string $trackingId
236 | *
237 | * @return AnalyticsProviderInterface
238 | */
239 | public function setTrackingId($trackingId);
240 |
241 | /**
242 | * set a custom optimize ID (the GTM-XXXXXX code)
243 | *
244 | * @param string $optimizeId
245 | *
246 | * @return AnalyticsProviderInterface
247 | */
248 | public function setOptimizeId($optimizeId);
249 |
250 | /**
251 | * enables Content Security Polity and sets nonce
252 | *
253 | * @return AnalyticsProviderInterface
254 | */
255 | public function withCSP();
256 |
257 | /**
258 | * disables Content Security Polity
259 | *
260 | * @return AnalyticsProviderInterface
261 | */
262 | public function withoutCSP();
263 |
264 | /**
265 | * returns the current Content Security Policy nonce
266 | *
267 | * @return string|null
268 | */
269 | public function cspNonce();
270 | }
271 |
--------------------------------------------------------------------------------
/src/Ipunkt/LaravelAnalytics/Contracts/TrackingBagInterface.php:
--------------------------------------------------------------------------------
1 | name = $name;
60 | }
61 |
62 | /**
63 | * set medium
64 | *
65 | * @param string $medium
66 | *
67 | * @return Campaign
68 | */
69 | public function setMedium($medium)
70 | {
71 | $this->medium = $medium;
72 |
73 | return $this;
74 | }
75 |
76 | /**
77 | * @return string
78 | */
79 | public function getMedium()
80 | {
81 | return $this->medium;
82 | }
83 |
84 | /**
85 | * set name
86 | *
87 | * @param string $name
88 | *
89 | * @return Campaign
90 | */
91 | public function setName($name)
92 | {
93 | $this->name = $name;
94 |
95 | return $this;
96 | }
97 |
98 | /**
99 | * @return string
100 | */
101 | public function getName()
102 | {
103 | return $this->name;
104 | }
105 |
106 | /**
107 | * set source
108 | *
109 | * @param string $source
110 | *
111 | * @return Campaign
112 | */
113 | public function setSource($source)
114 | {
115 | $this->source = $source;
116 |
117 | return $this;
118 | }
119 |
120 | /**
121 | * @return string
122 | */
123 | public function getSource()
124 | {
125 | return $this->source;
126 | }
127 |
128 | /**
129 | * returns Keyword
130 | *
131 | * @return string
132 | */
133 | public function getKeyword()
134 | {
135 | return $this->keyword;
136 | }
137 |
138 | /**
139 | * sets keyword
140 | *
141 | * @param string $keyword
142 | *
143 | * @return \Ipunkt\LaravelAnalytics\Data\Campaign
144 | */
145 | public function setKeyword($keyword)
146 | {
147 | $this->keyword = $keyword;
148 | return $this;
149 | }
150 |
151 | /**
152 | * returns Content
153 | *
154 | * @return string
155 | */
156 | public function getContent()
157 | {
158 | return $this->content;
159 | }
160 |
161 | /**
162 | * sets content
163 | *
164 | * @param string $content
165 | *
166 | * @return \Ipunkt\LaravelAnalytics\Data\Campaign
167 | */
168 | public function setContent($content)
169 | {
170 | $this->content = $content;
171 | return $this;
172 | }
173 |
174 | /**
175 | * returns Id
176 | *
177 | * @return string
178 | */
179 | public function getId()
180 | {
181 | return $this->id;
182 | }
183 |
184 | /**
185 | * sets id
186 | *
187 | * @param string $id
188 | *
189 | * @return \Ipunkt\LaravelAnalytics\Data\Campaign
190 | */
191 | public function setId($id)
192 | {
193 | $this->id = $id;
194 | return $this;
195 | }
196 | }
197 |
--------------------------------------------------------------------------------
/src/Ipunkt/LaravelAnalytics/Data/Event.php:
--------------------------------------------------------------------------------
1 | action = $action;
50 |
51 | return $this;
52 | }
53 |
54 | /**
55 | * returns action
56 | *
57 | * @return string
58 | */
59 | public function getAction()
60 | {
61 | return $this->action;
62 | }
63 |
64 | /**
65 | * set category
66 | *
67 | * @param string $category
68 | *
69 | * @return Event
70 | */
71 | public function setCategory($category)
72 | {
73 | $this->category = $category;
74 |
75 | return $this;
76 | }
77 |
78 | /**
79 | * returns category
80 | *
81 | * @return string
82 | */
83 | public function getCategory()
84 | {
85 | return $this->category;
86 | }
87 |
88 | /**
89 | * sets hit type
90 | *
91 | * @param string $hitType
92 | *
93 | * @return Event
94 | */
95 | public function setHitType($hitType)
96 | {
97 | $this->hitType = $hitType;
98 |
99 | return $this;
100 | }
101 |
102 | /**
103 | * returns hit type
104 | *
105 | * @return string
106 | */
107 | public function getHitType()
108 | {
109 | return $this->hitType;
110 | }
111 |
112 | /**
113 | * sets label
114 | *
115 | * @param string $label
116 | *
117 | * @return Event
118 | */
119 | public function setLabel($label)
120 | {
121 | $this->label = $label;
122 |
123 | return $this;
124 | }
125 |
126 | /**
127 | * returns label
128 | *
129 | * @return string
130 | */
131 | public function getLabel()
132 | {
133 | return $this->label;
134 | }
135 | }
--------------------------------------------------------------------------------
/src/Ipunkt/LaravelAnalytics/Data/Renderer/CampaignRenderer.php:
--------------------------------------------------------------------------------
1 | campaign = $campaign;
23 | }
24 |
25 | /**
26 | * Renders data
27 | *
28 | * @return string
29 | */
30 | public function render()
31 | {
32 | return $this->renderName()
33 | . $this->renderSource()
34 | . $this->renderMedium()
35 | . $this->renderKeyword()
36 | . $this->renderContent()
37 | . $this->renderId();
38 | }
39 |
40 | /**
41 | * returns the rendered name
42 | *
43 | * @return string
44 | */
45 | private function renderName()
46 | {
47 | $name = $this->campaign->getName();
48 |
49 | return empty($name) ? '' : "ga('set', 'campaignName', '{$name}');";
50 | }
51 |
52 | /**
53 | * returns the rendered source
54 | *
55 | * @return string
56 | */
57 | private function renderSource()
58 | {
59 | $source = $this->campaign->getSource();
60 |
61 | return empty($source) ? '' : "ga('set', 'campaignSource', '{$source}');";
62 | }
63 |
64 | /**
65 | * returns the rendered medium
66 | *
67 | * @return string
68 | */
69 | private function renderMedium()
70 | {
71 | $medium = $this->campaign->getMedium();
72 |
73 | return empty($medium) ? '' : "ga('set', 'campaignMedium', '{$medium}');";
74 | }
75 |
76 | /**
77 | * returns the rendered keyword
78 | *
79 | * @return string
80 | */
81 | private function renderKeyword()
82 | {
83 | $keyword = $this->campaign->getKeyword();
84 |
85 | return empty($keyword) ? '' : "ga('set', 'campaignKeyword', '{$keyword}');";
86 | }
87 |
88 | /**
89 | * returns the rendered content
90 | *
91 | * @return string
92 | */
93 | private function renderContent()
94 | {
95 | $content = $this->campaign->getContent();
96 |
97 | return empty($content) ? '' : "ga('set', 'campaignContent', '{$content}');";
98 | }
99 |
100 | /**
101 | * returns the rendered id
102 | *
103 | * @return string
104 | */
105 | private function renderId()
106 | {
107 | $id = $this->campaign->getId();
108 |
109 | return empty($id) ? '' : "ga('set', 'campaignId', '{$id}');";
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/src/Ipunkt/LaravelAnalytics/Data/Renderer/Renderer.php:
--------------------------------------------------------------------------------
1 | trackingId = Arr::get($options, 'tracking_id');
142 | $this->optimizeId = Arr::get($options, 'optimize_id');
143 | $this->trackingDomain = Arr::get($options, 'tracking_domain', 'auto');
144 | $this->trackerName = Arr::get($options, 'tracker_name', 't0');
145 | $this->displayFeatures = Arr::get($options, 'display_features', false);
146 | $this->anonymizeIp = Arr::get($options, 'anonymize_ip', false);
147 | $this->autoTrack = Arr::get($options, 'auto_track', false);
148 | $this->debug = Arr::get($options, 'debug', false);
149 |
150 | if ($this->trackingId === null) {
151 | throw new InvalidArgumentException('Argument tracking_id can not be null');
152 | }
153 |
154 | $this->trackingBag = new TrackingBag;
155 | }
156 |
157 | /**
158 | * track an page view
159 | *
160 | * @param null|string $page
161 | * @param null|string $title
162 | * @param null|string $hittype
163 | *
164 | * @return void
165 | */
166 | public function trackPage($page = null, $title = null, $hittype = null)
167 | {
168 | $allowedHitTypes = ['pageview', 'appview', 'event', 'transaction', 'item', 'social', 'exception', 'timing'];
169 | if ($hittype === null) {
170 | $hittype = $allowedHitTypes[0];
171 | }
172 |
173 | if (!in_array($hittype, $allowedHitTypes)) {
174 | return;
175 | }
176 |
177 | $trackingCode = "ga('send', 'pageview');";
178 |
179 | if ($page !== null || $title !== null || $hittype !== null) {
180 | $page = ($page === null) ? "window.location.protocol + '//' + window.location.hostname + window.location.pathname + window.location.search" : "'{$page}'";
181 | $title = ($title === null) ? "document.title" : "'{$title}'";
182 |
183 | $trackingCode = "ga('send', {'hitType': '{$hittype}', 'page': {$page}, 'title': {$title}});";
184 | }
185 |
186 | $this->trackingBag->add($trackingCode);
187 | }
188 |
189 | /**
190 | * track an event
191 | *
192 | * @param string $category
193 | * @param string $action
194 | * @param null|string $label
195 | * @param null|int $value
196 | */
197 | public function trackEvent($category, $action, $label = null, $value = null)
198 | {
199 | $command = '';
200 | if ($label !== null) {
201 | $command .= ", '{$label}'";
202 | if ($value !== null && is_numeric($value)) {
203 | $command .= ", {$value}";
204 | }
205 | }
206 |
207 | $trackingCode = "ga('send', 'event', '{$category}', '{$action}'$command);";
208 |
209 | $this->trackingBag->add($trackingCode);
210 | }
211 |
212 | /**
213 | * ecommerce tracking - add transaction
214 | *
215 | * @param string $id
216 | * @param null|string $affiliation
217 | * @param null|float $revenue
218 | * @param null|float $shipping
219 | * @param null|float $tax
220 | * @param null|string $currency
221 | *
222 | * @return AnalyticsProviderInterface
223 | */
224 | public function ecommerceAddTransaction(
225 | $id,
226 | $affiliation = null,
227 | $revenue = null,
228 | $shipping = null,
229 | $tax = null,
230 | $currency = null
231 | ) {
232 | // Call to enable ecommerce tracking automatically
233 | $this->enableEcommerceTracking();
234 |
235 | $parameters = ['id' => $id];
236 |
237 | if (!is_null($affiliation)) {
238 | $parameters['affiliation'] = $affiliation;
239 | }
240 |
241 | if (!is_null($revenue)) {
242 | $parameters['revenue'] = $revenue;
243 | }
244 |
245 | if (!is_null($shipping)) {
246 | $parameters['shipping'] = $shipping;
247 | }
248 |
249 | if (!is_null($tax)) {
250 | $parameters['tax'] = $tax;
251 | }
252 |
253 | if (!is_null($currency)) {
254 | $parameters['currency'] = $currency;
255 | }
256 |
257 | $jsonParameters = json_encode($parameters);
258 | $trackingCode = "ga('ecommerce:addTransaction', {$jsonParameters});";
259 |
260 | $this->trackingBag->add($trackingCode);
261 |
262 | return $this;
263 | }
264 |
265 | /**
266 | * ecommerce tracking - add item
267 | *
268 | * @param string $id
269 | * @param string $name
270 | * @param null|string $sku
271 | * @param null|string $category
272 | * @param null|float $price
273 | * @param null|int $quantity
274 | * @param null|string $currency
275 | *
276 | * @return AnalyticsProviderInterface
277 | */
278 | public function ecommerceAddItem(
279 | $id,
280 | $name,
281 | $sku = null,
282 | $category = null,
283 | $price = null,
284 | $quantity = null,
285 | $currency = null
286 | ) {
287 | // Call to enable ecommerce tracking automatically
288 | $this->enableEcommerceTracking();
289 |
290 | $parameters = [
291 | 'id' => $id,
292 | 'name' => $name,
293 | ];
294 |
295 | if (!is_null($sku)) {
296 | $parameters['sku'] = $sku;
297 | }
298 |
299 | if (!is_null($category)) {
300 | $parameters['category'] = $category;
301 | }
302 |
303 | if (!is_null($price)) {
304 | $parameters['price'] = $price;
305 | }
306 |
307 | if (!is_null($quantity)) {
308 | $parameters['quantity'] = $quantity;
309 | }
310 |
311 | if (!is_null($currency)) {
312 | $parameters['currency'] = $currency;
313 | }
314 |
315 | $jsonParameters = json_encode($parameters);
316 | $trackingCode = "ga('ecommerce:addItem', {$jsonParameters});";
317 |
318 | $this->trackingBag->add($trackingCode);
319 |
320 | return $this;
321 | }
322 |
323 | /**
324 | * track any custom code
325 | *
326 | * @param string $customCode
327 | *
328 | * @return void
329 | */
330 | public function trackCustom($customCode)
331 | {
332 | $this->trackingBag->add($customCode);
333 | }
334 |
335 | /**
336 | * enable display features
337 | *
338 | * @return GoogleAnalytics
339 | */
340 | public function enableDisplayFeatures()
341 | {
342 | $this->displayFeatures = true;
343 |
344 | return $this;
345 | }
346 |
347 | /**
348 | * disable display features
349 | *
350 | * @return GoogleAnalytics
351 | */
352 | public function disableDisplayFeatures()
353 | {
354 | $this->displayFeatures = false;
355 |
356 | return $this;
357 | }
358 |
359 | /**
360 | * enable ecommerce tracking
361 | *
362 | * @return GoogleAnalytics
363 | */
364 | public function enableEcommerceTracking()
365 | {
366 | $this->ecommerceTracking = true;
367 |
368 | return $this;
369 | }
370 |
371 | /**
372 | * disable ecommerce tracking
373 | *
374 | * @return GoogleAnalytics
375 | */
376 | public function disableEcommerceTracking()
377 | {
378 | $this->ecommerceTracking = false;
379 |
380 | return $this;
381 | }
382 |
383 | /**
384 | * enable auto tracking
385 | *
386 | * @return GoogleAnalytics
387 | */
388 | public function enableAutoTracking()
389 | {
390 | $this->autoTrack = true;
391 |
392 | return $this;
393 | }
394 |
395 | /**
396 | * disable auto tracking
397 | *
398 | * @return GoogleAnalytics
399 | */
400 | public function disableAutoTracking()
401 | {
402 | $this->autoTrack = false;
403 |
404 | return $this;
405 | }
406 |
407 | /**
408 | * render script block
409 | *
410 | * @return \Ipunkt\LaravelAnalytics\Providers\GoogleAnalytics
411 | */
412 | public function enableScriptBlock()
413 | {
414 | $this->renderScriptBlock = true;
415 |
416 | return $this;
417 | }
418 |
419 | /**
420 | * do not render script block
421 | *
422 | * @return \Ipunkt\LaravelAnalytics\Providers\GoogleAnalytics
423 | */
424 | public function disableScriptBlock()
425 | {
426 | $this->renderScriptBlock = false;
427 |
428 | return $this;
429 | }
430 |
431 | /**
432 | * returns the javascript embedding code
433 | *
434 | * @return string
435 | */
436 | public function render()
437 | {
438 | $script[] = $this->_getJavascriptTemplateBlockBegin();
439 |
440 | $trackingUserId = (null === $this->userId)
441 | ? ''
442 | : sprintf(", {'userId': '%s'}", $this->userId);
443 |
444 | if ($this->debug) {
445 | $script[] = "ga('create', '{$this->trackingId}', { 'cookieDomain': 'none' }, '{$this->trackerName}'{$trackingUserId});";
446 | } else {
447 | $script[] = "ga('create', '{$this->trackingId}', '{$this->trackingDomain}', '{$this->trackerName}'{$trackingUserId});";
448 | }
449 |
450 | if ($this->ecommerceTracking) {
451 | $script[] = "ga('require', 'ecommerce');";
452 | }
453 |
454 | if ($this->displayFeatures) {
455 | $script[] = "ga('require', 'displayfeatures');";
456 | }
457 |
458 | if ($this->optimizeId) {
459 | $script[] = "ga('require', '{$this->optimizeId}');";
460 | }
461 |
462 | if ($this->anonymizeIp) {
463 | $script[] = "ga('set', 'anonymizeIp', true);";
464 | }
465 |
466 | if ($this->nonInteraction) {
467 | $script[] = "ga('set', 'nonInteraction', true);";
468 | }
469 |
470 | if ($this->campaign instanceof Campaign) {
471 | $script[] = (new CampaignRenderer($this->campaign))->render();
472 | }
473 |
474 | $trackingStack = $this->trackingBag->get();
475 | if (count($trackingStack)) {
476 | $script[] = implode("\n", $trackingStack);
477 | }
478 |
479 | if ($this->autoTrack) {
480 | $script[] = "ga('send', 'pageview');";
481 | }
482 |
483 | if ($this->ecommerceTracking) {
484 | $script[] = "ga('ecommerce:send');";
485 | }
486 |
487 | $script[] = $this->_getJavascriptTemplateBlockEnd();
488 |
489 | return implode('', $script);
490 | }
491 |
492 | /**
493 | * sets or gets nonInteraction
494 | *
495 | * setting: $this->nonInteraction(true)->render();
496 | * getting: if ($this->nonInteraction()) echo 'non-interaction set';
497 | *
498 | * @param boolean|null $value
499 | *
500 | * @return bool|$this
501 | */
502 | public function nonInteraction($value = null)
503 | {
504 | if (null === $value) {
505 | return $this->nonInteraction;
506 | }
507 |
508 | $this->nonInteraction = ($value === true);
509 |
510 | return $this;
511 | }
512 |
513 | /**
514 | * make the tracking measurement url insecure
515 | *
516 | * @return \Ipunkt\LaravelAnalytics\Providers\GoogleAnalytics
517 | */
518 | public function unsecureMeasurementUrl()
519 | {
520 | $this->secureTrackingUrl = false;
521 |
522 | return $this;
523 | }
524 |
525 | /**
526 | * use the secured version of the tracking measurement url
527 | *
528 | * @return \Ipunkt\LaravelAnalytics\Providers\GoogleAnalytics
529 | */
530 | public function secureMeasurementUrl()
531 | {
532 | $this->secureTrackingUrl = false;
533 |
534 | return $this;
535 | }
536 |
537 | /**
538 | * assembles an url for tracking measurement without javascript
539 | *
540 | * e.g. for tracking email open events within a newsletter
541 | *
542 | * @param string $metricName
543 | * @param mixed $metricValue
544 | * @param \Ipunkt\LaravelAnalytics\Data\Event $event
545 | * @param \Ipunkt\LaravelAnalytics\Data\Campaign $campaign
546 | * @param string|null $clientId
547 | * @param array $params
548 | *
549 | * @return string
550 | */
551 | public function trackMeasurementUrl(
552 | $metricName,
553 | $metricValue,
554 | Event $event,
555 | Campaign $campaign,
556 | $clientId = null,
557 | array $params = []
558 | ) {
559 | $uniqueId = ($clientId !== null) ? $clientId : uniqid('track_');
560 |
561 | if ($event->getLabel() === '') {
562 | $event->setLabel($uniqueId);
563 | }
564 |
565 | if ($campaign->getName() === '') {
566 | $campaign->setName('Campaign ' . date('Y-m-d'));
567 | }
568 |
569 | $protocol = $this->secureTrackingUrl ? 'https' : 'http';
570 |
571 | $defaults = [
572 | 'url' => $protocol . '://www.google-analytics.com/collect?',
573 | 'params' => [
574 | 'v' => 1, // protocol version
575 | 'tid' => $this->trackingId, // tracking id
576 | 'cid' => $uniqueId, // client id
577 | 't' => $event->getHitType(),
578 | 'ec' => $event->getCategory(),
579 | 'ea' => $event->getAction(),
580 | 'el' => $event->getLabel(),
581 | 'cs' => $campaign->getSource(),
582 | 'cm' => $campaign->getMedium(),
583 | 'cn' => $campaign->getName(),
584 | $metricName => $metricValue, // metric data
585 | ],
586 | ];
587 |
588 | $url = isset($params['url']) ? $params['url'] : $defaults['url'];
589 | $url = rtrim($url, '?') . '?';
590 |
591 | if (isset($params['url'])) {
592 | unset($params['url']);
593 | }
594 |
595 | $params = array_merge($defaults['params'], $params);
596 | $queryParams = [];
597 | foreach ($params as $key => $value) {
598 | if (!empty($value)) {
599 | $queryParams[] = sprintf('%s=%s', $key, $value);
600 | }
601 | }
602 |
603 | return $url . implode('&', $queryParams);
604 | }
605 |
606 | /**
607 | * sets an user id for user tracking
608 | *
609 | * @param string $userId
610 | *
611 | * @return AnalyticsProviderInterface
612 | *
613 | * @see https://developers.google.com/analytics/devguides/collection/analyticsjs/cookies-user-id
614 | */
615 | public function setUserId($userId)
616 | {
617 | $this->userId = $userId;
618 |
619 | return $this;
620 | }
621 |
622 | /**
623 | * unset a possible given user id
624 | *
625 | * @return AnalyticsProviderInterface
626 | */
627 | public function unsetUserId()
628 | {
629 | return $this->setUserId(null);
630 | }
631 |
632 | /**
633 | * sets custom dimensions
634 | *
635 | * @param string|array $dimension
636 | * @param null|string $value
637 | * @return AnalyticsProviderInterface
638 | */
639 | public function setCustom($dimension, $value = null)
640 | {
641 | if ($value === null && is_array($dimension)) {
642 | $params = json_encode($dimension);
643 | $trackingCode = "ga('set', $params);";
644 | } else {
645 | $trackingCode = "ga('set', '$dimension', '$value');";
646 | }
647 |
648 | $this->trackCustom($trackingCode);
649 |
650 | return $this;
651 | }
652 |
653 | /**
654 | * sets a campaign
655 | *
656 | * @param Campaign $campaign
657 | * @return AnalyticsProviderInterface
658 | */
659 | public function setCampaign(Campaign $campaign)
660 | {
661 | $this->campaign = $campaign;
662 |
663 | return $this;
664 | }
665 |
666 | /**
667 | * unset a possible given campaign
668 | *
669 | * @return AnalyticsProviderInterface
670 | */
671 | public function unsetCampaign()
672 | {
673 | $this->campaign = null;
674 |
675 | return $this;
676 | }
677 |
678 | /**
679 | * enables Content Security Polity and sets nonce
680 | *
681 | * @return AnalyticsProviderInterface
682 | * @throws \Exception
683 | */
684 | public function withCSP()
685 | {
686 | if ($this->cspNonce === null) {
687 | $this->cspNonce = 'nonce-' . random_int(0, PHP_INT_MAX);
688 | }
689 |
690 | return $this;
691 | }
692 |
693 | /**
694 | * disables Content Security Polity
695 | *
696 | * @return AnalyticsProviderInterface
697 | */
698 | public function withoutCSP()
699 | {
700 | $this->cspNonce = null;
701 |
702 | return $this;
703 | }
704 |
705 | /**
706 | * returns the current Content Security Policy nonce
707 | *
708 | * @return string|null
709 | */
710 | public function cspNonce()
711 | {
712 | return $this->cspNonce;
713 | }
714 |
715 | /**
716 | * returns start block
717 | *
718 | * @return string
719 | */
720 | protected function _getJavascriptTemplateBlockBegin()
721 | {
722 | $appendix = $this->debug ? '_debug' : '';
723 |
724 | $scriptTag = ($this->cspNonce === null)
725 | ? ''
742 | : '';
743 | }
744 |
745 | /**
746 | * set a custom tracking ID (the UA-XXXXXXXX-1 code)
747 | *
748 | * @param string $trackingId
749 | *
750 | * @return AnalyticsProviderInterface
751 | */
752 | public function setTrackingId($trackingId)
753 | {
754 | $this->trackingId = $trackingId;
755 |
756 | return $this;
757 | }
758 |
759 | /**
760 | * set a custom optimize ID (the GTM-XXXXXX code)
761 | *
762 | * @param string $optimizeId
763 | *
764 | * @return AnalyticsProviderInterface
765 | */
766 | public function setOptimizeId($optimizeId)
767 | {
768 | $this->optimizeId = $optimizeId;
769 |
770 | return $this;
771 | }
772 | }
773 |
--------------------------------------------------------------------------------
/src/Ipunkt/LaravelAnalytics/Providers/NoAnalytics.php:
--------------------------------------------------------------------------------
1 | nonInteraction(true)->render();
153 | * getting: if ($this->nonInteraction()) echo 'non-interaction set';
154 | *
155 | * @param boolean|null $value
156 | *
157 | * @return bool|AnalyticsProviderInterface
158 | */
159 | public function nonInteraction($value = null)
160 | {
161 | if (null === $value) {
162 | return false;
163 | }
164 |
165 | return $this;
166 | }
167 |
168 | /**
169 | * sets an user id for user tracking
170 | *
171 | * @param string $userId
172 | *
173 | * @return AnalyticsProviderInterface
174 | *
175 | * @see https://developers.google.com/analytics/devguides/collection/analyticsjs/cookies-user-id
176 | */
177 | public function setUserId($userId)
178 | {
179 | return $this;
180 | }
181 |
182 | /**
183 | * unsets a possible given user id
184 | *
185 | * @return AnalyticsProviderInterface
186 | */
187 | public function unsetUserId()
188 | {
189 | return $this;
190 | }
191 |
192 | /**
193 | * sets custom dimensions
194 | *
195 | * @param string|array $dimension
196 | * @param null|string $value
197 | * @return AnalyticsProviderInterface
198 | */
199 | public function setCustom($dimension, $value = null)
200 | {
201 | return $this;
202 | }
203 |
204 | /**
205 | * sets a campaign
206 | *
207 | * @param Campaign $campaign
208 | * @return AnalyticsProviderInterface
209 | */
210 | public function setCampaign(Campaign $campaign)
211 | {
212 | return $this;
213 | }
214 |
215 | /**
216 | * unsets a possible given campaign
217 | *
218 | * @return AnalyticsProviderInterface
219 | */
220 | public function unsetCampaign()
221 | {
222 | return $this;
223 | }
224 |
225 | /**
226 | * enable ecommerce tracking
227 | *
228 | * @return AnalyticsProviderInterface
229 | */
230 | public function enableEcommerceTracking()
231 | {
232 | return $this;
233 | }
234 |
235 | /**
236 | * disable ecommerce tracking
237 | *
238 | * @return AnalyticsProviderInterface
239 | */
240 | public function disableEcommerceTracking()
241 | {
242 | return $this;
243 | }
244 |
245 | /**
246 | * ecommerce tracking - add transaction
247 | *
248 | * @param string $id
249 | * @param null|string $affiliation
250 | * @param null|float $revenue
251 | * @param null|float $shipping
252 | * @param null|float $tax
253 | * @param null|string $currency
254 | *
255 | * @return AnalyticsProviderInterface
256 | */
257 | public function ecommerceAddTransaction(
258 | $id,
259 | $affiliation = null,
260 | $revenue = null,
261 | $shipping = null,
262 | $tax = null,
263 | $currency = null
264 | ) {
265 | return $this;
266 | }
267 |
268 | /**
269 | * ecommerce tracking - add item
270 | *
271 | * @param string $id
272 | * @param string $name
273 | * @param null|string $sku
274 | * @param null|string $category
275 | * @param null|float $price
276 | * @param null|int $quantity
277 | * @param null|string $currency
278 | *
279 | * @return AnalyticsProviderInterface
280 | */
281 | public function ecommerceAddItem(
282 | $id,
283 | $name,
284 | $sku = null,
285 | $category = null,
286 | $price = null,
287 | $quantity = null,
288 | $currency = null
289 | ) {
290 | return $this;
291 | }
292 |
293 | /**
294 | * enables Content Security Polity and sets nonce
295 | *
296 | * @return AnalyticsProviderInterface
297 | */
298 | public function withCSP()
299 | {
300 | return $this;
301 | }
302 |
303 | /**
304 | * disables Content Security Polity
305 | *
306 | * @return AnalyticsProviderInterface
307 | */
308 | public function withoutCSP()
309 | {
310 | return $this;
311 | }
312 |
313 | /**
314 | * returns the current Content Security Policy nonce
315 | *
316 | * @return string|null
317 | */
318 | public function cspNonce()
319 | {
320 | return null;
321 | }
322 |
323 | /**
324 | * set a custom tracking ID (the UA-XXXXXXXX-1 code)
325 | *
326 | * @param string $trackingId
327 | *
328 | * @return AnalyticsProviderInterface
329 | */
330 | public function setTrackingId($trackingId)
331 | {
332 | return $this;
333 | }
334 |
335 | /**
336 | * set a custom optimize ID (the GTM-XXXXXX code)
337 | *
338 | * @param string $optimizeId
339 | *
340 | * @return AnalyticsProviderInterface
341 | */
342 | public function setOptimizeId($optimizeId)
343 | {
344 | return $this;
345 | }
346 | }
347 |
--------------------------------------------------------------------------------
/src/Ipunkt/LaravelAnalytics/TrackingBag.php:
--------------------------------------------------------------------------------
1 | sessionIdentifier)) {
31 | $sessionTracks = Session::get($this->sessionIdentifier);
32 | }
33 |
34 | // prevent duplicates in session
35 | $trackingKey = md5($tracking);
36 | $sessionTracks[$trackingKey] = $tracking;
37 |
38 | Session::flash($this->sessionIdentifier, $sessionTracks);
39 | }
40 |
41 | /**
42 | * returns all trackings with forgetting it
43 | *
44 | * @return array
45 | */
46 | public function get()
47 | {
48 | $trackings = [];
49 | if (Session::has($this->sessionIdentifier)) {
50 | $trackings = Session::get($this->sessionIdentifier);
51 | Session::forget($this->sessionIdentifier);
52 | }
53 |
54 | return $trackings;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/config/analytics.php:
--------------------------------------------------------------------------------
1 | env('ANALYTICS_PROVIDER', 'GoogleAnalytics'),
9 |
10 | /**
11 | * configurations for all possible providers
12 | */
13 | 'configurations' => [
14 |
15 | /**
16 | * The Google Analytics provider supports the following properties:
17 | * - tracking_id (string)
18 | * - optimize_id (string)
19 | * - tracking_domain (string:auto) - default will be 'auto' if config property not exists
20 | * - tracker_name (string:t0) - default will be 't0' if config property not exists
21 | * - display_features (bool) - default will be false if no config property exists
22 | * - anonymize_ip (bool) - default will be false if no config property exists
23 | * - auto_track (bool) - default will be false if no config property exists
24 | * - debug (bool) - default will be false if no config property exists
25 | */
26 | 'GoogleAnalytics' => [
27 |
28 | /**
29 | * Tracking ID: You have to set this
30 | * Format example: UA-XXXXXXXX-1
31 | */
32 | 'tracking_id' => env('ANALYTICS_TRACKING_ID', 'UA-XXXXXXXX-1'),
33 |
34 | /**
35 | * Optimize ID
36 | * Format example: GTM-XXXXXX
37 | */
38 | 'optimize_id' => env('ANALYTICS_OPTIMIZE_ID', ''),
39 |
40 | /**
41 | * Tracking Domain
42 | */
43 | 'tracking_domain' => env('ANALYTICS_TRACKING_DOMAIN', 'auto'),
44 |
45 | /**
46 | * Tracker Name
47 | */
48 | 'tracker_name' => env('ANALYTICS_TRACKER_NAME', 't0'),
49 |
50 | /**
51 | * enabling the display feature plugin
52 | */
53 | 'display_features' => env('ANALYTICS_DISPLAY_FEATURES', false),
54 |
55 | /**
56 | * Use ip anonymized
57 | */
58 | 'anonymize_ip' => env('ANALYTICS_ANONYMIZE_IP', true),
59 |
60 | /**
61 | * Auto tracking pageview: ga('send', 'pageview');
62 | * If false, you have to do it manually for each request
63 | * Or you can use Analytics::disableAutoTracking(), Analytics::enableAutoTracking()
64 | */
65 | 'auto_track' => env('ANALYTICS_AUTO_TRACK', true),
66 |
67 | /**
68 | * Enable the debugging version of Google Analytics
69 | */
70 | 'debug' => env('ANALYTICS_DEBUG', env('APP_ENV') === 'local'),
71 | ],
72 |
73 | ],
74 |
75 | /**
76 | * disable Analytics