├── .styleci.yml ├── changelog.md ├── src ├── Facades │ └── LaravelMatomoTracker.php ├── LaravelMatomoTrackerServiceProvider.php └── LaravelMatomoTracker.php ├── phpunit.xml ├── config └── matomotracker.php ├── contributing.md ├── composer.json ├── license.md └── readme.md /.styleci.yml: -------------------------------------------------------------------------------- 1 | preset: laravel -------------------------------------------------------------------------------- /changelog.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to `MatomoTracker` will be documented in this file. 4 | 5 | ## Version 0.1 6 | 7 | ### Added 8 | - Everything 9 | -------------------------------------------------------------------------------- /src/Facades/LaravelMatomoTracker.php: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 14 | ./tests/ 15 | 16 | 17 | 18 | 19 | src/ 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /config/matomotracker.php: -------------------------------------------------------------------------------- 1 | env('MATOMO_URL', ''), 9 | 10 | /** 11 | * The id of the site that should be tracked 12 | */ 13 | 'idSite' => env('MATOMO_SITE_ID', 1), 14 | 15 | /** 16 | * The auth token of your user 17 | */ 18 | 'tokenAuth' => env('MATOMO_AUTH_TOKEN', ''), 19 | 20 | /** 21 | * For queuing the tracking you can use custom queue names. Use 'default' if you want to run the queued items within the standard queue. 22 | */ 23 | 'queue' => env('MATOMO_QUEUE', 'matomotracker'), 24 | 25 | /** 26 | * Optionally set a custom queue connection. Laravel defaults to "sync". 27 | */ 28 | 'queueConnection' => env('MATOMO_QUEUE_CONNECTION', 'default'), 29 | ]; 30 | -------------------------------------------------------------------------------- /contributing.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Contributions are welcome and will be fully credited. 4 | 5 | Contributions are accepted via Pull Requests on [Github](https://github.com/alfrasc/laravel-matomo-tracker). 6 | 7 | # Things you could do 8 | If you want to contribute but do not know where to start, this list provides some starting points. 9 | - Write a comprehensive ReadMe 10 | 11 | ## Pull Requests 12 | 13 | - **Add tests!** - Your patch won't be accepted if it doesn't have tests. 14 | 15 | - **Document any change in behaviour** - Make sure the `readme.md` and any other relevant documentation are kept up-to-date. 16 | 17 | - **Consider our release cycle** - We try to follow [SemVer v2.0.0](http://semver.org/). Randomly breaking public APIs is not an option. 18 | 19 | - **One pull request per feature** - If you want to do more than one thing, send multiple pull requests. 20 | 21 | - **Send coherent history** - Make sure each individual commit in your pull request is meaningful. If you had to make multiple intermediate commits while developing, please [squash them](http://www.git-scm.com/book/en/v2/Git-Tools-Rewriting-History#Changing-Multiple-Commit-Messages) before submitting. 22 | 23 | 24 | **Happy coding**! 25 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "alfrasc/laravel-matomo-tracker", 3 | "description": "A Laravel facade/wrapper for the matomo/matomo-php-tracker for server side Matomo tracking.", 4 | "license": "BSD-3-Clause", 5 | "authors": [ 6 | { 7 | "name": "Alexander Schmidhuber", 8 | "email": "alexander.schmidhuber@gmail.com", 9 | "homepage": "https://schmidhuber.co.at" 10 | } 11 | ], 12 | "homepage": "https://github.com/alfrasc/matomotracker", 13 | "keywords": ["Laravel", "Matomo PHP Tracker", "Piwik", "Piwik PHP Tracker", "server side tracking"], 14 | "require": { 15 | "matomo/matomo-php-tracker": "^3.0.0" 16 | }, 17 | "require-dev": { 18 | "phpunit/phpunit": "~7.0", 19 | "mockery/mockery": "^1.1", 20 | "orchestra/testbench": "~3.0", 21 | "sempro/phpunit-pretty-print": "^1.0" 22 | }, 23 | "autoload": { 24 | "psr-4": { 25 | "Alfrasc\\MatomoTracker\\": "src/" 26 | } 27 | }, 28 | "autoload-dev": { 29 | "psr-4": { 30 | "Alfrasc\\MatomoTracker\\Tests\\": "tests" 31 | } 32 | }, 33 | "extra": { 34 | "laravel": { 35 | "providers": [ 36 | "Alfrasc\\MatomoTracker\\LaravelMatomoTrackerServiceProvider" 37 | ], 38 | "aliases": { 39 | "LaravelMatomoTracker": "Alfrasc\\MatomoTracker\\Facades\\LaravelMatomoTracker" 40 | } 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /license.md: -------------------------------------------------------------------------------- 1 | # The license 2 | 3 | Copyright (c) 2019 Alexander Schmidhuber 4 | 5 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | 9 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 10 | 11 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 14 | -------------------------------------------------------------------------------- /src/LaravelMatomoTrackerServiceProvider.php: -------------------------------------------------------------------------------- 1 | request = $request; 22 | 23 | // Publishing is only necessary when using the CLI. 24 | if ($this->app->runningInConsole()) { 25 | $this->bootForConsole(); 26 | } 27 | } 28 | 29 | /** 30 | * Register any package services. 31 | * 32 | * @return void 33 | */ 34 | public function register() 35 | { 36 | $this->mergeConfigFrom(__DIR__ . '/../config/matomotracker.php', 'matomotracker'); 37 | 38 | // Register the service the package provides. 39 | $this->app->singleton('laravelmatomotracker', function ($app) { 40 | return new LaravelMatomoTracker( 41 | $this->request, 42 | Config::get('matomotracker.idSite'), 43 | Config::get('matomotracker.url'), 44 | Config::get('matomotracker.tokenAuth') 45 | ); 46 | }); 47 | } 48 | 49 | /** 50 | * Get the services provided by the provider. 51 | * 52 | * @return array 53 | */ 54 | public function provides() 55 | { 56 | return ['laravelmatomotracker']; 57 | } 58 | 59 | /** 60 | * Console-specific booting. 61 | * 62 | * @return void 63 | */ 64 | protected function bootForConsole() 65 | { 66 | // Publishing the configuration file. 67 | $this->publishes([ 68 | __DIR__ . '/../config/matomotracker.php' => config_path('matomotracker.php'), 69 | ], 'matomotracker.config'); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # LaravelMatomoTracker 2 | 3 | [![Latest Version on Packagist][ico-version]][link-packagist] 4 | [![Total Downloads][ico-downloads]][link-downloads] 5 | 6 | ## About 7 | 8 | The `alfrasc\laravel-matomo-tracker` Laravel package is a wrapper for the `piwik\piwik-php-tracker`. The Piwik php tracker allows serverside tracking. 9 | 10 | ## Features 11 | 12 | * LaravelMatomoTracker Facade 13 | * Queued tracking requests in Laravel queue 14 | 15 | Feel free to suggest new features. 16 | 17 | ## Installation 18 | 19 | Via Composer 20 | 21 | Require the `alfrasc\laravel-matomo-tracker` package in your `composer.json` and update your dependencies: 22 | ``` bash 23 | $ composer require alfrasc/laravel-matomo-tracker 24 | ``` 25 | 26 | Publish the config file (optional) 27 | 28 | Run `php artisan vendor:publish` to publish the config file if needed. 29 | ``` bash 30 | $ php artisan vendor:publish 31 | ``` 32 | 33 | Update your `.env` 34 | 35 | Add these variables to your `.env` file and configure it to fit your environment. 36 | ``` bash 37 | [...] 38 | MATOMO_URL="https://your.matomo-install.com" 39 | MATOMO_SITE_ID=1 40 | MATOMO_AUTH_TOKEN="00112233445566778899aabbccddeeff" 41 | MATOMO_QUEUE="matomotracker" 42 | MATOMO_QUEUE_CONNECTION="default" 43 | [...] 44 | ``` 45 | 46 | That's it! 47 | 48 | ## Usage 49 | 50 | You can use the facade to track. 51 | 52 | ``` bash 53 | LaravelMatomoTracker::doTrackPageView('Page Title') 54 | ``` 55 | 56 | ### Tracking 57 | 58 | #### Basic functionality 59 | 60 | Please see the https://developer.matomo.org/api-reference/PHP-Piwik-Tracker page for basic method documentation. 61 | 62 | Additionally there are some Methods to simplyfy the usage: 63 | ``` bash 64 | // instead of using 65 | LaravelMatomoTracker::doTrackAction($actionUrl, 'download') // or 66 | LaravelMatomoTracker::doTrackAction($actionUrl, 'link') 67 | 68 | // you can use this 69 | LaravelMatomoTracker::doTrackDownload($actionUrl); 70 | LaravelMatomoTracker::doTrackOutlink($actionUrl); 71 | ``` 72 | 73 | #### Queues 74 | 75 | For queuing you can use these functions. 76 | ``` bash 77 | LaravelMatomoTracker::queuePageView(string $documentTitle) 78 | LaravelMatomoTracker::queueEvent(string $category, string $action, $name = false, $value = false) 79 | LaravelMatomoTracker::queueContentImpression(string $contentName, string $contentPiece = 'Unknown', $contentTarget = false) 80 | LaravelMatomoTracker::queueContentInteraction(string $interaction, string $contentName, string $contentPiece = 'Unknown', $contentTarget = false) 81 | LaravelMatomoTracker::queueSiteSearch(string $keyword, string $category = '', $countResults = false) 82 | LaravelMatomoTracker::queueGoal($idGoal, $revencue = 0.0) 83 | LaravelMatomoTracker::queueDownload(string $actionUrl) 84 | LaravelMatomoTracker::queueOutlink(string $actionUrl) 85 | LaravelMatomoTracker::queueEcommerceCartUpdate(float $grandTotal) 86 | LaravelMatomoTracker::queueEcommerceOrder(float $orderId, float $grandTotal, float $subTotal = 0.0, float $tax = 0.0, float $shipping = 0.0, float $discount = 0.0) 87 | LaravelMatomoTracker::queueBulkTrack() 88 | ``` 89 | 90 | For setting up queues, find the documentation on https://laravel.com/docs/6.x/queues. 91 | 92 | ### Settings 93 | 94 | Have a look in the https://developer.matomo.org/api-reference/PHP-Piwik-Tracker page for basic settings documentation. 95 | 96 | Additionaly these settings are available: 97 | ``` bash 98 | LaravelMatomoTracker::setCustomDimension(int $id, string $value) // only applicable if the custom dimensions plugin is installed on the Matomo installation 99 | LaravelMatomoTracker::setCustomDimensions([]) // array of custom dimension objects {id: , value: } // bulk insert of custom dimensions and basic type checking 100 | LaravelMatomoTracker::setCustomVariables([]) // array of custom variable objects {id: , name: , value: , scope: } // bulk insert of custom variables and basic type checking 101 | ``` 102 | 103 | ## Change log 104 | 105 | Please see the [changelog](changelog.md) for more information on what has changed recently. 106 | 107 | 108 | ## Contributing 109 | 110 | Please see [contributing.md](contributing.md) for details and a todolist. 111 | 112 | ## Security 113 | 114 | If you discover any security related issues, please email alexander.schmidhuber@gmail.com instead of using the issue tracker. 115 | 116 | ## Credits 117 | 118 | - [Alexander Schmidhuber][link-author] 119 | - [All Contributors][link-contributors] 120 | 121 | ## License 122 | 123 | BSD-3-Clause. Please see the [license file](license.md) for more information. 124 | 125 | [ico-version]: https://img.shields.io/packagist/v/alfrasc/laravel-matomo-tracker.svg?style=flat-square 126 | [ico-downloads]: https://img.shields.io/packagist/dt/alfrasc/laravel-matomo-tracker.svg?style=flat-square 127 | 128 | [link-packagist]: https://packagist.org/packages/alfrasc/laravel-matomo-tracker 129 | [link-downloads]: https://packagist.org/packages/alfrasc/laravel-matomo-tracker 130 | [link-author]: https://github.com/alfrasc 131 | [link-contributors]: ../../contributors 132 | -------------------------------------------------------------------------------- /src/LaravelMatomoTracker.php: -------------------------------------------------------------------------------- 1 | tokenAuth = $tokenAuth ?: config('matomotracker.tokenAuth'); 26 | $this->queue = config('matomotracker.queue', 'matomotracker'); 27 | $this->queueConnection = config('matomotracker.queueConnection', 'default'); 28 | 29 | $this->setTokenAuth(!is_null($tokenAuth) ? $tokenAuth : config('matomotracker.tokenAuth')); 30 | $this->setMatomoVariables($request, $idSite, $apiUrl); 31 | } 32 | 33 | /** 34 | * Overrides the PiwikTracker method and uses the \Illuminate\Http\Request for filling in the server vars. 35 | * 36 | * @param \Illuminate\Http\Request $request 37 | * @param int $idSite 38 | * @param string $apiUrl 39 | * 40 | * @return void 41 | */ 42 | private function setMatomoVariables(Request $request, int $idSite = null, string $apiUrl = null) 43 | { 44 | 45 | $this->apiUrl = $apiUrl ?: config('matomotracker.url'); 46 | $this->idSite = $idSite ?: config('matomotracker.idSite'); 47 | 48 | $this->ecommerceItems = array(); 49 | $this->attributionInfo = false; 50 | $this->eventCustomVar = false; 51 | // force-set time, so queued commands use the right request time 52 | $this->forcedDatetime = time(); 53 | $this->forcedNewVisit = false; 54 | $this->networkTime = false; 55 | $this->serverTime = false; 56 | $this->transferTime = false; 57 | $this->domProcessingTime = false; 58 | $this->domCompletionTime = false; 59 | $this->onLoadTime = false; 60 | $this->pageCustomVar = false; 61 | $this->ecommerceView = array(); 62 | $this->customParameters = array(); 63 | $this->customDimensions = array(); 64 | $this->customData = false; 65 | $this->hasCookies = false; 66 | $this->token_auth = false; 67 | $this->userAgent = false; 68 | $this->country = false; 69 | $this->region = false; 70 | $this->city = false; 71 | $this->lat = false; 72 | $this->long = false; 73 | $this->width = false; 74 | $this->height = false; 75 | $this->plugins = false; 76 | $this->localHour = false; 77 | $this->localMinute = false; 78 | $this->localSecond = false; 79 | $this->idPageview = false; 80 | 81 | // $this->idSite = $this->idSite; 82 | $this->urlReferrer = !empty($request->server('HTTP_REFERER')) ? $request->server('HTTP_REFERER') : false; 83 | $this->pageCharset = self::DEFAULT_CHARSET_PARAMETER_VALUES; 84 | $this->pageUrl = self::getCurrentUrl(); 85 | $this->ip = !empty($request->server('REMOTE_ADDR')) ? $request->server('REMOTE_ADDR') : false; 86 | $this->acceptLanguage = !empty($request->server('HTTP_ACCEPT_LANGUAGE')) ? $request->server('HTTP_ACCEPT_LANGUAGE') : false; 87 | $this->userAgent = !empty($request->server('HTTP_USER_AGENT')) ? $request->server('HTTP_USER_AGENT') : false; 88 | if (!empty($apiUrl)) { 89 | self::$URL = $this->apiUrl; 90 | } 91 | 92 | // Life of the visitor cookie (in sec) 93 | $this->configVisitorCookieTimeout = 33955200; // 13 months (365 + 28 days) 94 | // Life of the session cookie (in sec) 95 | $this->configSessionCookieTimeout = 1800; // 30 minutes 96 | // Life of the session cookie (in sec) 97 | $this->configReferralCookieTimeout = 15768000; // 6 months 98 | 99 | // Visitor Ids in order 100 | $this->userId = false; 101 | $this->forcedVisitorId = false; 102 | $this->cookieVisitorId = false; 103 | $this->randomVisitorId = false; 104 | 105 | $this->setNewVisitorId(); 106 | 107 | $this->configCookiesDisabled = false; 108 | $this->configCookiePath = self::DEFAULT_COOKIE_PATH; 109 | $this->configCookieDomain = ''; 110 | $this->configCookieSameSite = ''; 111 | $this->configCookieSecure = false; 112 | $this->configCookieHTTPOnly = false; 113 | 114 | $this->currentTs = time(); 115 | $this->createTs = $this->currentTs; 116 | $this->visitCount = 0; 117 | $this->currentVisitTs = false; 118 | $this->lastVisitTs = false; 119 | $this->ecommerceLastOrderTimestamp = false; 120 | 121 | // Allow debug while blocking the request 122 | $this->requestTimeout = 600; 123 | $this->doBulkRequests = false; 124 | $this->storedTrackingActions = array(); 125 | 126 | $this->sendImageResponse = true; 127 | 128 | $this->visitorCustomVar = $this->getCustomVariablesFromCookie(); 129 | 130 | $this->outgoingTrackerCookies = array(); 131 | $this->incomingTrackerCookies = array(); 132 | } 133 | 134 | /** 135 | * Sets the queue name 136 | * 137 | * @param string $queueName 138 | * 139 | * @return $this 140 | */ 141 | public function setQueue(string $queueName) 142 | { 143 | $this->queue = $queueName; 144 | return $this; 145 | } 146 | 147 | // Legacy code 148 | // /** 149 | // * Sets a custom dimension 150 | // * 151 | // * @param int $customDimensionId 152 | // * @param string $value 153 | // * 154 | // * @return $this 155 | // */ 156 | // public function setCustomDimension($id, $value) 157 | // { 158 | // $this->setCustomTrackingParameter('dimension' . $id, $value); 159 | // return $this; 160 | // } 161 | 162 | /** 163 | * Sets some custom dimensions 164 | * 165 | * @param array $customDimensions Is an array of objects with the fields 'id' and 'value' 166 | * 167 | * @return $this 168 | */ 169 | public function setCustomDimensions(array $customDimensions) 170 | { 171 | foreach ($customDimensions as $key => $customDimension) { 172 | $this->checkCustomDimension($customDimension); 173 | $this->setCustomDimension($key, $customDimension); 174 | } 175 | 176 | return $this; 177 | } 178 | 179 | /** checks if custom dimension data is correct 180 | * 181 | * @param object $customDimension 182 | * 183 | * @return bool 184 | */ 185 | private function checkCustomDimension(object $customDimension): bool 186 | { 187 | 188 | if (gettype($customDimension) !== 'object') { 189 | throw new Exception('Key is not of type object in custom dimension.'); 190 | } 191 | 192 | if (property_exists($customDimension, 'id')) { 193 | if (gettype($customDimension->id) !== 'integer') { 194 | throw new Exception('Id is not of type integer in custom dimension.'); 195 | } 196 | } else { 197 | throw new Exception('Missing property \'id\' in custom dimension.'); 198 | } 199 | 200 | if (property_exists($customDimension, 'value')) { 201 | if (gettype($customDimension->value) !== 'string') { 202 | throw new Exception('Value is not of type string in custom dimension.'); 203 | } 204 | } else { 205 | throw new Exception('Missing property \'id\' in custom dimension.'); 206 | } 207 | 208 | return true; 209 | } 210 | 211 | /** 212 | * Sets some custom variables 213 | * 214 | * @param array $customVariables 215 | */ 216 | public function setCustomVariables(array $customVariables) 217 | { 218 | foreach ($customVariables as $customVariable) { 219 | $this->checkCustomVariable($customVariable); 220 | 221 | $this->setCustomVariable($customVariable->id, $customVariable->name, $customVariable->value, property_exists($customVariable, 'scope') ? $customVariable->scope : 'visit'); 222 | } 223 | 224 | return $this; 225 | } 226 | 227 | /** checks if custom variable data is correct 228 | * 229 | * @param object $customVariable 230 | * 231 | * @return bool 232 | */ 233 | private function checkCustomVariable(object $customVariable): bool 234 | { 235 | if (gettype($customVariable) !== 'object') { 236 | throw new Exception('Key is not of type object in custom variable.'); 237 | } 238 | 239 | if (property_exists($customVariable, 'id')) { 240 | if (gettype($customVariable->id) !== 'integer') { 241 | throw new Exception('Id is not of type integer in custom variable.'); 242 | } 243 | } else { 244 | throw new Exception('Missing property \'id\' in custom variable.'); 245 | } 246 | 247 | if (property_exists($customVariable, 'name')) { 248 | if (gettype($customVariable->name) !== 'string') { 249 | throw new Exception('Name is not of type string in custom variable.'); 250 | } 251 | } else { 252 | throw new Exception('Missing property \'id\' in custom variable.'); 253 | } 254 | 255 | if (property_exists($customVariable, 'value')) { 256 | if (gettype($customVariable->value) !== 'string') { 257 | throw new Exception('Value is not of type string in custom variable.'); 258 | } 259 | } else { 260 | throw new Exception('Missing property \'id\' in custom variable.'); 261 | } 262 | 263 | if (property_exists($customVariable, 'scope')) { 264 | if (gettype($customVariable->scope) !== 'string') { 265 | throw new Exception('Scope is not of type string in custom variable.'); 266 | } 267 | 268 | if (!array_search($customVariable->scope, ['visit', 'page'])) { 269 | throw new Exception('Scope is not valid in custom variable. Use either \'visit\' or \'page\''); 270 | } 271 | } 272 | 273 | return true; 274 | } 275 | 276 | /** Shorthand for doTrackAction($actionUrl, 'download') 277 | * 278 | * @param string $actionUrl 279 | * 280 | * @return mixed 281 | */ 282 | public function doTrackDownload(string $actionUrl) 283 | { 284 | return $this->doTrackAction($actionUrl, 'download'); 285 | } 286 | 287 | /** Shorthand for doTrackAction($actionUrl, 'link') 288 | * 289 | * @param string $actionUrl 290 | * 291 | * @return mixed 292 | */ 293 | public function doTrackOutlink(string $actionUrl) 294 | { 295 | return $this->doTrackAction($actionUrl, 'link'); 296 | } 297 | 298 | /** Queues a pageview 299 | * 300 | * @param string $documentTitle 301 | * 302 | * @return void 303 | */ 304 | public function queuePageView(string $documentTitle) 305 | { 306 | dispatch(function () use ($documentTitle) { 307 | $this->doTrackPageView($documentTitle); 308 | }) 309 | ->onConnection($this->queueConnection) 310 | ->onQueue($this->queue); 311 | } 312 | 313 | /** Queues an event 314 | * 315 | * @param string $category 316 | * @param string $action 317 | * @param string|bool $name 318 | * @param string|bool $value 319 | * 320 | * @return void 321 | */ 322 | public function queueEvent(string $category, string $action, $name = false, $value = false) 323 | { 324 | dispatch(function () use ($category, $action, $name, $value) { 325 | $this->doTrackEvent($category, $action, $name, $value); 326 | }) 327 | ->onConnection($this->queueConnection) 328 | ->onQueue($this->queue); 329 | } 330 | 331 | /** Queues a content impression 332 | * 333 | * @param string $contentName 334 | * @param string $contentPiece 335 | * @param string|bool $contentTarget 336 | * 337 | * @return void 338 | */ 339 | public function queueContentImpression(string $contentName, string $contentPiece = 'Unknown', $contentTarget = false) 340 | { 341 | dispatch(function () use ($contentName, $contentPiece, $contentTarget) { 342 | $this->doTrackContentImpression($contentName, $contentPiece, $contentTarget); 343 | }) 344 | ->onConnection($this->queueConnection) 345 | ->onQueue($this->queue); 346 | } 347 | 348 | /** Queues a content interaction 349 | * 350 | * @param string $interaction Like 'click' or 'copy' 351 | * @param string $contentName 352 | * @param string $contentPiece 353 | * @param string|bool $contentTarget 354 | * 355 | * @return void 356 | */ 357 | public function queueContentInteraction(string $interaction, string $contentName, string $contentPiece = 'Unknown', $contentTarget = false) 358 | { 359 | dispatch(function () use ($interaction, $contentName, $contentPiece, $contentTarget) { 360 | $this->doTrackContentInteraction($interaction, $contentName, $contentPiece, $contentTarget); 361 | }) 362 | ->onConnection($this->queueConnection) 363 | ->onQueue($this->queue); 364 | } 365 | 366 | /** Queues a site search 367 | * 368 | * @param string $keyword 369 | * @param string $category 370 | * @param int|bool $countResults 371 | * 372 | * @return void 373 | */ 374 | public function queueSiteSearch(string $keyword, string $category = '', $countResults = false) 375 | { 376 | dispatch(function () use ($keyword, $category, $countResults) { 377 | $this->doTrackSiteSearch($keyword, $category, $countResults); 378 | }) 379 | ->onConnection($this->queueConnection) 380 | ->onQueue($this->queue); 381 | } 382 | 383 | /** Queues a goal 384 | * 385 | * @param mixed $idGoal 386 | * @param float $revencue 387 | * 388 | * @return void 389 | */ 390 | public function queueGoal($idGoal, $revencue = 0.0) 391 | { 392 | dispatch(function () use ($idGoal, $revencue) { 393 | $this->doTrackGoal($idGoal, $revencue); 394 | }) 395 | ->onConnection($this->queueConnection) 396 | ->onQueue($this->queue); 397 | } 398 | 399 | /** Queues a download 400 | * 401 | * @param string $actionUrl 402 | * 403 | * @return void 404 | */ 405 | public function queueDownload(string $actionUrl) 406 | { 407 | dispatch(function () use ($actionUrl) { 408 | $this->doTrackDownload($actionUrl); 409 | }) 410 | ->onConnection($this->queueConnection) 411 | ->onQueue($this->queue); 412 | } 413 | 414 | /** Queues a outlink 415 | * 416 | * @param string $actionUrl 417 | * 418 | * @return void 419 | */ 420 | public function queueOutlink(string $actionUrl) 421 | { 422 | dispatch(function () use ($actionUrl) { 423 | $this->doTrackOutlink($actionUrl); 424 | }) 425 | ->onConnection($this->queueConnection) 426 | ->onQueue($this->queue); 427 | } 428 | 429 | /** Queues an ecommerce update 430 | * 431 | * @param float $grandTotal 432 | * 433 | * @return void 434 | */ 435 | public function queueEcommerceCartUpdate(float $grandTotal) 436 | { 437 | dispatch(function () use ($grandTotal) { 438 | $this->doTrackEcommerceCartUpdate($grandTotal); 439 | }) 440 | ->onConnection($this->queueConnection) 441 | ->onQueue($this->queue); 442 | } 443 | 444 | /** Queues a ecommerce order 445 | * 446 | * @param float $orderId 447 | * @param float $grandTotal 448 | * @param float $subTotal 449 | * @param float $tax 450 | * @param float $shipping 451 | * @param float $discount 452 | * 453 | * @return void 454 | */ 455 | public function queueEcommerceOrder( 456 | float $orderId, 457 | float $grandTotal, 458 | float $subTotal = 0.0, 459 | float $tax = 0.0, 460 | float $shipping = 0.0, 461 | float $discount = 0.0 462 | ) { 463 | dispatch(function () use ( 464 | $orderId, 465 | $grandTotal, 466 | $subTotal, 467 | $tax, 468 | $shipping, 469 | $discount 470 | ) { 471 | $this->doTrackEcommerceOrder( 472 | $orderId, 473 | $grandTotal, 474 | $subTotal, 475 | $tax, 476 | $shipping, 477 | $discount 478 | ); 479 | }) 480 | ->onConnection($this->queueConnection) 481 | ->onQueue($this->queue); 482 | } 483 | 484 | /** Queues a bulk track 485 | * 486 | * @return void 487 | */ 488 | public function queueBulkTrack() 489 | { 490 | dispatch(function () { 491 | $this->doBulkTrack(); 492 | }) 493 | ->onConnection($this->queueConnection) 494 | ->onQueue($this->queue); 495 | } 496 | 497 | /** 498 | * Called after unserializing (e.g. after popping from the queue). Re-set 499 | * self::$URL, as only non-static properties have been applied. 500 | */ 501 | public function __wakeup() 502 | { 503 | if (!empty($this->apiUrl)) { 504 | self::$URL = $this->apiUrl; 505 | } 506 | } 507 | } 508 | --------------------------------------------------------------------------------