public function fonts(array $params) { $font = $params['font']; if (strlen($font) < 1) { return false; } $fontfiles = Registry::getInstance()->assets['fonts']; if (isset($fontfiles[$font])) { $asset = new FileAsset($fontfiles[$font]); switch (strtolower(substr($font, strpos($font, ".")))) { case ".eot": $type = "application/vnd.ms-fontobject"; break; case "otf": $type = "font/opentype"; break; case "ttf": $type = "application/x-font-ttf"; break; case ".woff": $type = "application/x-font-woff"; break; default: $type = "application/x-font"; } header('Content-Type: ' . $type); echo $asset->dump(); } return true; }
public function onTerminate(CarewEvent $carewEvent) { foreach ($this->finder->in($carewEvent->getArgument('webDir')) as $file) { $asset = new FileAsset($file->getPathname(), array($this->getFilter())); file_put_contents($file->getPathname(), $asset->dump()); } }
public function filterLoad(AssetInterface $asset) { $importFilter = $this->importFilter; $sourceRoot = $asset->getSourceRoot(); $sourcePath = $asset->getSourcePath(); $callback = function ($matches) use($importFilter, $sourceRoot, $sourcePath) { if (!$matches['url']) { return $matches[0]; } if (null === $sourceRoot) { return $matches[0]; } $importRoot = $sourceRoot; if (false !== strpos($matches['url'], '://')) { // absolute list($importScheme, $tmp) = explode('://', $matches['url'], 2); list($importHost, $importPath) = explode('/', $tmp, 2); $importRoot = $importScheme . '://' . $importHost; } elseif (0 === strpos($matches['url'], '//')) { // protocol-relative list($importHost, $importPath) = explode('/', substr($matches['url'], 2), 2); $importHost = '//' . $importHost; } elseif ('/' == $matches['url'][0]) { // root-relative $importPath = substr($matches['url'], 1); } elseif (null !== $sourcePath) { // document-relative $importPath = $matches['url']; if ('.' != ($sourceDir = dirname($sourcePath))) { $importPath = $sourceDir . '/' . $importPath; } } else { return $matches[0]; } // ignore other imports if ('css' != pathinfo($importPath, PATHINFO_EXTENSION)) { return $matches[0]; } $importSource = $importRoot . '/' . $importPath; if (false !== strpos($importSource, '://') || 0 === strpos($importSource, '//')) { $import = new HttpAsset($importSource, array($importFilter), true); } elseif (!file_exists($importSource)) { // ignore not found imports return $matches[0]; } else { $import = new FileAsset($importSource, array($importFilter), $importRoot, $importPath); } $import->setTargetPath($sourcePath); return $import->dump(); }; $content = $asset->getContent(); $lastHash = md5($content); do { $content = $this->filterImports($content, $callback); $hash = md5($content); } while ($lastHash != $hash && ($lastHash = $hash)); $asset->setContent($content); }
public function background(array $params) { $backgrounds = Registry::getInstance()->assets['backgrounds']; $dt = new \DateTime(); $dt->setTime(date("H"), 0, 0); srand($dt->getTimestamp()); $asset = new \Assetic\Asset\FileAsset($backgrounds[rand(0, count($backgrounds) - 1)]); header('Content-Type: image/jpeg'); header("Cache-Control: public, max-age=3600, s-max-age=1800"); echo $asset->dump(); return true; }
/** * @dataProvider getFilters */ public function testImport($filter1, $filter2) { $asset = new FileAsset(__DIR__ . '/fixtures/cssimport/main.css', array(), __DIR__ . '/fixtures/cssimport', 'main.css'); $asset->setTargetPath('foo/bar.css'); $asset->ensureFilter($filter1); $asset->ensureFilter($filter2); $expected = <<<CSS /* main.css */ /* import.css */ body { color: red; } /* more/evenmore/deep1.css */ /* more/evenmore/deep2.css */ body { background: url(../more/evenmore/bg.gif); } body { color: black; } CSS; $this->assertEquals($expected, $asset->dump(), '->filterLoad() inlines CSS imports'); }
/** * Integrator brand stylesheet. * * @Route("/style") * @Method({"GET"}) * * @param Request $request * @return Response */ public function indexAction(Request $request) { // Get vendor key $vendorKey = $this->getVendorCredentials()['vendorKey']; $d = DIRECTORY_SEPARATOR; // Get the system web directory $sysDir = $this->container->get('kernel')->getRootdir() . "{$d}..{$d}web{$d}"; // Get the style sheet input path to the uncompiled (raw from IRIS) vendor CSS file $sysPathUncompiled = "{$sysDir}css{$d}integrator{$d}uncompiled{$d}{$vendorKey}.less"; // Get the style sheet output path to the compiled (post Assetic) vendor CSS file $sysPathCompiled = "{$sysDir}css{$d}integrator{$d}compiled{$d}{$vendorKey}.css"; $compiledCss = ''; // Does a compiled CSS file exist for it that is also under x seconds old? if (!file_exists($sysPathCompiled) || $this->httpCacheMaxAgeInSeconds < filemtime($sysPathCompiled)) { // No CSS file exists or it's stale, make a new one // Get vendor style config, import the main style into it, and store it to disc in the uncompiled directory $vendorStyle = $this->getVendorStyle(); $vendorStyle .= "\n\n@import '../style.less';"; // todo Make better file_put_contents($sysPathUncompiled, $vendorStyle); /** @var CssRewriteFilter $asseticFilterCssRewrite */ $asseticFilterCssRewrite = $this->container->get('assetic.filter.cssrewrite'); /** @var LessphpFilter $asseticFilterLessPhp */ $asseticFilterLessPhp = $this->container->get('assetic.filter.lessphp'); $asseticFilterLessPhp->setFormatter('classic'); $asseticFilterLessPhp->setPreserveComments(false); $style = new FileAsset($sysPathUncompiled, array($asseticFilterCssRewrite, $asseticFilterLessPhp)); // Dump compiled CSS to file $compiledCss = $style->dump(); file_put_contents($sysPathCompiled, $compiledCss); } else { // Grab compiled CSS from file $compiledCss = file_get_contents($sysPathCompiled); } // Output compiled CSS $this->response->headers->set('Content-Type', 'text/css'); $this->response->setContent($compiledCss); return $this->response; }
/** * @param RequestResponseEvent $event */ public function listen(RequestResponseEvent $event) { $path = $event->getRequest()->getPathInfo(); $parts = pathinfo($path); $parts = array_merge(array('dirname' => '', 'basename' => '', 'extension' => '', 'filename'), $parts); switch (strtolower($parts['extension'])) { case 'css': //possible it's not yet compiled less file? $lessFile = $this->container->getApplication()->getWebRoot() . $path . '.less'; if (is_file($lessFile)) { $asset = new FileAsset($lessFile); $asset->ensureFilter(new LessphpFilter()); $content = $this->container->getCache()->fetch('assets_404', $path, function () use($asset) { return $asset->dump(); }, $asset->getLastModified(), 0, true); $event->setResponse(new Response($content, 200, array('Content-Type' => 'text/css'))); $event->stopPropagation(); return; } break; } }
/** * 合并文件,并且返回合并之后的文件名 * * @param string $moduleUniqueId * @param array $fileRelativePathArray * @param string $fileExt 合并之后的文件扩展名 * @param callback $fileContentFilter 对每个文件的内容做 filter * * @return string 合并之后的文件名 */ private function mergeAssetCssJsFile($moduleUniqueId, array $fileRelativePathArray, $fileExt, $fileContentFilter = null) { if (empty($fileRelativePathArray)) { throw new \InvalidArgumentException('fileRelativePathArray can not be empty'); } $targetModuleBasePath = $this->assetBasePath . DIRECTORY_SEPARATOR . $this->getModulePublishRelativeDir($moduleUniqueId) . DIRECTORY_SEPARATOR; // 计算合并之后的文件名 $targetFileNameSource = ''; foreach ($fileRelativePathArray as $relativeAssetPath) { // 智能发布资源 $this->publishAsset($moduleUniqueId, $relativeAssetPath); $sourcePath = $targetModuleBasePath . $relativeAssetPath; if (!is_file($sourcePath)) { printLog('Calculate FileNameSource Error : [' . $sourcePath . '] is not a regular file', 'AssetManager', \Core\Log\Base::ERROR); continue; } $targetModifyTime = filemtime($sourcePath); $targetFileNameSource .= '{' . $sourcePath . '[' . $targetModifyTime . ']}'; } // 目标文件名 $targetFileNameSourceMd5 = md5($targetFileNameSource); $targetFileName = $targetFileNameSourceMd5 . '.min' . $fileExt; // 合并文件已经存在,直接退出就可以了 if (is_file($targetModuleBasePath . $targetFileName)) { goto out; } // 打印 log printLog($targetFileNameSource, 'AssetManager'); // 做文件的合并 $filterArray = array(); // 建立对应的 filter if ('.js' == $fileExt) { $filterArray = array(new JSMinFilter()); } elseif ('.css' == $fileExt) { $filterArray = array(new CssImportFilter(), new CssRewriteFilter(), new CssMinFilter()); } else { // do nothing } $mergeFileContent = ''; foreach ($fileRelativePathArray as $relativeAssetPath) { $sourcePath = $targetModuleBasePath . $relativeAssetPath; if (!is_file($sourcePath)) { printLog('Merge File Error : [' . $sourcePath . '] is not a regular file', 'AssetManager', \Core\Log\Base::ERROR); continue; } // 我们采用 Assetic 来做文件处理 $fileAsset = new FileAsset($targetModuleBasePath . $relativeAssetPath, $filterArray, $targetModuleBasePath, $relativeAssetPath); $fileAsset->setTargetPath('.'); $mergeFileContent .= $fileContentFilter ? call_user_func_array($fileContentFilter, array($relativeAssetPath, $fileAsset->dump())) : $fileAsset->dump(); unset($fileAsset); // 释放内存 } // 生成合并之后的文件 file_put_contents($targetModuleBasePath . $targetFileName, $mergeFileContent); out: return $targetFileName; }
/** * When first part of a module name is not specified in paths and not equals baseUrl, we can't find module * so this module exclusions will not be excluded * * @covers Hearsay\RequireJSBundle\Assetic\Filter\RJsFilter::filterDump * @covers Hearsay\RequireJSBundle\Assetic\Filter\RJsFilter::addModule * @covers Hearsay\RequireJSBundle\Assetic\Filter\RJsFilter::addOption */ public function testNotFindModuleNameAmongPaths() { $this->filter->addOption('preserveLicenseComments', false); // registering optimizer modules config $this->filter->addModule("module/file3", array("include" => array("module/file", "module/file2"))); $this->filter->addModule("module2/file4", array("exclude" => array("module/file3"))); $asset = new FileAsset(__DIR__ . '/modules/module2/file4.js'); $asset->ensureFilter($this->filter); // expecting result contains only content of file4 although file4 depends on file3 and file3 depends on file 2 and file $this->assertRegExp('/^define\\("module\\/file2",\\{js:"got it twice"\\}\\),define\\("module\\/file",\\{js:"got it"\\}\\),' . 'require\\(\\["module\\/file2","module\\/file"\\],function\\(e,t\\)\\{return console.log\\(e,t\\)\\}\\),' . 'define\\("module\\/file3",function\\(\\)\\{\\}\\),require\\(\\["module\\/file3"\\],function\\(e\\)\\{return console.log\\(e\\)\\}\\),' . 'define\\(".{32}",function\\(\\)\\{\\}\\);$/', $asset->dump(), 'Defined exclusions for modules/module2/file4.js excluded incorrectly'); }
public function filterDump(AssetInterface $asset) { $sourceBase = $asset->getSourceRoot(); $sourcePath = $asset->getSourcePath(); $targetPath = $asset->getTargetPath(); $sourceDir = $asset->getSourceDirectory(); if (null === $sourcePath || null === $targetPath || $sourcePath == $targetPath) { return; } // learn how to get from the target back to the source if (false !== strpos($sourceBase, '://')) { list($scheme, $url) = explode('://', $sourceBase . '/' . $sourcePath, 2); list($host, $path) = explode('/', $url, 2); $host = $scheme . '://' . $host . '/'; $path = false === strpos($path, '/') ? '' : dirname($path); $path .= '/'; } else { // assume source and target are on the same host $host = ''; // pop entries off the target until it fits in the source if ('.' == dirname($sourcePath)) { $path = str_repeat('../', substr_count($targetPath, '/')); } elseif ('.' == ($targetDir = dirname($targetPath))) { $path = dirname($sourcePath) . '/'; } else { $path = ''; while (0 !== strpos($sourcePath, $targetDir)) { if (false !== ($pos = strrpos($targetDir, '/'))) { $targetDir = substr($targetDir, 0, $pos); $path .= '../'; } else { $targetDir = ''; $path .= '../'; break; } } $path .= ltrim(substr(dirname($sourcePath) . '/', strlen($targetDir)), '/'); } } $content = $this->filterReferences($asset->getContent(), function ($matches) use($sourceDir, $host) { $path = $sourceDir; if (false !== strpos($matches['url'], '://') || 0 === strpos($matches['url'], '//') || 0 === strpos($matches['url'], 'data:')) { // absolute or protocol-relative or data uri return $matches[0]; } if (isset($matches['url'][0]) && '/' == $matches['url'][0]) { // root relative return str_replace($matches['url'], $host . $matches['url'], $matches[0]); } // document relative $url = $matches['url']; while (0 === strpos($url, '../') && 2 <= substr_count($path, '/')) { $path = substr($path, 0, strrpos(rtrim($path, '/'), '/') + 1); $url = substr($url, 3); } $originalAsset = $path . $url; $originalAsset = reset(preg_split("/[#?]/", $originalAsset)); $rootDir = $this->kernel->getRootDir(); $rootDir = substr($rootDir, 0, -3); $relativeAsset = substr($originalAsset, strlen($rootDir)); $assetName = $this->assetFactory->generateAssetName($relativeAsset); $targetAssetPath = $rootDir . 'web/' . $url; $targetParts = explode('/', $targetAssetPath); $fileName = $assetName . '_' . array_pop($targetParts); array_push($targetParts, $fileName); $targetAssetPath = implode('/', $targetParts); $targetAssetPath = reset(preg_split("/[#?]/", $targetAssetPath)); $urlParts = explode('/', $matches['url']); array_pop($urlParts); array_push($urlParts, $fileName); $urlNew = implode('/', $urlParts); if (!is_dir($dir = dirname($targetAssetPath))) { if (false === @mkdir($dir, 0777, true)) { throw new \RuntimeException('Unable to create directory ' . $dir); } } $asset = new FileAsset($originalAsset); try { $contents = $asset->dump(); } catch (\Exception $e) { echo 'WARNING: ' . $e->getMessage(); } if (false === @file_put_contents($targetAssetPath, $contents)) { throw new \RuntimeException('Unable to write file ' . $targetAssetPath); } $result = str_replace($matches['url'], $urlNew, $matches[0]); return $result; }); $asset->setContent($content); }
/** * Add yaml css to layout. * * @param Database_Result $objPage * @param Database_Result $objLayout * @param PageRegular $objPageRegular */ public function hookGetPageLayout($objPage, $objLayout, $objPageRegular) { $autoInclude = $objLayout->xyaml_auto_include || $GLOBALS['TL_CONFIG']['yaml_auto_include']; $path = $objLayout->xyaml_auto_include ? $objLayout->xyaml_path : $GLOBALS['TL_CONFIG']['yaml_path']; if ($autoInclude && $objLayout->xyaml && !empty($path)) { $mode = $objLayout->xyaml_auto_include ? $objLayout->xyaml_mode : $GLOBALS['TL_CONFIG']['yaml_mode']; $filter = $objLayout->xyaml_auto_include ? $objLayout->xyaml_compass_filter : $GLOBALS['TL_CONFIG']['yaml_compass_filter']; $path = \Compat::resolveFile($path, false); if ($path) { if (!is_array($GLOBALS['TL_CSS'])) { $GLOBALS['TL_CSS'] = array(); } if (!is_array($GLOBALS['TL_JAVASCRIPT'])) { $GLOBALS['TL_JAVASCRIPT'] = array(); } $useSass = $mode == 'sass'; if ($useSass) { $activeModules = \Config::getInstance()->getActiveModules(); if (!in_array('assetic', $activeModules)) { throw new \RuntimeException('Cannot use YAML SASS without assetic extension'); } global $container; /** @var AsseticFactory $factory */ $factory = $container['assetic.factory']; $filters = array($factory->createFilterOrChain($filter)); } else { $filters = array(); } // add yaml addons $addons = deserialize($objLayout->xyaml_addons, true); $this->addFiles($objPage, $objLayout, $addons, $GLOBALS['YAML_ADDONS'], $path, $useSass, $filters); // add yaml forms $forms = deserialize($objLayout->xyaml_forms, true); $this->addFiles($objPage, $objLayout, $forms, $GLOBALS['YAML_FORMS'], $path, $useSass, $filters); // add yaml navigation $navigations = deserialize($objLayout->xyaml_navigation, true); $this->addFiles($objPage, $objLayout, $navigations, $GLOBALS['YAML_NAVIGATION'], $path, $useSass, $filters); // add yaml print $prints = deserialize($objLayout->xyaml_print, true); $this->addFiles($objPage, $objLayout, $prints, $GLOBALS['YAML_PRINT'], $path, $useSass, $filters); // add yaml screen $screens = deserialize($objLayout->xyaml_screen, true); $this->addFiles($objPage, $objLayout, $screens, $GLOBALS['YAML_SCREEN'], $path, $useSass, $filters); // add yaml base $this->addStyleSheets($objPage, $objLayout, array('core/base.css'), $path, $useSass, $filters); // add yaml iehacks if ($objLayout->xyaml_iehacks) { $ieHacks = $path . '/core/iehacks.min.css'; if ($useSass) { $targetPath = 'assets/css/iehacks-' . substr(md5($path), 0, 8) . '.css'; if (!file_exists(TL_ROOT . '/' . $targetPath)) { // load asset $asset = new FileAsset(TL_ROOT . '/' . $path . '/core/_iehacks.scss', $filters, TL_ROOT, $path . '/core/_iehacks.scss'); $asset->setTargetPath(TL_ROOT . '/' . $targetPath); $asset->dump(); } $ieHacks = $targetPath; } $GLOBALS['TL_HEAD']['xyaml_iehacks'] = <<<EOF <!--[if lte IE 7]> <link rel="stylesheet" href="{$ieHacks}" type="text/css"/> <![endif]--> EOF; } // linearize level if ($objLayout->xyaml_subcolumns_linearize) { $cssClass = ' linearize-level-' . $objLayout->xyaml_subcolumns_linearize; $GLOBALS['TL_SUBCL']['yaml4']['scclass'] .= $cssClass; $GLOBALS['TL_SUBCL']['yaml4_additional']['scclass'] .= $cssClass; } } } return false; }