diff options
Diffstat (limited to 'plugins/CustomJsTracker/TrackerUpdater.php')
-rw-r--r-- | plugins/CustomJsTracker/TrackerUpdater.php | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/plugins/CustomJsTracker/TrackerUpdater.php b/plugins/CustomJsTracker/TrackerUpdater.php new file mode 100644 index 0000000000..c301862b90 --- /dev/null +++ b/plugins/CustomJsTracker/TrackerUpdater.php @@ -0,0 +1,165 @@ +<?php +/** + * Piwik - free/libre analytics platform + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + */ + +namespace Piwik\Plugins\CustomJsTracker; + +use Piwik\Common; +use Piwik\Container\StaticContainer; +use Piwik\Plugins\CustomJsTracker\TrackingCode\PiwikJsManipulator; +use Piwik\Plugins\CustomJsTracker\TrackingCode\PluginTrackerFiles; +use Piwik\Piwik; + +/** + * Updates the Piwik JavaScript Tracker "piwik.js" in case plugins extend the tracker. + * + * Usage: + * StaticContainer::get('Piwik\Plugins\CustomJsTracker\TrackerUpdater')->update(); + */ +class TrackerUpdater +{ + const DEVELOPMENT_PIWIK_JS = '/js/piwik.js'; + const ORIGINAL_PIWIK_JS = '/js/piwik.min.js'; + const TARGET_MATOMO_JS = '/matomo.js'; + + /** + * @var File + */ + private $fromFile; + + /** + * @var File + */ + private $toFile; + + private $trackerFiles = array(); + + /** + * @param string|null $fromFile If null then the minified JS tracker file in /js fill be used + * @param string|null $toFile If null then the minified JS tracker will be updated. + */ + public function __construct($fromFile = null, $toFile = null) + { + if (!isset($fromFile)) { + $fromFile = PIWIK_DOCUMENT_ROOT . self::ORIGINAL_PIWIK_JS; + } + + if (!isset($toFile)) { + $toFile = PIWIK_DOCUMENT_ROOT . self::TARGET_MATOMO_JS; + } + + $this->setFromFile($fromFile); + $this->setToFile($toFile); + $this->trackerFiles = StaticContainer::get('Piwik\Plugins\CustomJsTracker\TrackingCode\PluginTrackerFiles'); + } + + public function setFromFile($fromFile) + { + if (is_string($fromFile)) { + $fromFile = new File($fromFile); + } + $this->fromFile = $fromFile; + } + + public function getFromFile() + { + return $this->fromFile; + } + + public function setToFile($toFile) + { + if (is_string($toFile)) { + $toFile = new File($toFile); + } + $this->toFile = $toFile; + } + + public function getToFile() + { + return $this->toFile; + } + + public function setTrackerFiles(PluginTrackerFiles $trackerFiles) + { + $this->trackerFiles = $trackerFiles; + } + + /** + * Checks whether the Piwik JavaScript tracker file "piwik.js" is writable. + * @throws \Exception In case the piwik.js file is not writable. + * + * @api + */ + public function checkWillSucceed() + { + $this->fromFile->checkReadable(); + $this->toFile->checkWritable(); + } + + public function getCurrentTrackerFileContent() + { + return $this->toFile->getContent(); + } + + public function getUpdatedTrackerFileContent() + { + $trackingCode = new PiwikJsManipulator($this->fromFile->getContent(), $this->trackerFiles); + $newContent = $trackingCode->manipulateContent(); + + return $newContent; + } + + /** + * Updates / re-generates the Piwik JavaScript tracker "piwik.js". + * + * It may not be possible to update the "piwik.js" tracker file if the file is not writable. It won't throw + * an exception in such a case and instead just to nothing. To check if the update would succeed, call + * {@link checkWillSucceed()}. + * + * @api + */ + public function update() + { + if (!$this->toFile->hasWriteAccess() || !$this->fromFile->hasReadAccess()) { + return; + } + + $newContent = $this->getUpdatedTrackerFileContent(); + + if (!$this->toFile->isFileContentSame($newContent)) { + $savedFiles = $this->toFile->save($newContent); + foreach ($savedFiles as $savedFile) { + + /** + * Triggered after the tracker JavaScript content (the content of the piwik.js file) is changed. + * + * @param string $absolutePath The path to the new piwik.js file. + */ + Piwik::postEvent('CustomJsTracker.trackerJsChanged', [$savedFile]); + } + + } + + // we need to make sure to sync matomo.js / piwik.js + $this->updateAlternative('piwik.js', 'matomo.js', $newContent); + $this->updateAlternative('matomo.js', 'piwik.js', $newContent); + } + + private function updateAlternative($fromFile, $toFile, $newContent) + { + if (Common::stringEndsWith($this->toFile->getName(), $fromFile)) { + $alternativeFilename = dirname($this->toFile->getPath()) . DIRECTORY_SEPARATOR . $toFile; + $file = $this->toFile->setFile($alternativeFilename); + if ($file->hasWriteAccess() && !$file->isFileContentSame($newContent)) { + $savedFiles = $file->save($newContent); + foreach ($savedFiles as $savedFile) { + Piwik::postEvent('CustomJsTracker.trackerJsChanged', [$savedFile]); + } + } + } + } +} |