blizz_vanisher-8.x-1.x-dev/src/Service/MatomoVanisher.php
src/Service/MatomoVanisher.php
<?php
namespace Drupal\blizz_vanisher\Service;
/**
* Class MatomoVanisher.
*
* @package Drupal\blizz_vanisher\Service
*/
class MatomoVanisher extends ThirdPartyServicesVanisher implements ThirdPartyServicesVanisherInterface {
const FIND_MATOMO_ID_REGEX = '~_paq\.push\(.*?([\'"])setSiteId[^\1],.*?\1(\d+)\1~i';
const FIND_MATOMO_HOST_REGEX = '~u=.*?([\'"]).*?(\/\/.*?)\1~is';
const FIND_MATOMO_PARAMETERS_REGEX = '~_paq\.push\(\["[^"]*?(?<!setSiteId|setTrackerUrl)".*?\);{0,1}~is';
/**
* {@inheritdoc}
*/
public function vanish(&$content) {
$replaced_script = [];
$script = $this->getScript('piwik.php', $this->getAllScripts($content));
if ($script) {
$data = $this->getData($script);
if ($data) {
$replaced_script[] = $this->getReplacementScript($data);
// Remove the original script.
$content = $this->removeScript($script, $content);
// Remove the piwik script loaded by the piwik module if installed.
$content = $this->removeByRegex('~(<script.*?piwik\.js.*?><\/script>)~i', $content);
}
}
$replaced_script[] = '(tarteaucitron.job = tarteaucitron.job || []).push(\'matomo\');';
return implode("\n", $replaced_script);
}
/**
* Returns the matomo data.
*
* @param string $script
* The matomo script.
*
* @return array
* The matomo data.
*
* @throws \Exception
* When the matomo id could not be found in the script.
*/
protected function getData($script) {
$data = [
'matomo_id' => $this->findMatomoId($script),
'matomo_host' => $this->findMatomoHost($script),
];
$parameters = $this->findMatomoParameters($script);
if (is_array($parameters)) {
$parameters = implode("\n", $parameters);
$data['matomo_parameters'] = $parameters;
}
return $data;
}
/**
* Finds the matomo id in the script.
*
* @param string $script
* The matomo script.
*
* @return string
* The matomo id.
*
* @throws \Exception
* When the matomo id could not be found.
*/
protected function findMatomoId($script) {
$matches = [];
$ret = preg_match(self::FIND_MATOMO_ID_REGEX, $script, $matches);
if ($ret === FALSE || $ret < 1) {
throw new \Exception('Failed to find mandatory matomo id.');
}
return $matches[2];
}
/**
* Finds the matomo host in the script.
*
* @param string $script
* The matomo script.
*
* @return string
* The matomo host or an empty string.
*/
protected function findMatomoHost($script) {
$matches = [];
$ret = preg_match(self::FIND_MATOMO_HOST_REGEX, $script, $matches);
if ($ret === 1) {
return $matches[2];
}
return '';
}
/**
* Finds the additional parameters for matomo in the script.
*
* @param string $script
* The matomo script.
*
* @return array
* An array of matomo parameters or an empty array.
*/
protected function findMatomoParameters($script) {
$matches = [];
$ret = preg_match_all(self::FIND_MATOMO_PARAMETERS_REGEX, $script, $matches);
if ($ret !== FALSE && $ret > 0) {
return $matches[0];
}
return $matches;
}
/**
* Returns the replacement script.
*
* @param array $data
* The matomo data.
*
* @return string
* The replacement script.
*/
public function getReplacementScript(array $data) {
if (!isset($data['matomo_id'])) {
throw new \InvalidArgumentException('The array key "matomo_id" is missing.');
}
if (!isset($data['matomo_host'])) {
throw new \InvalidArgumentException('The array key "matomo_host" is missing.');
}
if (!isset($data['matomo_parameters'])) {
throw new \InvalidArgumentException('The array key "matomo_parameters" is missing.');
}
return <<< EOF
tarteaucitron.user.matomoId = '{$data['matomo_id']}';
tarteaucitron.user.matomoHost = '{$data['matomo_host']}';
tarteaucitron.user.matomoParameters = function () { {$data['matomo_parameters']} };
EOF;
}
/**
* Returns the vanisher name.
*
* @return string
* The vanisher name.
*/
public function getVanisherName() {
return 'matomo';
}
/**
* Returns the name of this vanisher.
*
* @return string
* The name of this vanisher.
*/
public function __toString() {
return 'Matomo Vanisher';
}
/**
*
*/
public function getCookies() {
return ['_pk_ref', '_pk_cvar', '_pk_id', '_pk_ses', '_pk_hsr', 'piwik_ignore', '_pk_uid'];
}
/**
*
*/
public function getJavascript() {
return <<< EOT
function () {
if (tarteaucitron.user.matomoId === undefined) {
return;
}
window._paq = window._paq || [];
window._paq.push(["setSiteId", tarteaucitron.user.matomoId]);
window._paq.push(["setTrackerUrl", tarteaucitron.user.matomoHost + "piwik.js"]);
if (typeof tarteaucitron.user.matomoParameters === 'function') {
tarteaucitron.user.matomoParameters();
}
tarteaucitron.addScript(tarteaucitron.user.matomoHost + 'piwik.js', '', '', true, 'defer', 'defer');
}
EOT;
}
/**
*
*/
public function getFallbackJavascript() {
return '';
}
}
