From 8e25360e8af19d6c75c5f03906b8e34482c210a7 Mon Sep 17 00:00:00 2001 From: alutskevich Date: Thu, 30 May 2024 00:45:36 +0200 Subject: [PATCH] 134 - add types for arguments and return values --- MatomoTracker.php | 530 ++++++++++++++++++++++++++-------------------- 1 file changed, 299 insertions(+), 231 deletions(-) diff --git a/MatomoTracker.php b/MatomoTracker.php index 234c6bf..33fda5f 100644 --- a/MatomoTracker.php +++ b/MatomoTracker.php @@ -210,7 +210,7 @@ class MatomoTracker * @param string $apiUrl "http://example.org/matomo/" or "http://matomo.example.org/" * If set, will overwrite MatomoTracker::$URL */ - public function __construct($idSite, $apiUrl = '') + public function __construct(int $idSite, string $apiUrl = '') { $this->idSite = $idSite; $this->urlReferrer = !empty($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : false; @@ -237,7 +237,7 @@ public function __construct($idSite, $apiUrl = '') $this->visitorCustomVar = $this->getCustomVariablesFromCookie(); } - public function setApiUrl(string $url) + public function setApiUrl(string $url): void { self::$URL = $url; } @@ -248,12 +248,12 @@ public function setApiUrl(string $url) * It is recommended to only send UTF-8 data to Matomo. * If required though, you can also specify another charset using this function. * - * @param string $charset * @return $this */ - public function setPageCharset($charset = '') + public function setPageCharset(string $charset = ''): self { $this->pageCharset = $charset; + return $this; } @@ -263,9 +263,10 @@ public function setPageCharset($charset = '') * @param string $url Raw URL (not URL encoded) * @return $this */ - public function setUrl($url) + public function setUrl(string $url): self { $this->pageUrl = $url; + return $this; } @@ -275,9 +276,10 @@ public function setUrl($url) * @param string $url Raw URL (not URL encoded) * @return $this */ - public function setUrlReferrer($url) + public function setUrlReferrer(string $url): self { $this->urlReferrer = $url; + return $this; } @@ -290,7 +292,7 @@ public function setUrlReferrer($url) * @deprecated this metric is deprecated please use performance timings instead * @see setPerformanceTimings */ - public function setGenerationTime($timeMs) + public function setGenerationTime(int $timeMs): self { return $this; } @@ -307,21 +309,28 @@ public function setGenerationTime($timeMs) * @param null|int $onload Onload time in ms (loadEventEnd – loadEventStart) * @return $this */ - public function setPerformanceTimings($network = null, $server = null, $transfer = null, $domProcessing = null, $domCompletion = null, $onload = null) - { + public function setPerformanceTimings( + ?int $network = null, + ?int $server = null, + ?int $transfer = null, + ?int $domProcessing = null, + ?int $domCompletion = null, + ?int $onload = null + ): self { $this->networkTime = $network; $this->serverTime = $server; $this->transferTime = $transfer; $this->domProcessingTime = $domProcessing; $this->domCompletionTime = $domCompletion; $this->onLoadTime = $onload; + return $this; } /** * Clear / reset all previously set performance metrics. */ - public function clearPerformanceTimings() + public function clearPerformanceTimings(): void { $this->networkTime = false; $this->serverTime = false; @@ -335,9 +344,10 @@ public function clearPerformanceTimings() * @deprecated * @ignore */ - public function setUrlReferer($url) + public function setUrlReferer(string $url): self { $this->setUrlReferrer($url); + return $this; } @@ -356,13 +366,14 @@ public function setUrlReferer($url) * @throws Exception * @see function getAttributionInfo() in https://github.com/matomo-org/matomo/blob/master/js/matomo.js */ - public function setAttributionInfo($jsonEncoded) + public function setAttributionInfo(string $jsonEncoded): self { $decoded = json_decode($jsonEncoded, $assoc = true); if (!is_array($decoded)) { throw new Exception("setAttributionInfo() is expecting a JSON encoded string, $jsonEncoded given"); } $this->attributionInfo = $decoded; + return $this; } @@ -377,16 +388,17 @@ public function setAttributionInfo($jsonEncoded) * @return $this * @throws Exception */ - public function setCustomVariable($id, $name, $value, $scope = 'visit') - { - if (!is_int($id)) { - throw new Exception("Parameter id to setCustomVariable should be an integer"); - } - if ($scope == 'page') { + public function setCustomVariable( + int $id, + string $name, + string $value, + string $scope = 'visit' + ): self { + if ($scope === 'page') { $this->pageCustomVar[$id] = array($name, $value); - } elseif ($scope == 'event') { + } elseif ($scope === 'event') { $this->eventCustomVar[$id] = array($name, $value); - } elseif ($scope == 'visit') { + } elseif ($scope === 'visit') { $this->visitorCustomVar[$id] = array($name, $value); } else { throw new Exception("Invalid 'scope' parameter value"); @@ -407,28 +419,29 @@ public function setCustomVariable($id, $name, $value, $scope = 'visit') * @return mixed An array with this format: array( 0 => CustomVariableName, 1 => CustomVariableValue ) or false * @see matomo.js getCustomVariable() */ - public function getCustomVariable($id, $scope = 'visit') + public function getCustomVariable(int $id, string $scope = 'visit') { - if ($scope == 'page') { - return isset($this->pageCustomVar[$id]) ? $this->pageCustomVar[$id] : false; - } elseif ($scope == 'event') { - return isset($this->eventCustomVar[$id]) ? $this->eventCustomVar[$id] : false; - } else { - if ($scope != 'visit') { - throw new Exception("Invalid 'scope' parameter value"); - } + if ($scope === 'page') { + return $this->pageCustomVar[$id] ?? false; + } + + if ($scope === 'event') { + return $this->eventCustomVar[$id] ?? false; } + + if ($scope !== 'visit') { + throw new Exception("Invalid 'scope' parameter value"); + } + if (!empty($this->visitorCustomVar[$id])) { return $this->visitorCustomVar[$id]; } $cookieDecoded = $this->getCustomVariablesFromCookie(); - if (!is_int($id)) { - throw new Exception("Parameter to getCustomVariable should be an integer"); - } + if (!is_array($cookieDecoded) || !isset($cookieDecoded[$id]) || !is_array($cookieDecoded[$id]) - || count($cookieDecoded[$id]) != 2 + || count($cookieDecoded[$id]) !== 2 ) { return false; } @@ -442,7 +455,7 @@ public function getCustomVariable($id, $scope = 'visit') * This can be useful when you have enabled bulk requests, * and you wish to clear Custom Variables of 'visit' scope. */ - public function clearCustomVariables() + public function clearCustomVariables(): void { $this->visitorCustomVar = []; $this->pageCustomVar = []; @@ -456,16 +469,17 @@ public function clearCustomVariables() * @param string $value value for custom dimension * @return $this */ - public function setCustomDimension($id, $value) + public function setCustomDimension(int $id, string $value): self { - $this->customDimensions['dimension'.(int)$id] = $value; + $this->customDimensions['dimension'.$id] = $value; + return $this; } /** * Clears all previously set custom dimensions */ - public function clearCustomDimensions() + public function clearCustomDimensions(): void { $this->customDimensions = []; } @@ -476,9 +490,9 @@ public function clearCustomDimensions() * @param int $id id of custom dimension * @return string|null */ - public function getCustomDimension($id) + public function getCustomDimension(int $id): ?string { - return $this->customDimensions['dimension'.(int)$id] ?? null; + return $this->customDimensions['dimension'.$id] ?? null; } /** @@ -491,48 +505,51 @@ public function getCustomDimension($id) * @return $this * @throws Exception */ - public function setCustomTrackingParameter($trackingApiParameter, $value) + public function setCustomTrackingParameter(string $trackingApiParameter, string $value): self { $matches = []; if (preg_match('/^dimension([0-9]+)$/', $trackingApiParameter, $matches)) { $this->setCustomDimension($matches[1], $value); + return $this; } $this->customParameters[$trackingApiParameter] = $value; + return $this; } /** * Clear / reset all previously set custom tracking parameters. */ - public function clearCustomTrackingParameters() + public function clearCustomTrackingParameters(): void { - $this->customParameters = array(); + $this->customParameters = []; } /** * Sets the current visitor ID to a random new one. * @return $this */ - public function setNewVisitorId() + public function setNewVisitorId(): self { $this->randomVisitorId = substr(md5(uniqid(rand(), true)), 0, self::LENGTH_VISITOR_ID); $this->forcedVisitorId = false; $this->cookieVisitorId = false; + return $this; } /** * Sets the current site ID. * - * @param int $idSite * @return $this */ - public function setIdSite($idSite) + public function setIdSite(int $idSite): self { $this->idSite = $idSite; + return $this; } @@ -542,9 +559,10 @@ public function setIdSite($idSite) * @param string $acceptLanguage For example "fr-fr" * @return $this */ - public function setBrowserLanguage($acceptLanguage) + public function setBrowserLanguage(string $acceptLanguage): self { $this->acceptLanguage = $acceptLanguage; + return $this; } @@ -555,9 +573,10 @@ public function setBrowserLanguage($acceptLanguage) * @param string $userAgent * @return $this */ - public function setUserAgent($userAgent) + public function setUserAgent(string $userAgent): self { $this->userAgent = $userAgent; + return $this; } @@ -570,15 +589,20 @@ public function setUserAgent($userAgent) * @param string $model Value of the header 'HTTP_SEC_CH_UA_MODEL' * @param string $platform Value of the header 'HTTP_SEC_CH_UA_PLATFORM' * @param string $platformVersion Value of the header 'HTTP_SEC_CH_UA_PLATFORM_VERSION' - * @param string|array $fullVersionList Value of header 'HTTP_SEC_CH_UA_FULL_VERSION_LIST' or an array containing - * all brands with the structure - * [['brand' => 'Chrome', 'version' => '10.0.2'], ['brand' => '...] + * @param string|array $fullVersionList Value of header 'HTTP_SEC_CH_UA_FULL_VERSION_LIST' + * or an array containing all brands with the structure + * [['brand' => 'Chrome', 'version' => '10.0.2'], ['brand' => '...] * @param string $uaFullVersion Value of the header 'HTTP_SEC_CH_UA_FULL_VERSION' * * @return $this */ - public function setClientHints($model = '', $platform = '', $platformVersion = '', $fullVersionList = '', $uaFullVersion = '') - { + public function setClientHints( + string $model = '', + string $platform = '', + string $platformVersion = '', + $fullVersionList = '', + string $uaFullVersion = '' + ): self { if (is_string($fullVersionList)) { $reg = '/^"([^"]+)"; ?v="([^"]+)"(?:, )?/'; $list = []; @@ -609,12 +633,13 @@ public function setClientHints($model = '', $platform = '', $platformVersion = ' * using either the visitor's IP address or language. * * Allowed only for Admin/Super User, must be used along with setTokenAuth(). - * @param string $country + * * @return $this */ - public function setCountry($country) + public function setCountry(string $country): self { $this->country = $country; + return $this; } @@ -623,12 +648,13 @@ public function setCountry($country) * using the visitor's IP address (if configured to do so). * * Allowed only for Admin/Super User, must be used along with setTokenAuth(). - * @param string $region + * * @return $this */ - public function setRegion($region) + public function setRegion(string $region): self { $this->region = $region; + return $this; } @@ -637,12 +663,13 @@ public function setRegion($region) * using the visitor's IP address (if configured to do so). * * Allowed only for Admin/Super User, must be used along with setTokenAuth(). - * @param string $city + * * @return $this */ - public function setCity($city) + public function setCity(string $city): self { $this->city = $city; + return $this; } @@ -651,12 +678,13 @@ public function setCity($city) * latitude using the visitor's IP address (if configured to do so). * * Allowed only for Admin/Super User, must be used along with setTokenAuth(). - * @param float $lat + * * @return $this */ - public function setLatitude($lat) + public function setLatitude(float $lat): self { $this->lat = $lat; + return $this; } @@ -665,21 +693,21 @@ public function setLatitude($lat) * longitude using the visitor's IP address (if configured to do so). * * Allowed only for Admin/Super User, must be used along with setTokenAuth(). - * @param float $long + * * @return $this */ - public function setLongitude($long) + public function setLongitude(float $long): self { $this->long = $long; + return $this; } /** * Enables the bulk request feature. When used, each tracking action is stored until the * doBulkTrack method is called. This method will send all tracking data at once. - * */ - public function enableBulkTracking() + public function enableBulkTracking(): void { $this->doBulkRequests = true; } @@ -687,9 +715,8 @@ public function enableBulkTracking() /** * Disables the bulk request feature. Make sure to call `doBulkTrack()` before disabling it if you have stored * tracking actions previously as this method won't be sending any previously stored actions before disabling it. - * */ - public function disableBulkTracking() + public function disableBulkTracking(): void { $this->doBulkRequests = false; } @@ -704,8 +731,13 @@ public function disableBulkTracking() * @param bool $httpOnly (optional) Set HTTPOnly flag for cookies * @param string $sameSite (optional) Set SameSite flag for cookies */ - public function enableCookies($domain = '', $path = '/', $secure = false, $httpOnly = false, $sameSite = '') - { + public function enableCookies( + string $domain = '', + string $path = '/', + bool $secure = false, + bool $httpOnly = false, + string $sameSite = '' + ): void { $this->configCookiesDisabled = false; $this->configCookieDomain = self::domainFixup($domain); $this->configCookiePath = $path; @@ -717,7 +749,7 @@ public function enableCookies($domain = '', $path = '/', $secure = false, $httpO /** * If image response is disabled Matomo will respond with a HTTP 204 header instead of responding with a gif. */ - public function disableSendImageResponse() + public function disableSendImageResponse(): void { $this->sendImageResponse = false; } @@ -744,15 +776,16 @@ protected static function domainFixup($domain) /** * Get cookie name with prefix and domain hash - * @param string $cookieName - * @return string */ - protected function getCookieName($cookieName) + protected function getCookieName(string $cookieName): string { // NOTE: If the cookie name is changed, we must also update the method in matomo.js with the same name. $hash = substr( sha1( - ($this->configCookieDomain == '' ? self::getCurrentHost() : $this->configCookieDomain) . $this->configCookiePath + ($this->configCookieDomain === '' + ? self::getCurrentHost() + : $this->configCookieDomain + ) . $this->configCookiePath ), 0, 4 @@ -767,7 +800,7 @@ protected function getCookieName($cookieName) * @param string $documentTitle Page title as it will appear in the Actions > Page titles report * @return mixed Response string or true if using bulk requests. */ - public function doTrackPageView($documentTitle) + public function doTrackPageView(string $documentTitle) { if (!$this->idPageviewSetManually) { $this->generateNewPageviewId(); @@ -781,10 +814,8 @@ public function doTrackPageView($documentTitle) /** * Override PageView id for every use of `doTrackPageView()`. Do not use this if you call `doTrackPageView()` * multiple times during tracking (if, for example, you are tracking a single page application). - * - * @param string $idPageview */ - public function setPageviewId($idPageview) + public function setPageviewId(string $idPageview): void { $this->idPageview = $idPageview; $this->idPageviewSetManually = true; @@ -795,14 +826,14 @@ public function setPageviewId($idPageview) * If the id was not set manually, the id that was automatically generated in last `doTrackPageView()` will * be returned. If there was no last page view, this will be false. * - * @return mixed The PageView id as string or false if there is none yet. + * @return string|false The PageView id as string or false if there is none yet. */ public function getPageviewId() { return $this->idPageview; } - private function generateNewPageviewId() + private function generateNewPageviewId(): void { $this->idPageview = substr(md5(uniqid(rand(), true)), 0, 6); } @@ -816,8 +847,12 @@ private function generateNewPageviewId() * @param float|bool $value (optional) The Event's value * @return mixed Response string or true if using bulk requests. */ - public function doTrackEvent($category, $action, $name = false, $value = false) - { + public function doTrackEvent( + string $category, + string $action, + $name = false, + $value = false + ) { $url = $this->getUrlTrackEvent($category, $action, $name, $value); return $this->sendRequest($url); @@ -831,8 +866,11 @@ public function doTrackEvent($category, $action, $name = false, $value = false) * @param string|bool $contentTarget (optional) The target of the content. For instance the URL of a landing page. * @return mixed Response string or true if using bulk requests. */ - public function doTrackContentImpression($contentName, $contentPiece = 'Unknown', $contentTarget = false) - { + public function doTrackContentImpression( + string $contentName, + string $contentPiece = 'Unknown', + $contentTarget = false + ) { $url = $this->getUrlTrackContentImpression($contentName, $contentPiece, $contentTarget); return $this->sendRequest($url); @@ -849,12 +887,11 @@ public function doTrackContentImpression($contentName, $contentPiece = 'Unknown' * @return mixed Response string or true if using bulk requests. */ public function doTrackContentInteraction( - $interaction, - $contentName, - $contentPiece = 'Unknown', + string $interaction, + string $contentName, + string $contentPiece = 'Unknown', $contentTarget = false - ) - { + ) { $url = $this->getUrlTrackContentInteraction($interaction, $contentName, $contentPiece, $contentTarget); return $this->sendRequest($url); @@ -870,8 +907,11 @@ public function doTrackContentInteraction( * * @return mixed Response or true if using bulk requests. */ - public function doTrackSiteSearch($keyword, $category = '', $countResults = false) - { + public function doTrackSiteSearch( + string $keyword, + string $category = '', + $countResults = false + ) { $url = $this->getUrlTrackSiteSearch($keyword, $category, $countResults); return $this->sendRequest($url); @@ -884,7 +924,7 @@ public function doTrackSiteSearch($keyword, $category = '', $countResults = fals * @param float $revenue Revenue for this conversion * @return mixed Response or true if using bulk request */ - public function doTrackGoal($idGoal, $revenue = 0.0) + public function doTrackGoal(int $idGoal, float $revenue = 0.0) { $url = $this->getUrlTrackGoal($idGoal, $revenue); @@ -898,7 +938,7 @@ public function doTrackGoal($idGoal, $revenue = 0.0) * @param string $actionType Type of the action: 'download' or 'link' * @return mixed Response or true if using bulk request */ - public function doTrackAction($actionUrl, $actionType) + public function doTrackAction(string $actionUrl, string $actionType) { // Referrer could be udpated to be the current URL temporarily (to mimic JS behavior) $url = $this->getUrlTrackAction($actionUrl, $actionType); @@ -922,8 +962,13 @@ public function doTrackAction($actionUrl, $actionType) * @throws Exception * @return $this */ - public function addEcommerceItem($sku, $name = '', $category = '', $price = 0.0, $quantity = 1) - { + public function addEcommerceItem( + string $sku, + string $name = '', + $category = '', + $price = 0.0, + int $quantity = 1 + ): self { if (empty($sku)) { throw new Exception("You must specify a SKU for the Ecommerce item"); } @@ -931,6 +976,7 @@ public function addEcommerceItem($sku, $name = '', $category = '', $price = 0.0, $price = $this->forceDotAsSeparatorForDecimalPoint($price); $this->ecommerceItems[] = array($sku, $name, $category, $price, $quantity); + return $this; } @@ -944,7 +990,7 @@ public function addEcommerceItem($sku, $name = '', $category = '', $price = 0.0, * @param float $grandTotal Cart grandTotal (typically the sum of all items' prices) * @return mixed Response or true if using bulk request */ - public function doTrackEcommerceCartUpdate($grandTotal) + public function doTrackEcommerceCartUpdate(float $grandTotal) { $url = $this->getUrlTrackEcommerceCartUpdate($grandTotal); @@ -968,7 +1014,7 @@ public function doBulkTrack() ); } - $data = array('requests' => $this->storedTrackingActions); + $data = ['requests' => $this->storedTrackingActions]; // token_auth is not required by default, except if bulk_requests_require_authentication=1 if (!empty($this->token_auth)) { @@ -978,7 +1024,7 @@ public function doBulkTrack() $postData = json_encode($data); $response = $this->sendRequest($this->getBaseUrl(), 'POST', $postData, $force = true); - $this->storedTrackingActions = array(); + $this->storedTrackingActions = []; return $response; } @@ -1002,13 +1048,12 @@ public function doBulkTrack() */ public function doTrackEcommerceOrder( $orderId, - $grandTotal, - $subTotal = 0.0, - $tax = 0.0, - $shipping = 0.0, - $discount = 0.0 - ) - { + float $grandTotal, + float $subTotal = 0.0, + float $tax = 0.0, + float $shipping = 0.0, + float $discount = 0.0 + ) { $url = $this->getUrlTrackEcommerceOrder($orderId, $grandTotal, $subTotal, $tax, $shipping, $discount); return $this->sendRequest($url); @@ -1017,20 +1062,20 @@ public function doTrackEcommerceOrder( /** * Tracks a PHP Throwable a crash (requires CrashAnalytics to be enabled in the target Matomo) * - * @param Throwable $ex (required) the throwable to track. The message, stack trace, file location and line number + * @param Throwable $throwable (required) the throwable to track. The message, stack trace, file location and line number * of the crash are deduced from this parameter. The crash type is set to the class name of * the Throwable. * @param string|null $category (optional) a category value for this crash. This can be any information you want * to attach to the crash. * @return mixed Response or true if using bulk request */ - public function doTrackPhpThrowable(\Throwable $ex, $category = null) + public function doTrackPhpThrowable(Throwable $throwable, ?string $category = null) { - $message = $ex->getMessage(); - $stack = $ex->getTraceAsString(); - $type = get_class($ex); - $location = $ex->getFile(); - $line = $ex->getLine(); + $message = $throwable->getMessage(); + $stack = $throwable->getTraceAsString(); + $type = get_class($throwable); + $location = $throwable->getFile(); + $line = $throwable->getLine(); return $this->doTrackCrash($message, $type, $category, $stack, $location, $line); } @@ -1048,8 +1093,15 @@ public function doTrackPhpThrowable(\Throwable $ex, $category = null) * @param int|null $column (optional) the source file column where the crash originated. * @return mixed Response or true if using bulk request */ - public function doTrackCrash($message, $type = null, $category = null, $stack = null, $location = null, $line = null, $column = null) - { + public function doTrackCrash( + string $message, + ?string $type = null, + ?string $category = null, + ?string $stack = null, + ?string $location = null, + ?int $line = null, + ?int $column = null + ) { $url = $this->getUrlTrackCrash($message, $type, $category, $stack, $location, $line, $column); return $this->sendRequest($url); @@ -1089,8 +1141,12 @@ public function doPing() * @param float $price Specify the price at which the item was displayed * @return $this */ - public function setEcommerceView($sku = '', $name = '', $category = '', $price = 0.0) - { + public function setEcommerceView( + string $sku = '', + string $name = '', + $category = '', + float $price = 0.0 + ): self { $this->ecommerceView = []; if (!empty($category)) { @@ -1103,7 +1159,6 @@ public function setEcommerceView($sku = '', $name = '', $category = '', $price = $this->ecommerceView['_pkc'] = $category; if (!empty($price)) { - $price = (float)$price; $price = $this->forceDotAsSeparatorForDecimalPoint($price); $this->ecommerceView['_pkp'] = $price; } @@ -1116,9 +1171,10 @@ public function setEcommerceView($sku = '', $name = '', $category = '', $price = $this->ecommerceView['_pks'] = $sku; } if (empty($name)) { - $name = ""; + $name = ''; } $this->ecommerceView['_pkn'] = $name; + return $this; } @@ -1127,9 +1183,8 @@ public function setEcommerceView($sku = '', $name = '', $category = '', $price = * If for instance a German locale is used it would be a comma otherwise. * * @param float|string $value - * @return string */ - private function forceDotAsSeparatorForDecimalPoint($value) + private function forceDotAsSeparatorForDecimalPoint($value): string { if (null === $value || false === $value) { return $value; @@ -1146,9 +1201,7 @@ private function forceDotAsSeparatorForDecimalPoint($value) */ public function getUrlTrackEcommerceCartUpdate($grandTotal) { - $url = $this->getUrlTrackEcommerce($grandTotal); - - return $url; + return $this->getUrlTrackEcommerce($grandTotal); } /** @@ -1164,8 +1217,7 @@ public function getUrlTrackEcommerceOrder( $tax = 0.0, $shipping = 0.0, $discount = 0.0 - ) - { + ) { if (empty($orderId)) { throw new Exception("You must specifiy an orderId for the Ecommerce order"); } @@ -1226,7 +1278,7 @@ protected function getUrlTrackEcommerce($grandTotal, $subTotal = 0.0, $tax = 0.0 * @param string $documentTitle Page view name as it will appear in Matomo reports * @return string URL to matomo.php with all parameters set to track the pageview */ - public function getUrlTrackPageView($documentTitle = '') + public function getUrlTrackPageView(string $documentTitle = ''): string { $url = $this->getRequest($this->idSite); if (strlen($documentTitle) > 0) { @@ -1247,13 +1299,17 @@ public function getUrlTrackPageView($documentTitle = '') * @return string URL to matomo.php with all parameters set to track the pageview * @throws */ - public function getUrlTrackEvent($category, $action, $name = false, $value = false) - { + public function getUrlTrackEvent( + string $category, + string $action, + $name = false, + $value = false + ): string { $url = $this->getRequest($this->idSite); - if (strlen($category) == 0) { + if (strlen($category) === 0) { throw new Exception("You must specify an Event Category name (Music, Videos, Games...)."); } - if (strlen($action) == 0) { + if (strlen($action) === 0) { throw new Exception("You must specify an Event action (click, view, add...)."); } @@ -1281,11 +1337,14 @@ public function getUrlTrackEvent($category, $action, $name = false, $value = fal * @throws Exception In case $contentName is empty * @return string URL to matomo.php with all parameters set to track the pageview */ - public function getUrlTrackContentImpression($contentName, $contentPiece, $contentTarget) - { + public function getUrlTrackContentImpression( + string $contentName, + string $contentPiece, + $contentTarget + ): string { $url = $this->getRequest($this->idSite); - if (strlen($contentName) == 0) { + if (strlen($contentName) === 0) { throw new Exception("You must specify a content name"); } @@ -1312,15 +1371,19 @@ public function getUrlTrackContentImpression($contentName, $contentPiece, $conte * @throws Exception In case $interaction or $contentName is empty * @return string URL to matomo.php with all parameters set to track the pageview */ - public function getUrlTrackContentInteraction($interaction, $contentName, $contentPiece, $contentTarget) - { + public function getUrlTrackContentInteraction( + string $interaction, + string $contentName, + string $contentPiece, + $contentTarget + ): string { $url = $this->getRequest($this->idSite); - if (strlen($interaction) == 0) { + if (strlen($interaction) === 0) { throw new Exception("You must specify a name for the interaction"); } - if (strlen($contentName) == 0) { + if (strlen($contentName) === 0) { throw new Exception("You must specify a content name"); } @@ -1341,12 +1404,8 @@ public function getUrlTrackContentInteraction($interaction, $contentName, $conte * Builds URL to track a site search. * * @see doTrackSiteSearch() - * @param string $keyword - * @param string $category - * @param int $countResults - * @return string */ - public function getUrlTrackSiteSearch($keyword, $category, $countResults) + public function getUrlTrackSiteSearch(string $keyword, string $category, int $countResults): string { $url = $this->getRequest($this->idSite); $url .= '&search=' . urlencode($keyword); @@ -1368,7 +1427,7 @@ public function getUrlTrackSiteSearch($keyword, $category, $countResults) * @param float $revenue Revenue for this conversion * @return string URL to matomo.php with all parameters set to track the goal conversion */ - public function getUrlTrackGoal($idGoal, $revenue = 0.0) + public function getUrlTrackGoal(int $idGoal, float $revenue = 0.0): string { $url = $this->getRequest($this->idSite); $url .= '&idgoal=' . $idGoal; @@ -1388,7 +1447,7 @@ public function getUrlTrackGoal($idGoal, $revenue = 0.0) * @param string $actionType Type of the action: 'download' or 'link' * @return string URL to matomo.php with all parameters set to track an action */ - public function getUrlTrackAction($actionUrl, $actionType) + public function getUrlTrackAction(string $actionUrl, string $actionType): string { $url = $this->getRequest($this->idSite); $url .= '&' . $actionType . '=' . urlencode($actionUrl); @@ -1410,8 +1469,15 @@ public function getUrlTrackAction($actionUrl, $actionType) * @param int|null $column (optional) the source file column where the crash originated. * @return string URL to matomo.php with all parameters set to track an action */ - public function getUrlTrackCrash($message, $type = null, $category = null, $stack = null, $location = null, $line = null, $column = null) - { + public function getUrlTrackCrash( + string $message, + ?string $type = null, + ?string $category = null, + ?string $stack = null, + ?string $location = null, + ?int $line = null, + ?int $column = null + ): string { $url = $this->getRequest($this->idSite); $url .= '&ca=1&cra=' . urlencode($message); if ($type) { @@ -1447,9 +1513,10 @@ public function getUrlTrackCrash($message, $type = null, $category = null, $stac * If the datetime is older than one day (default value for tracking_requests_require_authentication_when_custom_timestamp_newer_than), then you must call setTokenAuth() with a valid Admin/Super user token. * @return $this */ - public function setForceVisitDateTime($dateTime) + public function setForceVisitDateTime(string $dateTime): self { $this->forcedDatetime = $dateTime; + return $this; } @@ -1460,9 +1527,10 @@ public function setForceVisitDateTime($dateTime) * If you call setForceNewVisit() before calling doTrack*, then a new visit will be created for this request. * @return $this */ - public function setForceNewVisit() + public function setForceNewVisit(): self { $this->forcedNewVisit = true; + return $this; } @@ -1474,9 +1542,10 @@ public function setForceNewVisit() * @param string $ip IP string, eg. 130.54.2.1 * @return $this */ - public function setIp($ip) + public function setIp(string $ip): self { $this->ip = $ip; + return $this; } @@ -1489,12 +1558,13 @@ public function setIp($ip) * @return $this * @throws Exception */ - public function setUserId($userId) + public function setUserId(string $userId): self { if ($userId === '') { throw new Exception("User ID cannot be empty."); } $this->userId = $userId; + return $this; } @@ -1503,10 +1573,9 @@ public function setUserId($userId) * * Note: matches implementation of Tracker\Request->getUserIdHashed() * - * @param $id * @return string */ - public static function getUserIdHashed($id) + public static function getUserIdHashed($id): string { return substr(sha1($id), 0, 16); } @@ -1523,10 +1592,10 @@ public static function getUserIdHashed($id) * @return $this * @throws Exception */ - public function setVisitorId($visitorId) + public function setVisitorId(string $visitorId): self { $hexChars = '01234567890abcdefABCDEF'; - if (strlen($visitorId) != self::LENGTH_VISITOR_ID + if (strlen($visitorId) !== self::LENGTH_VISITOR_ID || strspn($visitorId, $hexChars) !== strlen($visitorId) ) { throw new Exception( @@ -1538,6 +1607,7 @@ public function setVisitorId($visitorId) ); } $this->forcedVisitorId = $visitorId; + return $this; } @@ -1599,14 +1669,14 @@ public function getUserId() * * @return bool True if cookie exists and is valid, False otherwise */ - protected function loadVisitorIdCookie() + protected function loadVisitorIdCookie(): bool { $idCookie = $this->getCookieMatchingName('id'); if ($idCookie === false) { return false; } $parts = explode('.', $idCookie); - if (strlen($parts[0]) != self::LENGTH_VISITOR_ID) { + if (strlen($parts[0]) !== self::LENGTH_VISITOR_ID) { return false; } @@ -1621,7 +1691,7 @@ protected function loadVisitorIdCookie() /** * Deletes all first party cookies from the client */ - public function deleteCookies() + public function deleteCookies(): void { $cookies = array('id', 'ses', 'cvar', 'ref'); foreach ($cookies as $cookie) { @@ -1659,9 +1729,10 @@ public function getAttributionInfo() * @param string $token_auth token_auth 32 chars token_auth string * @return $this */ - public function setTokenAuth($token_auth) + public function setTokenAuth(string $token_auth): self { $this->token_auth = $token_auth; + return $this; } @@ -1671,12 +1742,13 @@ public function setTokenAuth($token_auth) * @param string $time HH:MM:SS format * @return $this */ - public function setLocalTime($time) + public function setLocalTime(string $time): self { - list($hour, $minute, $second) = explode(':', $time); + [$hour, $minute, $second] = explode(':', $time); $this->localHour = (int)$hour; $this->localMinute = (int)$minute; $this->localSecond = (int)$second; + return $this; } @@ -1687,10 +1759,11 @@ public function setLocalTime($time) * @param int $height * @return $this */ - public function setResolution($width, $height) + public function setResolution(int $width, int $height): self { $this->width = $width; $this->height = $height; + return $this; } @@ -1698,48 +1771,41 @@ public function setResolution($width, $height) * Sets if the browser supports cookies * This is reported in "List of plugins" report in Matomo. * - * @param bool $bool * @return $this */ - public function setBrowserHasCookies($bool) + public function setBrowserHasCookies(bool $hasCookies): self { - $this->hasCookies = $bool; + $this->hasCookies = $hasCookies; + return $this; } /** * Will append a custom string at the end of the Tracking request. - * @param string $string + * * @return $this */ - public function setDebugStringAppend($string) + public function setDebugStringAppend(string $debugString): self { - $this->DEBUG_APPEND_URL = '&' . $string; + $this->DEBUG_APPEND_URL = '&' . $debugString; + return $this; } /** * Sets visitor browser supported plugins * - * @param bool $flash - * @param bool $java - * @param bool $quickTime - * @param bool $realPlayer - * @param bool $pdf - * @param bool $windowsMedia - * @param bool $silverlight * @return $this */ public function setPlugins( - $flash = false, - $java = false, - $quickTime = false, - $realPlayer = false, - $pdf = false, - $windowsMedia = false, - $silverlight = false - ) - { + bool $flash = false, + bool $java = false, + bool $quickTime = false, + bool $realPlayer = false, + bool $pdf = false, + bool $windowsMedia = false, + bool $silverlight = false + ): self { $this->plugins = '&fla=' . (int)$flash . '&java=' . (int)$java . @@ -1748,6 +1814,7 @@ public function setPlugins( '&pdf=' . (int)$pdf . '&wma=' . (int)$windowsMedia . '&ag=' . (int)$silverlight; + return $this; } @@ -1756,7 +1823,7 @@ public function setPlugins( * from the request and write updated cookies in the response (using setrawcookie). * This can be disabled by calling this function. */ - public function disableCookieSupport() + public function disableCookieSupport(): void { $this->configCookiesDisabled = true; } @@ -1765,7 +1832,7 @@ public function disableCookieSupport() * Returns the maximum number of seconds the tracker will spend waiting for a response * from Matomo. Defaults to 600 seconds. */ - public function getRequestTimeout() + public function getRequestTimeout(): int { return $this->requestTimeout; } @@ -1774,17 +1841,17 @@ public function getRequestTimeout() * Sets the maximum number of seconds that the tracker will spend waiting for a response * from Matomo. * - * @param int $timeout * @return $this * @throws Exception */ - public function setRequestTimeout($timeout) + public function setRequestTimeout(int $timeout): self { - if (!is_int($timeout) || $timeout < 0) { + if ($timeout < 0) { throw new Exception("Invalid value supplied for request timeout: $timeout"); } $this->requestTimeout = $timeout; + return $this; } @@ -1792,7 +1859,7 @@ public function setRequestTimeout($timeout) * Returns the maximum number of seconds the tracker will spend trying to connect to Matomo. * Defaults to 300 seconds. */ - public function getRequestConnectTimeout() + public function getRequestConnectTimeout(): int { return $this->requestConnectTimeout; } @@ -1804,13 +1871,14 @@ public function getRequestConnectTimeout() * @return $this * @throws Exception */ - public function setRequestConnectTimeout($timeout) + public function setRequestConnectTimeout(int $timeout): self { - if (!is_int($timeout) || $timeout < 0) { + if ($timeout < 0) { throw new Exception("Invalid value supplied for request connect timeout: $timeout"); } $this->requestConnectTimeout = $timeout; + return $this; } @@ -1823,18 +1891,18 @@ public function setRequestConnectTimeout($timeout) * @param string $method Either 'POST' or 'GET' * @return $this */ - public function setRequestMethodNonBulk($method) + public function setRequestMethodNonBulk(string $method): self { $this->requestMethod = strtoupper($method) === 'POST' ? 'POST' : 'GET'; + return $this; } /** * If a proxy is needed to look up the address of the Matomo site, set it with this * @param string $proxy IP as string, for example "173.234.92.107" - * @param int $proxyPort */ - public function setProxy($proxy, $proxyPort = 80) + public function setProxy(string $proxy, int $proxyPort = 80): void { $this->proxy = $proxy; $this->proxyPort = $proxyPort; @@ -1844,7 +1912,7 @@ public function setProxy($proxy, $proxyPort = 80) * If the proxy IP and the proxy port have been set, with the setProxy() function * returns a string, like "173.234.92.107:80" */ - private function getProxy() + private function getProxy(): ?string { if (isset($this->proxy) && isset($this->proxyPort)) { return $this->proxy.":".$this->proxyPort; @@ -1861,20 +1929,26 @@ private function getProxy() /** * Returns array of curl options for request + * + * @return array */ - protected function prepareCurlOptions($url, $method, $data, $forcePostUrlEncoded) - { - $options = array( + protected function prepareCurlOptions( + string $url, + string $method, + $data, + bool $forcePostUrlEncoded + ): array { + $options = [ CURLOPT_URL => $url, CURLOPT_USERAGENT => $this->userAgent, CURLOPT_HEADER => true, CURLOPT_TIMEOUT => $this->requestTimeout, CURLOPT_CONNECTTIMEOUT => $this->requestConnectTimeout, CURLOPT_RETURNTRANSFER => true, - CURLOPT_HTTPHEADER => array( + CURLOPT_HTTPHEADER => [ 'Accept-Language: ' . $this->acceptLanguage, - ), - ); + ], + ]; if ($method === 'GET') { $options[CURLOPT_FOLLOWLOCATION] = true; @@ -1922,17 +1996,19 @@ protected function prepareCurlOptions($url, $method, $data, $forcePostUrlEncoded /** * Returns array of stream options for request + * + * @return array{http: array} */ - protected function prepareStreamOptions($method, $data, $forcePostUrlEncoded) + protected function prepareStreamOptions(string $method, $data, bool $forcePostUrlEncoded): array { - $stream_options = array( - 'http' => array( + $stream_options = [ + 'http' => [ 'method' => $method, 'user_agent' => $this->userAgent, 'header' => "Accept-Language: " . $this->acceptLanguage . "\r\n", 'timeout' => $this->requestTimeout, - ), - ); + ], + ]; $proxy = $this->getProxy(); if (isset($proxy)) { @@ -1959,7 +2035,7 @@ protected function prepareStreamOptions($method, $data, $forcePostUrlEncoded) /** * @ignore */ - protected function sendRequest($url, $method = 'GET', $data = null, $force = false) + protected function sendRequest(string $url, string $method = 'GET', $data = null, bool $force = false): string { self::$DEBUG_LAST_REQUESTED_URL = $url; @@ -2073,7 +2149,7 @@ protected function getTimestamp() /** * Returns the base URL for the Matomo server. */ - protected function getBaseUrl() + protected function getBaseUrl(): string { if (empty(self::$URL)) { throw new Exception( @@ -2094,7 +2170,7 @@ protected function getBaseUrl() /** * @ignore */ - protected function getRequest($idSite) + protected function getRequest(int $idSite): string { $this->setFirstPartyCookies(); @@ -2198,9 +2274,9 @@ protected function getRequest($idSite) } // Reset page level custom variables after this page view - $this->ecommerceView = array(); - $this->pageCustomVar = array(); - $this->eventCustomVar = array(); + $this->ecommerceView = []; + $this->pageCustomVar = []; + $this->eventCustomVar = []; $this->clearCustomDimensions(); $this->clearCustomTrackingParameters(); @@ -2214,11 +2290,10 @@ protected function getRequest($idSite) /** * Returns a first party cookie which name contains $name * - * @param string $name * @return string String value of cookie, or false if not found * @ignore */ - protected function getCookieMatchingName($name) + protected function getCookieMatchingName(string $name) { if ($this->configCookiesDisabled) { return false; @@ -2244,10 +2319,9 @@ protected function getCookieMatchingName($name) * If current URL is "http://example.org/dir1/dir2/index.php?param1=value1¶m2=value2" * will return "/dir1/dir2/index.php" * - * @return string * @ignore */ - protected static function getCurrentScriptName() + protected static function getCurrentScriptName(): string { $url = ''; if (!empty($_SERVER['PATH_INFO'])) { @@ -2281,10 +2355,10 @@ protected static function getCurrentScriptName() * @return string 'https' or 'http' * @ignore */ - protected static function getCurrentScheme() + protected static function getCurrentScheme(): string { if (isset($_SERVER['HTTPS']) - && ($_SERVER['HTTPS'] == 'on' || $_SERVER['HTTPS'] === true) + && ($_SERVER['HTTPS'] === 'on' || $_SERVER['HTTPS'] === true) ) { return 'https'; } @@ -2296,10 +2370,9 @@ protected static function getCurrentScheme() * If current URL is "http://example.org/dir1/dir2/index.php?param1=value1¶m2=value2" * will return "http://example.org" * - * @return string * @ignore */ - protected static function getCurrentHost() + protected static function getCurrentHost(): string { if (isset($_SERVER['HTTP_HOST'])) { return $_SERVER['HTTP_HOST']; @@ -2312,10 +2385,9 @@ protected static function getCurrentHost() * If current URL is "http://example.org/dir1/dir2/index.php?param1=value1¶m2=value2" * will return "?param1=value1¶m2=value2" * - * @return string * @ignore */ - protected static function getCurrentQueryString() + protected static function getCurrentQueryString(): string { $url = ''; if (isset($_SERVER['QUERY_STRING']) @@ -2330,10 +2402,9 @@ protected static function getCurrentQueryString() /** * Returns the current full URL (scheme, host, path and query string. * - * @return string * @ignore */ - protected static function getCurrentUrl() + protected static function getCurrentUrl(): string { return self::getCurrentScheme() . '://' . self::getCurrentHost() @@ -2346,7 +2417,7 @@ protected static function getCurrentUrl() * All cookies are supported: 'id' and 'ses' and 'ref' and 'cvar' cookies. * @return $this */ - protected function setFirstPartyCookies() + protected function setFirstPartyCookies(): self { if ($this->configCookiesDisabled) { return $this; @@ -2379,12 +2450,9 @@ protected function setFirstPartyCookies() * * This replicates the matomo.js tracker algorithms for consistency and better accuracy. * - * @param $cookieName - * @param $cookieValue - * @param $cookieTTL * @return $this */ - protected function setCookie($cookieName, $cookieValue, $cookieTTL) + protected function setCookie(string $cookieName, $cookieValue, int $cookieTTL): self { $cookieExpire = $this->currentTs + $cookieTTL; if (!headers_sent()) { @@ -2411,7 +2479,7 @@ protected function getCustomVariablesFromCookie() return []; } - return json_decode($cookie, $assoc = true); + return json_decode($cookie, true); } /** @@ -2451,9 +2519,9 @@ public function getIncomingTrackerCookie($name) * * @param array $headers Array with HTTP response headers as values */ - protected function parseIncomingCookies($headers) + protected function parseIncomingCookies(array $headers): void { - $this->incomingTrackerCookies = array(); + $this->incomingTrackerCookies = []; if (!empty($headers)) { $headerName = 'set-cookie:';