PDF rausgenommen
This commit is contained in:
61
msd2/tracking/piwik/core/AssetManager/UIAsset.php
Normal file
61
msd2/tracking/piwik/core/AssetManager/UIAsset.php
Normal file
@ -0,0 +1,61 @@
|
||||
<?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\AssetManager;
|
||||
|
||||
use Exception;
|
||||
|
||||
abstract class UIAsset
|
||||
{
|
||||
abstract public function validateFile();
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
abstract public function getAbsoluteLocation();
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
abstract public function getRelativeLocation();
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
abstract public function getBaseDirectory();
|
||||
|
||||
/**
|
||||
* Removes the previous file if it exists.
|
||||
* Also tries to remove compressed version of the file.
|
||||
*
|
||||
* @see ProxyStaticFile::serveStaticFile(serveFile
|
||||
* @throws Exception if the file couldn't be deleted
|
||||
*/
|
||||
abstract public function delete();
|
||||
|
||||
/**
|
||||
* @param string $content
|
||||
* @throws \Exception
|
||||
*/
|
||||
abstract public function writeContent($content);
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
abstract public function getContent();
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
abstract public function exists();
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
abstract public function getModificationDate();
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
<?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\AssetManager\UIAsset;
|
||||
|
||||
use Exception;
|
||||
use Piwik\AssetManager\UIAsset;
|
||||
|
||||
class InMemoryUIAsset extends UIAsset
|
||||
{
|
||||
private $content;
|
||||
|
||||
public function validateFile()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
public function getAbsoluteLocation()
|
||||
{
|
||||
throw new Exception('invalid operation');
|
||||
}
|
||||
|
||||
public function getRelativeLocation()
|
||||
{
|
||||
throw new Exception('invalid operation');
|
||||
}
|
||||
|
||||
public function getBaseDirectory()
|
||||
{
|
||||
throw new Exception('invalid operation');
|
||||
}
|
||||
|
||||
public function delete()
|
||||
{
|
||||
$this->content = null;
|
||||
}
|
||||
|
||||
public function exists()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function writeContent($content)
|
||||
{
|
||||
$this->content = $content;
|
||||
}
|
||||
|
||||
public function getContent()
|
||||
{
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
public function getModificationDate()
|
||||
{
|
||||
throw new Exception('invalid operation');
|
||||
}
|
||||
}
|
135
msd2/tracking/piwik/core/AssetManager/UIAsset/OnDiskUIAsset.php
Normal file
135
msd2/tracking/piwik/core/AssetManager/UIAsset/OnDiskUIAsset.php
Normal file
@ -0,0 +1,135 @@
|
||||
<?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\AssetManager\UIAsset;
|
||||
|
||||
use Exception;
|
||||
use Piwik\AssetManager\UIAsset;
|
||||
use Piwik\Common;
|
||||
use Piwik\Filesystem;
|
||||
|
||||
class OnDiskUIAsset extends UIAsset
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $baseDirectory;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $relativeLocation;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $relativeRootDir;
|
||||
|
||||
/**
|
||||
* @param string $baseDirectory
|
||||
* @param string $fileLocation
|
||||
*/
|
||||
public function __construct($baseDirectory, $fileLocation, $relativeRootDir = '')
|
||||
{
|
||||
$this->baseDirectory = $baseDirectory;
|
||||
$this->relativeLocation = $fileLocation;
|
||||
|
||||
if (!empty($relativeRootDir)
|
||||
&& is_string($relativeRootDir)
|
||||
&& !Common::stringEndsWith($relativeRootDir, '/')) {
|
||||
$relativeRootDir .= '/';
|
||||
}
|
||||
|
||||
$this->relativeRootDir = $relativeRootDir;
|
||||
}
|
||||
|
||||
public function getAbsoluteLocation()
|
||||
{
|
||||
return $this->baseDirectory . '/' . $this->relativeLocation;
|
||||
}
|
||||
|
||||
public function getRelativeLocation()
|
||||
{
|
||||
if (isset($this->relativeRootDir)) {
|
||||
return $this->relativeRootDir . $this->relativeLocation;
|
||||
}
|
||||
return $this->relativeLocation;
|
||||
}
|
||||
|
||||
public function getBaseDirectory()
|
||||
{
|
||||
return $this->baseDirectory;
|
||||
}
|
||||
|
||||
public function validateFile()
|
||||
{
|
||||
if (!$this->assetIsReadable()) {
|
||||
throw new Exception("The ui asset with 'href' = " . $this->getAbsoluteLocation() . " is not readable");
|
||||
}
|
||||
}
|
||||
|
||||
public function delete()
|
||||
{
|
||||
if ($this->exists()) {
|
||||
try {
|
||||
Filesystem::remove($this->getAbsoluteLocation());
|
||||
} catch (Exception $e) {
|
||||
throw new Exception("Unable to delete merged file : " . $this->getAbsoluteLocation() . ". Please delete the file and refresh");
|
||||
}
|
||||
|
||||
// try to remove compressed version of the merged file.
|
||||
Filesystem::remove($this->getAbsoluteLocation() . ".deflate", true);
|
||||
Filesystem::remove($this->getAbsoluteLocation() . ".gz", true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $content
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function writeContent($content)
|
||||
{
|
||||
$this->delete();
|
||||
|
||||
$newFile = @fopen($this->getAbsoluteLocation(), "w");
|
||||
|
||||
if (!$newFile) {
|
||||
throw new Exception("The file : " . $newFile . " can not be opened in write mode.");
|
||||
}
|
||||
|
||||
fwrite($newFile, $content);
|
||||
|
||||
fclose($newFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getContent()
|
||||
{
|
||||
return file_get_contents($this->getAbsoluteLocation());
|
||||
}
|
||||
|
||||
public function exists()
|
||||
{
|
||||
return $this->assetIsReadable();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
private function assetIsReadable()
|
||||
{
|
||||
return is_readable($this->getAbsoluteLocation());
|
||||
}
|
||||
|
||||
public function getModificationDate()
|
||||
{
|
||||
return filemtime($this->getAbsoluteLocation());
|
||||
}
|
||||
}
|
66
msd2/tracking/piwik/core/AssetManager/UIAssetCacheBuster.php
Normal file
66
msd2/tracking/piwik/core/AssetManager/UIAssetCacheBuster.php
Normal file
@ -0,0 +1,66 @@
|
||||
<?php
|
||||
/**
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*
|
||||
* @method static \Piwik\AssetManager\UIAssetCacheBuster getInstance()
|
||||
*/
|
||||
namespace Piwik\AssetManager;
|
||||
|
||||
use Piwik\Plugin\Manager;
|
||||
use Piwik\Singleton;
|
||||
use Piwik\Version;
|
||||
|
||||
class UIAssetCacheBuster extends Singleton
|
||||
{
|
||||
/**
|
||||
* Cache buster based on
|
||||
* - Piwik version
|
||||
* - Loaded plugins (name and version)
|
||||
* - Super user salt
|
||||
* - Latest
|
||||
*
|
||||
* @param string[] $pluginNames
|
||||
* @return string
|
||||
*/
|
||||
public function piwikVersionBasedCacheBuster($pluginNames = false)
|
||||
{
|
||||
static $cachedCacheBuster = null;
|
||||
|
||||
if (empty($cachedCacheBuster) || $pluginNames !== false) {
|
||||
|
||||
$masterFile = PIWIK_INCLUDE_PATH . '/.git/refs/heads/master';
|
||||
$currentGitHash = file_exists($masterFile) ? @file_get_contents($masterFile) : null;
|
||||
|
||||
$plugins = !$pluginNames ? Manager::getInstance()->getLoadedPluginsName() : $pluginNames;
|
||||
sort($plugins);
|
||||
|
||||
$pluginsInfo = '';
|
||||
foreach ($plugins as $pluginName) {
|
||||
$plugin = Manager::getInstance()->getLoadedPlugin($pluginName);
|
||||
$pluginsInfo .= $plugin->getPluginName() . $plugin->getVersion() . ',';
|
||||
}
|
||||
|
||||
$cacheBuster = md5($pluginsInfo . PHP_VERSION . Version::VERSION . trim($currentGitHash));
|
||||
|
||||
if ($pluginNames !== false) {
|
||||
return $cacheBuster;
|
||||
}
|
||||
|
||||
$cachedCacheBuster = $cacheBuster;
|
||||
}
|
||||
|
||||
return $cachedCacheBuster;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $content
|
||||
* @return string
|
||||
*/
|
||||
public function md5BasedCacheBuster($content)
|
||||
{
|
||||
return md5($content);
|
||||
}
|
||||
}
|
73
msd2/tracking/piwik/core/AssetManager/UIAssetCatalog.php
Normal file
73
msd2/tracking/piwik/core/AssetManager/UIAssetCatalog.php
Normal file
@ -0,0 +1,73 @@
|
||||
<?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\AssetManager;
|
||||
|
||||
class UIAssetCatalog
|
||||
{
|
||||
/**
|
||||
* @var UIAsset[]
|
||||
*/
|
||||
private $uiAssets = array();
|
||||
|
||||
/**
|
||||
* @var UIAssetCatalogSorter
|
||||
*/
|
||||
private $catalogSorter;
|
||||
|
||||
/**
|
||||
* @var string[] Absolute file locations
|
||||
*/
|
||||
private $existingAssetLocations = array();
|
||||
|
||||
/**
|
||||
* @param UIAssetCatalogSorter $catalogSorter
|
||||
*/
|
||||
public function __construct($catalogSorter)
|
||||
{
|
||||
$this->catalogSorter = $catalogSorter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param UIAsset $uiAsset
|
||||
*/
|
||||
public function addUIAsset($uiAsset)
|
||||
{
|
||||
$location = $uiAsset->getAbsoluteLocation();
|
||||
|
||||
if (!$this->assetAlreadyInCatalog($location)) {
|
||||
$this->existingAssetLocations[] = $location;
|
||||
$this->uiAssets[] = $uiAsset;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return UIAsset[]
|
||||
*/
|
||||
public function getAssets()
|
||||
{
|
||||
return $this->uiAssets;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return UIAssetCatalog
|
||||
*/
|
||||
public function getSortedCatalog()
|
||||
{
|
||||
return $this->catalogSorter->sortUIAssetCatalog($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param UIAsset $uiAsset
|
||||
* @return boolean
|
||||
*/
|
||||
private function assetAlreadyInCatalog($location)
|
||||
{
|
||||
return in_array($location, $this->existingAssetLocations);
|
||||
}
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
<?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\AssetManager;
|
||||
|
||||
class UIAssetCatalogSorter
|
||||
{
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
private $priorityOrder;
|
||||
|
||||
/**
|
||||
* @param string[] $priorityOrder
|
||||
*/
|
||||
public function __construct($priorityOrder)
|
||||
{
|
||||
$this->priorityOrder = $priorityOrder;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param UIAssetCatalog $uiAssetCatalog
|
||||
* @return UIAssetCatalog
|
||||
*/
|
||||
public function sortUIAssetCatalog($uiAssetCatalog)
|
||||
{
|
||||
$sortedCatalog = new UIAssetCatalog($this);
|
||||
foreach ($this->priorityOrder as $filePattern) {
|
||||
$assetsMatchingPattern = array_filter($uiAssetCatalog->getAssets(), function ($uiAsset) use ($filePattern) {
|
||||
return preg_match('~^' . $filePattern . '~', $uiAsset->getRelativeLocation());
|
||||
});
|
||||
|
||||
foreach ($assetsMatchingPattern as $assetMatchingPattern) {
|
||||
$sortedCatalog->addUIAsset($assetMatchingPattern);
|
||||
}
|
||||
}
|
||||
|
||||
$this->addUnmatchedAssets($uiAssetCatalog, $sortedCatalog);
|
||||
|
||||
return $sortedCatalog;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param UIAssetCatalog $uiAssetCatalog
|
||||
* @param UIAssetCatalog $sortedCatalog
|
||||
*/
|
||||
private function addUnmatchedAssets($uiAssetCatalog, $sortedCatalog)
|
||||
{
|
||||
foreach ($uiAssetCatalog->getAssets() as $uiAsset) {
|
||||
$sortedCatalog->addUIAsset($uiAsset);
|
||||
}
|
||||
}
|
||||
}
|
150
msd2/tracking/piwik/core/AssetManager/UIAssetFetcher.php
Normal file
150
msd2/tracking/piwik/core/AssetManager/UIAssetFetcher.php
Normal file
@ -0,0 +1,150 @@
|
||||
<?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\AssetManager;
|
||||
|
||||
use Piwik\AssetManager\UIAsset\OnDiskUIAsset;
|
||||
use Piwik\Plugin\Manager;
|
||||
use Piwik\Theme;
|
||||
|
||||
abstract class UIAssetFetcher
|
||||
{
|
||||
/**
|
||||
* @var UIAssetCatalog
|
||||
*/
|
||||
protected $catalog;
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
protected $fileLocations = array();
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
protected $plugins;
|
||||
|
||||
/**
|
||||
* @var Theme
|
||||
*/
|
||||
private $theme;
|
||||
|
||||
/**
|
||||
* @param string[] $plugins
|
||||
* @param Theme $theme
|
||||
*/
|
||||
public function __construct($plugins, $theme)
|
||||
{
|
||||
$this->plugins = $plugins;
|
||||
$this->theme = $theme;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getPlugins()
|
||||
{
|
||||
return $this->plugins;
|
||||
}
|
||||
|
||||
/**
|
||||
* $return UIAssetCatalog
|
||||
*/
|
||||
public function getCatalog()
|
||||
{
|
||||
if ($this->catalog == null) {
|
||||
$this->createCatalog();
|
||||
}
|
||||
|
||||
return $this->catalog;
|
||||
}
|
||||
|
||||
abstract protected function retrieveFileLocations();
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
abstract protected function getPriorityOrder();
|
||||
|
||||
private function createCatalog()
|
||||
{
|
||||
$this->retrieveFileLocations();
|
||||
|
||||
$this->initCatalog();
|
||||
|
||||
$this->populateCatalog();
|
||||
|
||||
$this->sortCatalog();
|
||||
}
|
||||
|
||||
private function initCatalog()
|
||||
{
|
||||
$catalogSorter = new UIAssetCatalogSorter($this->getPriorityOrder());
|
||||
$this->catalog = new UIAssetCatalog($catalogSorter);
|
||||
}
|
||||
|
||||
private function populateCatalog()
|
||||
{
|
||||
$pluginBaseDir = Manager::getPluginsDirectory();
|
||||
$pluginWebDirectories = Manager::getAlternativeWebRootDirectories();
|
||||
$matomoRootDir = $this->getBaseDirectory();
|
||||
|
||||
foreach ($this->fileLocations as $fileLocation) {
|
||||
$fileAbsolute = $matomoRootDir . '/' . $fileLocation;
|
||||
|
||||
$newUIAsset = new OnDiskUIAsset($this->getBaseDirectory(), $fileLocation);
|
||||
if ($newUIAsset->exists()) {
|
||||
$this->catalog->addUIAsset($newUIAsset);
|
||||
continue;
|
||||
}
|
||||
|
||||
$found = false;
|
||||
|
||||
if (strpos($fileAbsolute, $pluginBaseDir) === 0) {
|
||||
// we iterate over all custom plugin directories only for plugin files, not libs files (not needed there)
|
||||
foreach ($pluginWebDirectories as $pluginDirectory => $relative) {
|
||||
$fileTest = str_replace($pluginBaseDir, $pluginDirectory, $fileAbsolute);
|
||||
$newFileRelative = str_replace($pluginDirectory, '', $fileTest);
|
||||
$testAsset = new OnDiskUIAsset($pluginDirectory, $newFileRelative, $relative);
|
||||
if ($testAsset->exists()) {
|
||||
$this->catalog->addUIAsset($testAsset);
|
||||
$found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$found) {
|
||||
// we add it anyway so it'll trigger an error about the missing file
|
||||
$this->catalog->addUIAsset($newUIAsset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function sortCatalog()
|
||||
{
|
||||
$this->catalog = $this->catalog->getSortedCatalog();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private function getBaseDirectory()
|
||||
{
|
||||
// served by web server directly, so must be a public path
|
||||
return PIWIK_DOCUMENT_ROOT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Theme
|
||||
*/
|
||||
public function getTheme()
|
||||
{
|
||||
return $this->theme;
|
||||
}
|
||||
}
|
@ -0,0 +1,88 @@
|
||||
<?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\AssetManager\UIAssetFetcher;
|
||||
|
||||
use Piwik\AssetManager\UIAssetFetcher;
|
||||
use Piwik\Piwik;
|
||||
|
||||
class JScriptUIAssetFetcher extends UIAssetFetcher
|
||||
{
|
||||
|
||||
protected function retrieveFileLocations()
|
||||
{
|
||||
if (!empty($this->plugins)) {
|
||||
|
||||
/**
|
||||
* Triggered when gathering the list of all JavaScript files needed by Piwik
|
||||
* and its plugins.
|
||||
*
|
||||
* Plugins that have their own JavaScript should use this event to make those
|
||||
* files load in the browser.
|
||||
*
|
||||
* JavaScript files should be placed within a **javascripts** subdirectory in your
|
||||
* plugin's root directory.
|
||||
*
|
||||
* _Note: While you are developing your plugin you should enable the config setting
|
||||
* `[Development] disable_merged_assets` so JavaScript files will be reloaded immediately
|
||||
* after every change._
|
||||
*
|
||||
* **Example**
|
||||
*
|
||||
* public function getJsFiles(&$jsFiles)
|
||||
* {
|
||||
* $jsFiles[] = "plugins/MyPlugin/javascripts/myfile.js";
|
||||
* $jsFiles[] = "plugins/MyPlugin/javascripts/anotherone.js";
|
||||
* }
|
||||
*
|
||||
* @param string[] $jsFiles The JavaScript files to load.
|
||||
*/
|
||||
Piwik::postEvent('AssetManager.getJavaScriptFiles', array(&$this->fileLocations), null, $this->plugins);
|
||||
}
|
||||
|
||||
$this->addThemeFiles();
|
||||
}
|
||||
|
||||
protected function addThemeFiles()
|
||||
{
|
||||
$theme = $this->getTheme();
|
||||
if (!$theme) {
|
||||
return;
|
||||
}
|
||||
if (in_array($theme->getThemeName(), $this->plugins)) {
|
||||
$jsInThemes = $this->getTheme()->getJavaScriptFiles();
|
||||
|
||||
if (!empty($jsInThemes)) {
|
||||
foreach ($jsInThemes as $jsFile) {
|
||||
$this->fileLocations[] = $jsFile;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function getPriorityOrder()
|
||||
{
|
||||
return array(
|
||||
'libs/bower_components/jquery/dist/jquery.min.js',
|
||||
'libs/bower_components/jquery-ui/ui/minified/jquery-ui.min.js',
|
||||
'libs/jquery/jquery.browser.js',
|
||||
'libs/',
|
||||
'js/',
|
||||
'piwik.js',
|
||||
'matomo.js',
|
||||
'plugins/CoreHome/javascripts/require.js',
|
||||
'plugins/Morpheus/javascripts/piwikHelper.js',
|
||||
'plugins/Morpheus/javascripts/',
|
||||
'plugins/CoreHome/javascripts/uiControl.js',
|
||||
'plugins/CoreHome/javascripts/broadcast.js',
|
||||
'plugins/CoreHome/javascripts/', // load CoreHome JS before other plugins
|
||||
'plugins/',
|
||||
'tests/',
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
<?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\AssetManager\UIAssetFetcher;
|
||||
|
||||
use Piwik\AssetManager\UIAssetFetcher;
|
||||
|
||||
class StaticUIAssetFetcher extends UIAssetFetcher
|
||||
{
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
private $priorityOrder;
|
||||
|
||||
public function __construct($fileLocations, $priorityOrder, $theme)
|
||||
{
|
||||
parent::__construct(array(), $theme);
|
||||
|
||||
$this->fileLocations = $fileLocations;
|
||||
$this->priorityOrder = $priorityOrder;
|
||||
}
|
||||
|
||||
protected function retrieveFileLocations()
|
||||
{
|
||||
}
|
||||
|
||||
protected function getPriorityOrder()
|
||||
{
|
||||
return $this->priorityOrder;
|
||||
}
|
||||
}
|
@ -0,0 +1,85 @@
|
||||
<?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\AssetManager\UIAssetFetcher;
|
||||
|
||||
use Piwik\AssetManager\UIAssetFetcher;
|
||||
use Piwik\Piwik;
|
||||
|
||||
class StylesheetUIAssetFetcher extends UIAssetFetcher
|
||||
{
|
||||
protected function getPriorityOrder()
|
||||
{
|
||||
$theme = $this->getTheme();
|
||||
$themeName = $theme->getThemeName();
|
||||
|
||||
$order = array(
|
||||
'plugins/Morpheus/stylesheets/base/bootstrap.css',
|
||||
'plugins/Morpheus/stylesheets/base/icons.css',
|
||||
'libs/',
|
||||
'plugins/CoreHome/stylesheets/color_manager.css', // must be before other Piwik stylesheets
|
||||
'plugins/Morpheus/stylesheets/base.less',
|
||||
);
|
||||
|
||||
if ($themeName === 'Morpheus') {
|
||||
$order[] = 'plugins\/((?!Morpheus).)*\/';
|
||||
} else {
|
||||
$order[] = sprintf('plugins\/((?!(Morpheus)|(%s)).)*\/', $themeName);
|
||||
}
|
||||
|
||||
$order = array_merge(
|
||||
$order,
|
||||
array(
|
||||
'plugins/Dashboard/stylesheets/dashboard.less',
|
||||
'tests/',
|
||||
)
|
||||
);
|
||||
|
||||
return $order;
|
||||
}
|
||||
|
||||
protected function retrieveFileLocations()
|
||||
{
|
||||
/**
|
||||
* Triggered when gathering the list of all stylesheets (CSS and LESS) needed by
|
||||
* Piwik and its plugins.
|
||||
*
|
||||
* Plugins that have stylesheets should use this event to make those stylesheets
|
||||
* load.
|
||||
*
|
||||
* Stylesheets should be placed within a **stylesheets** subdirectory in your plugin's
|
||||
* root directory.
|
||||
*
|
||||
* **Example**
|
||||
*
|
||||
* public function getStylesheetFiles(&$stylesheets)
|
||||
* {
|
||||
* $stylesheets[] = "plugins/MyPlugin/stylesheets/myfile.less";
|
||||
* $stylesheets[] = "plugins/MyPlugin/stylesheets/myotherfile.css";
|
||||
* }
|
||||
*
|
||||
* @param string[] &$stylesheets The list of stylesheet paths.
|
||||
*/
|
||||
Piwik::postEvent('AssetManager.getStylesheetFiles', array(&$this->fileLocations));
|
||||
|
||||
$this->addThemeFiles();
|
||||
}
|
||||
|
||||
protected function addThemeFiles()
|
||||
{
|
||||
$theme = $this->getTheme();
|
||||
if (!$theme) {
|
||||
return;
|
||||
}
|
||||
$themeStylesheet = $theme->getStylesheet();
|
||||
|
||||
if ($themeStylesheet) {
|
||||
$this->fileLocations[] = $themeStylesheet;
|
||||
}
|
||||
}
|
||||
}
|
193
msd2/tracking/piwik/core/AssetManager/UIAssetMerger.php
Normal file
193
msd2/tracking/piwik/core/AssetManager/UIAssetMerger.php
Normal file
@ -0,0 +1,193 @@
|
||||
<?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\AssetManager;
|
||||
|
||||
|
||||
abstract class UIAssetMerger
|
||||
{
|
||||
/**
|
||||
* @var UIAssetFetcher
|
||||
*/
|
||||
private $assetFetcher;
|
||||
|
||||
/**
|
||||
* @var UIAsset
|
||||
*/
|
||||
private $mergedAsset;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $mergedContent;
|
||||
|
||||
/**
|
||||
* @var UIAssetCacheBuster
|
||||
*/
|
||||
protected $cacheBuster;
|
||||
|
||||
/**
|
||||
* @param UIAsset $mergedAsset
|
||||
* @param UIAssetFetcher $assetFetcher
|
||||
* @param UIAssetCacheBuster $cacheBuster
|
||||
*/
|
||||
public function __construct($mergedAsset, $assetFetcher, $cacheBuster)
|
||||
{
|
||||
$this->mergedAsset = $mergedAsset;
|
||||
$this->assetFetcher = $assetFetcher;
|
||||
$this->cacheBuster = $cacheBuster;
|
||||
}
|
||||
|
||||
public function generateFile()
|
||||
{
|
||||
if (!$this->shouldGenerate()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->mergedContent = $this->getMergedAssets();
|
||||
|
||||
$this->postEvent($this->mergedContent);
|
||||
|
||||
$this->adjustPaths();
|
||||
|
||||
$this->addPreamble();
|
||||
|
||||
$this->writeContentToFile();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
abstract protected function getMergedAssets();
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
abstract protected function generateCacheBuster();
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
abstract protected function getPreamble();
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
abstract protected function getFileSeparator();
|
||||
|
||||
/**
|
||||
* @param UIAsset $uiAsset
|
||||
* @return string
|
||||
*/
|
||||
abstract protected function processFileContent($uiAsset);
|
||||
|
||||
/**
|
||||
* @param string $mergedContent
|
||||
*/
|
||||
abstract protected function postEvent(&$mergedContent);
|
||||
|
||||
protected function getConcatenatedAssets()
|
||||
{
|
||||
if (empty($this->mergedContent)) {
|
||||
$this->concatenateAssets();
|
||||
}
|
||||
|
||||
return $this->mergedContent;
|
||||
}
|
||||
|
||||
protected function concatenateAssets()
|
||||
{
|
||||
$mergedContent = '';
|
||||
|
||||
foreach ($this->getAssetCatalog()->getAssets() as $uiAsset) {
|
||||
$uiAsset->validateFile();
|
||||
$content = $this->processFileContent($uiAsset);
|
||||
|
||||
$mergedContent .= $this->getFileSeparator() . $content;
|
||||
}
|
||||
|
||||
$this->mergedContent = $mergedContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
protected function getPlugins()
|
||||
{
|
||||
return $this->assetFetcher->getPlugins();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return UIAssetCatalog
|
||||
*/
|
||||
protected function getAssetCatalog()
|
||||
{
|
||||
return $this->assetFetcher->getCatalog();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
private function shouldGenerate()
|
||||
{
|
||||
if (!$this->mergedAsset->exists()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return !$this->isFileUpToDate();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
private function isFileUpToDate()
|
||||
{
|
||||
$f = fopen($this->mergedAsset->getAbsoluteLocation(), 'r');
|
||||
$firstLine = fgets($f);
|
||||
fclose($f);
|
||||
|
||||
if (!empty($firstLine) && trim($firstLine) == trim($this->getCacheBusterValue())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Some CSS file in the merge, has changed since last merged asset was generated
|
||||
// Note: we do not detect changes in @import'ed LESS files
|
||||
return false;
|
||||
}
|
||||
|
||||
private function adjustPaths()
|
||||
{
|
||||
$theme = $this->assetFetcher->getTheme();
|
||||
// During installation theme is not yet ready
|
||||
if ($theme) {
|
||||
$this->mergedContent = $this->assetFetcher->getTheme()->rewriteAssetsPathToTheme($this->mergedContent);
|
||||
}
|
||||
}
|
||||
|
||||
private function writeContentToFile()
|
||||
{
|
||||
$this->mergedAsset->writeContent($this->mergedContent);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function getCacheBusterValue()
|
||||
{
|
||||
if (empty($this->cacheBusterValue)) {
|
||||
$this->cacheBusterValue = $this->generateCacheBuster();
|
||||
}
|
||||
|
||||
return $this->cacheBusterValue;
|
||||
}
|
||||
|
||||
private function addPreamble()
|
||||
{
|
||||
$this->mergedContent = $this->getPreamble() . $this->mergedContent;
|
||||
}
|
||||
}
|
@ -0,0 +1,88 @@
|
||||
<?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\AssetManager\UIAssetMerger;
|
||||
|
||||
use Piwik\AssetManager\UIAsset;
|
||||
use Piwik\AssetManager\UIAssetCacheBuster;
|
||||
use Piwik\AssetManager\UIAssetFetcher\JScriptUIAssetFetcher;
|
||||
use Piwik\AssetManager\UIAssetMerger;
|
||||
use Piwik\AssetManager;
|
||||
use Piwik\AssetManager\UIAssetMinifier;
|
||||
use Piwik\Piwik;
|
||||
|
||||
class JScriptUIAssetMerger extends UIAssetMerger
|
||||
{
|
||||
/**
|
||||
* @var UIAssetMinifier
|
||||
*/
|
||||
private $assetMinifier;
|
||||
|
||||
/**
|
||||
* @param UIAsset $mergedAsset
|
||||
* @param JScriptUIAssetFetcher $assetFetcher
|
||||
* @param UIAssetCacheBuster $cacheBuster
|
||||
*/
|
||||
public function __construct($mergedAsset, $assetFetcher, $cacheBuster)
|
||||
{
|
||||
parent::__construct($mergedAsset, $assetFetcher, $cacheBuster);
|
||||
|
||||
$this->assetMinifier = UIAssetMinifier::getInstance();
|
||||
}
|
||||
|
||||
protected function getMergedAssets()
|
||||
{
|
||||
return $this->getConcatenatedAssets();
|
||||
}
|
||||
|
||||
protected function generateCacheBuster()
|
||||
{
|
||||
$cacheBuster = $this->cacheBuster->piwikVersionBasedCacheBuster($this->getPlugins());
|
||||
return "/* Matomo Javascript - cb=" . $cacheBuster . "*/\n";
|
||||
}
|
||||
|
||||
protected function getPreamble()
|
||||
{
|
||||
return $this->getCacheBusterValue();
|
||||
}
|
||||
|
||||
protected function postEvent(&$mergedContent)
|
||||
{
|
||||
$plugins = $this->getPlugins();
|
||||
|
||||
if (!empty($plugins)) {
|
||||
|
||||
/**
|
||||
* Triggered after all the JavaScript files Piwik uses are minified and merged into a
|
||||
* single file, but before the merged JavaScript is written to disk.
|
||||
*
|
||||
* Plugins can use this event to modify merged JavaScript or do something else
|
||||
* with it.
|
||||
*
|
||||
* @param string $mergedContent The minified and merged JavaScript.
|
||||
*/
|
||||
Piwik::postEvent('AssetManager.filterMergedJavaScripts', array(&$mergedContent), null, $plugins);
|
||||
}
|
||||
}
|
||||
|
||||
public function getFileSeparator()
|
||||
{
|
||||
return "\n";
|
||||
}
|
||||
|
||||
protected function processFileContent($uiAsset)
|
||||
{
|
||||
$content = $uiAsset->getContent();
|
||||
|
||||
if (!$this->assetMinifier->isMinifiedJs($content)) {
|
||||
$content = $this->assetMinifier->minifyJs($content);
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
}
|
@ -0,0 +1,260 @@
|
||||
<?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\AssetManager\UIAssetMerger;
|
||||
|
||||
use Exception;
|
||||
use lessc;
|
||||
use Piwik\AssetManager\UIAsset;
|
||||
use Piwik\AssetManager\UIAssetMerger;
|
||||
use Piwik\Common;
|
||||
use Piwik\Exception\StylesheetLessCompileException;
|
||||
use Piwik\Piwik;
|
||||
use Piwik\Plugin\Manager;
|
||||
|
||||
class StylesheetUIAssetMerger extends UIAssetMerger
|
||||
{
|
||||
/**
|
||||
* @var lessc
|
||||
*/
|
||||
private $lessCompiler;
|
||||
|
||||
/**
|
||||
* @var UIAsset[]
|
||||
*/
|
||||
private $cssAssetsToReplace = array();
|
||||
|
||||
public function __construct($mergedAsset, $assetFetcher, $cacheBuster)
|
||||
{
|
||||
parent::__construct($mergedAsset, $assetFetcher, $cacheBuster);
|
||||
|
||||
$this->lessCompiler = self::getLessCompiler();
|
||||
}
|
||||
|
||||
protected function getMergedAssets()
|
||||
{
|
||||
// note: we're using setImportDir on purpose (not addImportDir)
|
||||
$this->lessCompiler->setImportDir(PIWIK_DOCUMENT_ROOT);
|
||||
$concatenatedAssets = $this->getConcatenatedAssets();
|
||||
|
||||
$this->lessCompiler->setFormatter('classic');
|
||||
try {
|
||||
$compiled = $this->lessCompiler->compile($concatenatedAssets);
|
||||
} catch(\Exception $e) {
|
||||
throw new StylesheetLessCompileException($e->getMessage());
|
||||
}
|
||||
|
||||
foreach ($this->cssAssetsToReplace as $asset) {
|
||||
// to fix #10173
|
||||
$cssPath = $asset->getAbsoluteLocation();
|
||||
$cssContent = $this->processFileContent($asset);
|
||||
$compiled = str_replace($this->getCssStatementForReplacement($cssPath), $cssContent, $compiled);
|
||||
}
|
||||
|
||||
$this->mergedContent = $compiled;
|
||||
$this->cssAssetsToReplace = array();
|
||||
|
||||
return $compiled;
|
||||
}
|
||||
|
||||
private function getCssStatementForReplacement($path)
|
||||
{
|
||||
return '.nonExistingSelectorOnlyForReplacementOfCssFiles { display:"' . $path . '"; }';
|
||||
}
|
||||
|
||||
protected function concatenateAssets()
|
||||
{
|
||||
$concatenatedContent = '';
|
||||
|
||||
foreach ($this->getAssetCatalog()->getAssets() as $uiAsset) {
|
||||
$uiAsset->validateFile();
|
||||
|
||||
try {
|
||||
$path = $uiAsset->getAbsoluteLocation();
|
||||
} catch (Exception $e) {
|
||||
$path = null;
|
||||
}
|
||||
|
||||
if (!empty($path) && Common::stringEndsWith($path, '.css')) {
|
||||
// to fix #10173
|
||||
$concatenatedContent .= "\n" . $this->getCssStatementForReplacement($path) . "\n";
|
||||
$this->cssAssetsToReplace[] = $uiAsset;
|
||||
} else {
|
||||
$content = $this->processFileContent($uiAsset);
|
||||
$concatenatedContent .= $this->getFileSeparator() . $content;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggered after all less stylesheets are concatenated into one long string but before it is
|
||||
* minified and merged into one file.
|
||||
*
|
||||
* This event can be used to add less stylesheets that are not located in a file on the disc.
|
||||
*
|
||||
* @param string $concatenatedContent The content of all concatenated less files.
|
||||
*/
|
||||
Piwik::postEvent('AssetManager.addStylesheets', array(&$concatenatedContent));
|
||||
|
||||
$this->mergedContent = $concatenatedContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return lessc
|
||||
* @throws Exception
|
||||
*/
|
||||
private static function getLessCompiler()
|
||||
{
|
||||
if (!class_exists("lessc")) {
|
||||
throw new Exception("Less was added to composer during 2.0. ==> Execute this command to update composer packages: \$ php composer.phar install");
|
||||
}
|
||||
$less = new lessc();
|
||||
return $less;
|
||||
}
|
||||
|
||||
protected function generateCacheBuster()
|
||||
{
|
||||
$fileHash = $this->cacheBuster->md5BasedCacheBuster($this->getConcatenatedAssets());
|
||||
return "/* compile_me_once=$fileHash */";
|
||||
}
|
||||
|
||||
protected function getPreamble()
|
||||
{
|
||||
return $this->getCacheBusterValue() . "\n"
|
||||
. "/* Matomo CSS file is compiled with Less. You may be interested in writing a custom Theme for Matomo! */\n";
|
||||
}
|
||||
|
||||
protected function postEvent(&$mergedContent)
|
||||
{
|
||||
/**
|
||||
* Triggered after all less stylesheets are compiled to CSS, minified and merged into
|
||||
* one file, but before the generated CSS is written to disk.
|
||||
*
|
||||
* This event can be used to modify merged CSS.
|
||||
*
|
||||
* @param string $mergedContent The merged and minified CSS.
|
||||
*/
|
||||
Piwik::postEvent('AssetManager.filterMergedStylesheets', array(&$mergedContent));
|
||||
}
|
||||
|
||||
public function getFileSeparator()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
protected function processFileContent($uiAsset)
|
||||
{
|
||||
$pathsRewriter = $this->getCssPathsRewriter($uiAsset);
|
||||
$content = $uiAsset->getContent();
|
||||
$content = $this->rewriteCssImagePaths($content, $pathsRewriter);
|
||||
$content = $this->rewriteCssImportPaths($content, $pathsRewriter);
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rewrite CSS url() directives
|
||||
*
|
||||
* @param string $content
|
||||
* @param callable $pathsRewriter
|
||||
* @return string
|
||||
*/
|
||||
private function rewriteCssImagePaths($content, $pathsRewriter)
|
||||
{
|
||||
$content = preg_replace_callback("/(url\(['\"]?)([^'\")]*)/", $pathsRewriter, $content);
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rewrite CSS import directives
|
||||
*
|
||||
* @param string $content
|
||||
* @param callable $pathsRewriter
|
||||
* @return string
|
||||
*/
|
||||
private function rewriteCssImportPaths($content, $pathsRewriter)
|
||||
{
|
||||
$content = preg_replace_callback("/(@import \")([^\")]*)/", $pathsRewriter, $content);
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rewrite CSS url directives
|
||||
* - rewrites paths defined relatively to their css/less definition file
|
||||
* - rewrite windows directory separator \\ to /
|
||||
*
|
||||
* @param UIAsset $uiAsset
|
||||
* @return \Closure
|
||||
*/
|
||||
private function getCssPathsRewriter($uiAsset)
|
||||
{
|
||||
$baseDirectory = dirname($uiAsset->getRelativeLocation());
|
||||
$webDirs = Manager::getAlternativeWebRootDirectories();
|
||||
|
||||
return function ($matches) use ($baseDirectory, $webDirs) {
|
||||
$absolutePath = PIWIK_DOCUMENT_ROOT . "/$baseDirectory/" . $matches[2];
|
||||
|
||||
// Allow to import extension less file
|
||||
if (strpos($matches[2], '.') === false) {
|
||||
$absolutePath .= '.less';
|
||||
}
|
||||
|
||||
// Prevent from rewriting full path
|
||||
$absolutePathReal = realpath($absolutePath);
|
||||
if ($absolutePathReal) {
|
||||
$relativePath = $baseDirectory . "/" . $matches[2];
|
||||
$relativePath = str_replace('\\', '/', $relativePath);
|
||||
$publicPath = $matches[1] . $relativePath;
|
||||
} else {
|
||||
foreach ($webDirs as $absPath => $relativePath) {
|
||||
if (strpos($baseDirectory, $relativePath) === 0) {
|
||||
if (strpos($matches[2], '.') === 0) {
|
||||
// eg ../images/ok.png
|
||||
$fileRelative = $baseDirectory . '/' . $matches[2];
|
||||
$fileAbsolute = $absPath . str_replace($relativePath, '', $fileRelative);
|
||||
if (file_exists($fileAbsolute)) {
|
||||
return $matches[1] . $fileRelative;
|
||||
}
|
||||
} elseif (strpos($matches[2], 'plugins/') === 0) {
|
||||
// eg plugins/Foo/images/ok.png
|
||||
$fileRelative = substr($matches[2], strlen('plugins/'));
|
||||
$fileAbsolute = $absPath . $fileRelative;
|
||||
if (file_exists($fileAbsolute)) {
|
||||
return $matches[1] . $relativePath . $fileRelative;
|
||||
}
|
||||
} elseif ($matches[1] === '@import "') {
|
||||
$fileRelative = $baseDirectory . '/' . $matches[2];
|
||||
$fileAbsolute = $absPath . str_replace($relativePath, '', $fileRelative);
|
||||
if (file_exists($fileAbsolute)) {
|
||||
return $matches[1] . $baseDirectory . '/' . $matches[2];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$publicPath = $matches[1] . $matches[2];
|
||||
}
|
||||
|
||||
return $publicPath;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param UIAsset $uiAsset
|
||||
* @return int
|
||||
*/
|
||||
protected function countDirectoriesInPathToRoot($uiAsset)
|
||||
{
|
||||
$rootDirectory = realpath($uiAsset->getBaseDirectory());
|
||||
|
||||
if ($rootDirectory != PATH_SEPARATOR
|
||||
&& substr($rootDirectory, -strlen(PATH_SEPARATOR)) !== PATH_SEPARATOR) {
|
||||
$rootDirectory .= PATH_SEPARATOR;
|
||||
}
|
||||
$rootDirectoryLen = strlen($rootDirectory);
|
||||
return $rootDirectoryLen;
|
||||
}
|
||||
}
|
66
msd2/tracking/piwik/core/AssetManager/UIAssetMinifier.php
Normal file
66
msd2/tracking/piwik/core/AssetManager/UIAssetMinifier.php
Normal file
@ -0,0 +1,66 @@
|
||||
<?php
|
||||
/**
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*
|
||||
* @method static \Piwik\AssetManager\UIAssetMinifier getInstance()
|
||||
*/
|
||||
namespace Piwik\AssetManager;
|
||||
|
||||
use Exception;
|
||||
use JShrink\Minifier;
|
||||
use Piwik\Singleton;
|
||||
|
||||
class UIAssetMinifier extends Singleton
|
||||
{
|
||||
const MINIFIED_JS_RATIO = 100;
|
||||
|
||||
protected function __construct()
|
||||
{
|
||||
self::validateDependency();
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if the provided JavaScript content has already been minified or not.
|
||||
* The heuristic is based on a custom ratio : (size of file) / (number of lines).
|
||||
* The threshold (100) has been found empirically on existing files :
|
||||
* - the ratio never exceeds 50 for non-minified content and
|
||||
* - it never goes under 150 for minified content.
|
||||
*
|
||||
* @param string $content Contents of the JavaScript file
|
||||
* @return boolean
|
||||
*/
|
||||
public function isMinifiedJs($content)
|
||||
{
|
||||
$lineCount = substr_count($content, "\n");
|
||||
|
||||
if ($lineCount == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$contentSize = strlen($content);
|
||||
|
||||
$ratio = $contentSize / $lineCount;
|
||||
|
||||
return $ratio > self::MINIFIED_JS_RATIO;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $content
|
||||
* @return string
|
||||
*/
|
||||
public function minifyJs($content)
|
||||
{
|
||||
return Minifier::minify($content);
|
||||
}
|
||||
|
||||
private static function validateDependency()
|
||||
{
|
||||
if (!class_exists("JShrink\\Minifier")) {
|
||||
throw new Exception("JShrink could not be found, maybe you are using Matomo from git and need to update Composer. $ php composer.phar update");
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user