It performs the following actions:
- Identifies required assets
- Includes assets in the rendered HTML page
- Manages asset merging and minifying
- Manages server-side cache
Whether assets are included individually or as merged files is defined by
the global option 'disable_merged_assets'. See the documentation in the global
config for more information.
/** * Return the base.less compiled to css * * @return string */ public function getUpdaterJs() { Common::sendHeader('Content-Type: application/javascript; charset=UTF-8'); Common::sendHeader('Cache-Control: max-age=' . 60 * 60); $files = array('libs/bower_components/jquery/dist/jquery.min.js', 'libs/bower_components/jquery-ui/ui/minified/jquery-ui.min.js', 'libs/bower_components/materialize/dist/js/materialize.min.js', 'plugins/Morpheus/javascripts/piwikHelper.js', 'plugins/CoreHome/javascripts/donate.js', 'plugins/CoreUpdater/javascripts/updateLayout.js', 'libs/bower_components/angular/angular.min.js', 'libs/bower_components/angular-sanitize/angular-sanitize.js', 'libs/bower_components/angular-animate/angular-animate.js', 'libs/bower_components/angular-cookies/angular-cookies.js', 'libs/bower_components/ngDialog/js/ngDialog.min.js', 'plugins/CoreHome/angularjs/common/services/service.module.js', 'plugins/CoreHome/angularjs/common/filters/filter.module.js', 'plugins/CoreHome/angularjs/common/filters/translate.js', 'plugins/CoreHome/angularjs/common/directives/directive.module.js', 'plugins/CoreHome/angularjs/common/directives/focus-anywhere-but-here.js', 'plugins/CoreHome/angularjs/piwikApp.config.js', 'plugins/CoreHome/angularjs/piwikApp.js', 'plugins/Installation/javascripts/installation.js'); return AssetManager::compileCustomJs($files); }
/** * Called on Core install, update, plugin enable/disable * Will clear all cache that could be affected by the change in configuration being made */ public static function deleteAllCacheOnUpdate($pluginName = false) { AssetManager::getInstance()->removeMergedAssets($pluginName); View::clearCompiledTemplates(); Cache::deleteTrackerCache(); self::clearPhpCaches(); }
/** * @group Core */ public function test_removeMergedAssets_PluginNameSpecified_NonCoreThemeWithAssets() { list($stylesheetAsset, $coreJsAsset, $nonCoreJsAsset) = $this->generateAllMergedAssets(); $this->assetManager->removeMergedAssets(self::NON_CORE_THEME_PLUGIN_NAME); $this->assertFalse($stylesheetAsset->exists()); $this->assertTrue($coreJsAsset->exists()); $this->assertFalse($nonCoreJsAsset->exists()); }
protected function execute(InputInterface $input, OutputInterface $output) { $specs = $input->getArgument('specs'); $persistFixtureData = $input->getOption("persist-fixture-data"); $keepSymlinks = $input->getOption('keep-symlinks'); $printLogs = $input->getOption('print-logs'); $drop = $input->getOption('drop'); $assumeArtifacts = $input->getOption('assume-artifacts'); $plugin = $input->getOption('plugin'); $skipDeleteAssets = $input->getOption('skip-delete-assets'); $core = $input->getOption('core'); $extraOptions = $input->getOption('extra-options'); $storeInUiTestsRepo = $input->getOption('store-in-ui-tests-repo'); $screenshotRepo = $input->getOption('screenshot-repo'); if (!$skipDeleteAssets) { AssetManager::getInstance()->removeMergedAssets(); } $this->writeJsConfig(); $options = array(); if ($persistFixtureData) { $options[] = "--persist-fixture-data"; } if ($keepSymlinks) { $options[] = "--keep-symlinks"; } if ($printLogs) { $options[] = "--print-logs"; } if ($drop) { $options[] = "--drop"; } if ($assumeArtifacts) { $options[] = "--assume-artifacts"; } if ($plugin) { $options[] = "--plugin=" . $plugin; } if ($core) { $options[] = "--core"; } if ($storeInUiTestsRepo) { $options[] = "--store-in-ui-tests-repo"; } if ($screenshotRepo) { $options[] = "--screenshot-repo"; } if ($extraOptions) { $options[] = $extraOptions; } $options = implode(" ", $options); $specs = implode(" ", $specs); $cmd = "phantomjs '" . PIWIK_INCLUDE_PATH . "/tests/lib/screenshot-testing/run-tests.js' {$options} {$specs}"; $output->writeln('Executing command: <info>' . $cmd . '</info>'); $output->writeln(''); passthru($cmd, $returnCode); return $returnCode; }
protected function execute(InputInterface $input, OutputInterface $output) { if (!file_exists(PIWIK_INCLUDE_PATH . '/tests/UI/expected-ui-screenshots/README.md')) { // REMOVE THIS CHECK AFTER 1st April 2015 $output->writeln('<error>"tests/UI/expected-ui-screenshots" does not exist. You might have to run "git submodule update --init"</error>'); return; } $specs = $input->getArgument('specs'); $persistFixtureData = $input->getOption("persist-fixture-data"); $keepSymlinks = $input->getOption('keep-symlinks'); $printLogs = $input->getOption('print-logs'); $drop = $input->getOption('drop'); $assumeArtifacts = $input->getOption('assume-artifacts'); $plugin = $input->getOption('plugin'); $skipDeleteAssets = $input->getOption('skip-delete-assets'); $core = $input->getOption('core'); if (!$skipDeleteAssets) { AssetManager::getInstance()->removeMergedAssets(); } $options = array(); if ($persistFixtureData) { $options[] = "--persist-fixture-data"; } if ($keepSymlinks) { $options[] = "--keep-symlinks"; } if ($printLogs) { $options[] = "--print-logs"; } if ($drop) { $options[] = "--drop"; } if ($assumeArtifacts) { $options[] = "--assume-artifacts"; } if ($plugin) { $options[] = "--plugin=" . $plugin; } if ($core) { $options[] = "--core"; } $options = implode(" ", $options); $specs = implode(" ", $specs); $cmd = "phantomjs '" . PIWIK_INCLUDE_PATH . "/tests/lib/screenshot-testing/run-tests.js' {$options} {$specs}"; $output->writeln('Executing command: <info>' . $cmd . '</info>'); $output->writeln(''); passthru($cmd); }
public function performSetUp($setupEnvironmentOnly = false) { parent::performSetUp($setupEnvironmentOnly); $this->createSegments(); $this->setupDashboards(); AssetManager::getInstance()->removeMergedAssets(); $visitorIdDeterministic = bin2hex(Db::fetchOne("SELECT idvisitor FROM " . Common::prefixTable('log_visit') . " WHERE idsite = 2 AND location_latitude IS NOT NULL LIMIT 1")); $this->testEnvironment->forcedIdVisitor = $visitorIdDeterministic; $this->testEnvironment->overlayUrl = $this->getLocalTestSiteUrl(); $this->createOverlayTestSite(); $forcedNowTimestamp = Option::get("Tests.forcedNowTimestamp"); if ($forcedNowTimestamp == false) { throw Exception("Incorrect fixture setup, Tests.forcedNowTimestamp option does not exist! Run the setup again."); } $this->testEnvironment->forcedNowTimestamp = $forcedNowTimestamp; $this->testEnvironment->save(); }
public function testIsMergedAssetsDisabled() { $manager = new AssetManager(); // default $this->assertFalse($manager->isMergedAssetsDisabled()); // with configuration $defaultConfig = Config::getInstance()->Development['disable_merged_assets']; Config::getInstance()->Development['disable_merged_assets'] = false; $this->assertFalse($manager->isMergedAssetsDisabled()); Config::getInstance()->Development['disable_merged_assets'] = true; $this->assertTrue($manager->isMergedAssetsDisabled()); // reset the config Config::getInstance()->Development['disable_merged_assets'] = $defaultConfig; // with $_GET parameter $_GET['disable_merged_assets'] = '1'; $this->assertTrue($manager->isMergedAssetsDisabled()); unset($_GET['disable_merged_assets']); $_GET['disable_merged_assets'] = '0'; $this->assertFalse($manager->isMergedAssetsDisabled()); unset($_GET['disable_merged_assets']); }
/** * Prints out the CSS for installer/updater * * During installation and update process, we load a minimal Less file. * At this point Piwik may not be setup yet to write files in tmp/assets/ * so in this case we compile and return the string on every request. */ public function getBaseCss() { @header('Content-Type: text/css'); return AssetManager::getInstance()->getCompiledBaseCss()->getContent(); }
protected function addFunction_includeAssets() { $includeAssetsFunction = new Twig_SimpleFunction('includeAssets', function ($params) { if (!isset($params['type'])) { throw new Exception("The function includeAssets needs a 'type' parameter."); } $assetType = strtolower($params['type']); switch ($assetType) { case 'css': return AssetManager::getInstance()->getCssInclusionDirective(); case 'js': return AssetManager::getInstance()->getJsInclusionDirective(); default: throw new Exception("The twig function includeAssets 'type' parameter needs to be either 'css' or 'js'."); } }); $this->twig->addFunction($includeAssetsFunction); }
/** * Output the merged non core JavaScript file. * This method is called when the asset manager is enabled. * * @see core/AssetManager.php */ public function getNonCoreJs() { $jsMergedFile = AssetManager::getInstance()->getMergedNonCoreJavaScript(); $this->serveJsFile($jsMergedFile); }
protected function applyFilter_cacheBuster($output) { $assetManager = AssetManager::getInstance(); $stylesheet = $assetManager->getMergedStylesheetAsset(); if ($stylesheet->exists()) { $content = $stylesheet->getContent(); } else { $content = $assetManager->getMergedStylesheet()->getContent(); } $cacheBuster = UIAssetCacheBuster::getInstance(); $tagJs = 'cb=' . $cacheBuster->piwikVersionBasedCacheBuster(); $tagCss = 'cb=' . $cacheBuster->md5BasedCacheBuster($content); $pattern = array('~<script type=[\'"]text/javascript[\'"] src=[\'"]([^\'"]+)[\'"]>~', '~<script src=[\'"]([^\'"]+)[\'"] type=[\'"]text/javascript[\'"]>~', '~<link rel=[\'"]stylesheet[\'"] type=[\'"]text/css[\'"] href=[\'"]([^\'"]+)[\'"] ?/?>~', '~(src|href)=\\"index.php\\?module=([A-Za-z0-9_]+)&action=([A-Za-z0-9_]+)\\?cb=~'); $replace = array('<script type="text/javascript" src="$1?' . $tagJs . '">', '<script type="text/javascript" src="$1?' . $tagJs . '">', '<link rel="stylesheet" type="text/css" href="$1?' . $tagCss . '" />', '$1="index.php?module=$2&action=$3&cb='); return preg_replace($pattern, $replace, $output); }
public static function compileCustomStylesheets($files) { $assetManager = new AssetManager(); $fetcher = new StaticUIAssetFetcher($files, $priorityOrder = array(), $theme = null); $assetManager->setMinimalStylesheetFetcher($fetcher); return $assetManager->getCompiledBaseCss()->getContent(); }
private function getCompressedFileLocation() { return \Piwik\AssetManager::getInstance()->getAssetDirectory() . '/' . basename(TEST_FILE_LOCATION); }
/** * @return boolean */ private function isMergedAssetsDisabled() { return AssetManager::getInstance()->isMergedAssetsDisabled(); }
/** * Writes the public key to the client JavaScript file. * * @param array $key Key to write (contains exponent "e" and modulus "n") */ protected static function writePublicKeyJS($key) { // write the key to the file $content = 'var LoginEncrypted_PublicKey = {e:\'' . $key['e'] . '\', n:\'' . $key['n'] . '\'};'; file_put_contents(__DIR__ . static::PUBLIC_KEY_JS_FILE, $content); // remove merged piwik JS file, to force its re-generation including the newly written file // Note: Plugin name provided, so that, depending on its type, either "core" or "non_core" JS // gets removed from /tmp/assets. Otherwise, both JS would be removed, unnecessarily. $pluginName = explode('\\', get_called_class()); AssetManager::getInstance()->removeMergedAssets($pluginName[2]); }