/** * @param \AssetsBundle\AssetFile\AssetFile $oAssetFile * @return string */ public function filterAssetFile(\AssetsBundle\AssetFile\AssetFile $oAssetFile) { // Prevent time limit errors set_time_limit(0); $oLessParser = $this->getLessParser(); $oLessParser->Reset(); return trim($oLessParser->parseFile($oAssetFile->getAssetFilePath())->getCss()); }
/** * @param \AssetsBundle\AssetFile\AssetFile $oAssetFile * @return string */ public function filterAssetFile(\AssetsBundle\AssetFile\AssetFile $oAssetFile) { $oLessParser = new \lessc(); $oLessParser->addImportDir(getcwd()); $oLessParser->setAllowUrlRewrite(true); //Prevent time limit errors set_time_limit(0); return trim($oLessParser->compile($oAssetFile->getAssetFileContents())); }
/** * @see \Zend\ServiceManager\FactoryInterface::createService() * @param \Zend\ServiceManager\ServiceLocatorInterface $oServiceLocator * @throws \UnexpectedValueException * @return \AssetsBundle\Service\ServiceOptions */ public function createService(\Zend\ServiceManager\ServiceLocatorInterface $oServiceLocator) { $aConfiguration = $oServiceLocator->get('Config'); if (!isset($aConfiguration['assets_bundle'])) { throw new \UnexpectedValueException('AssetsBundle configuration is undefined'); } $aOptions = $aConfiguration['assets_bundle']; if ($aOptions instanceof \Traversable) { $aOptions = \Zend\Stdlib\ArrayUtils::iteratorToArray($aOptions); } elseif (!is_array($aOptions)) { throw new \InvalidArgumentException('"assets_bundle" configuration expects an array or Traversable object; received "' . (is_object($aOptions) ? get_class($aOptions) : gettype($aOptions)) . '"'); } //Define base URL of the application if (!isset($aOptions['baseUrl'])) { if (($oRequest = $oServiceLocator->get('request')) instanceof \Zend\Http\PhpEnvironment\Request) { $aOptions['baseUrl'] = $oRequest->getBaseUrl(); } else { $oRequest = new \Zend\Http\PhpEnvironment\Request(); $aOptions['baseUrl'] = $oRequest->getBaseUrl(); } } //Retrieve filters if (isset($aOptions['view_helper_plugins'])) { $aViewHelperPlugins = $aOptions['view_helper_plugins']; if ($aViewHelperPlugins instanceof \Traversable) { $aViewHelperPlugins = \Zend\Stdlib\ArrayUtils::iteratorToArray($aOptions); } elseif (!is_array($aViewHelperPlugins)) { throw new \InvalidArgumentException('Assets bundle "filters" option expects an array or Traversable object; received "' . (is_object($aViewHelperPlugins) ? get_class($aViewHelperPlugins) : gettype($aViewHelperPlugins)) . '"'); } $oViewHelperPluginManager = $oServiceLocator->get('ViewHelperManager'); foreach ($aViewHelperPlugins as $sAssetFileType => $oViewHelperPlugin) { if (!\AssetsBundle\AssetFile\AssetFile::assetFileTypeExists($sAssetFileType)) { throw new \LogicException('Asset file type "' . $sAssetFileType . '" is not valid'); } if (is_string($oViewHelperPlugin)) { if ($oViewHelperPluginManager->has($oViewHelperPlugin)) { $oViewHelperPlugin = $oViewHelperPluginManager->get($oViewHelperPlugin); } elseif (class_exists($oViewHelperPlugin)) { $oViewHelperPlugin = new $oViewHelperPlugin(); } else { throw new \LogicException('View helper plugin "' . $oViewHelperPlugin . '" is not a registered service or an existing class'); } if ($oViewHelperPlugin instanceof \Zend\View\Helper\HelperInterface) { $aViewHelperPlugins[$sAssetFileType] = $oViewHelperPlugin; } else { throw new \LogicException('View helper plugin expects an instance of "\\Zend\\View\\Helper\\HelperInterface", "' . get_class($oViewHelperPlugin) . '" given'); } } } $aOptions['view_helper_plugins'] = $aViewHelperPlugins; } //Unset filters unset($aOptions['filters']); return new \AssetsBundle\Service\ServiceOptions($aOptions); }
/** * @param \AssetsBundle\AssetFile\AssetFile $oAssetFile * @return boolean */ protected function assetFileShouldBeOptimize(\AssetsBundle\AssetFile\AssetFile $oAssetFile) { return $this->imagecreatefromstringExists && !!$oAssetFile->getAssetFileContents(); }
/** * Cache Js asset files and retrieve cached asset files * @return array */ protected function cacheJsAssetFiles() { if ($bIsProduction = $this->getOptions()->isProduction()) { //Retrieve asset file filters manager $oAssetFileFiltersManager = $this->getAssetFileFiltersManager(); //Retrieve Js asset file filter if available $oJsFileFilter = $oAssetFileFiltersManager->has(\AssetsBundle\AssetFile\AssetFile::ASSET_JS) ? $oAssetFileFiltersManager->get(\AssetsBundle\AssetFile\AssetFile::ASSET_JS) : null; //Create tmp asset file \Zend\Stdlib\ErrorHandler::stop(true); $sTmpAssetFilePath = tempnam($this->getOptions()->getTmpDirPath(), '.' . \AssetsBundle\AssetFile\AssetFile::getAssetFileDefaultExtension(\AssetsBundle\AssetFile\AssetFile::ASSET_JS)); \Zend\Stdlib\ErrorHandler::start(); $oTmpAssetFile = new \AssetsBundle\AssetFile\AssetFile(array('asset_file_type' => \AssetsBundle\AssetFile\AssetFile::ASSET_JS, 'asset_file_path' => $sTmpAssetFilePath)); foreach ($this->getAssetFilesConfiguration()->getAssetFiles(\AssetsBundle\AssetFile\AssetFile::ASSET_JS) as $oAssetFile) { $sAssetFileContent = $oJsFileFilter ? $oJsFileFilter->filterAssetFile($oAssetFile) : $oAssetFile->getAssetFileContents(); $oTmpAssetFile->setAssetFileContents($sAssetFileContent . PHP_EOL); } return array($this->getAssetFilesCacheManager()->cacheAssetFile($oTmpAssetFile)); } else { //Retrieve asset files cache manager $oAssetFilesCacheManager = $this->getAssetFilesCacheManager(); $aAssetFiles = array(); foreach ($this->getAssetFilesConfiguration()->getAssetFiles(\AssetsBundle\AssetFile\AssetFile::ASSET_JS) as $oAssetFile) { //Cache asset file $aAssetFiles[] = $oAssetFilesCacheManager->cacheAssetFile($oAssetFile); } return $aAssetFiles; } }
/** * @param string $sAssetFileType * @return \AssetsBundle\AssetFile\AssetFile * @throws \InvalidArgumentException */ protected function createTmpAssetFile($sAssetFileType) { if (!\AssetsBundle\AssetFile\AssetFile::assetFileTypeExists($sAssetFileType)) { throw new \InvalidArgumentException('Asset file type "' . $sAssetFileType . '" is not valid'); } // Create tmp asset file \Zend\Stdlib\ErrorHandler::start(); $sTmpAssetFilePath = tempnam($this->getOptions()->getTmpDirPath(), $sAssetFileType . '_' . uniqid()); \Zend\Stdlib\ErrorHandler::stop(true); $this->tmpAssetFilesPathes[] = $sTmpAssetFilePath; return new \AssetsBundle\AssetFile\AssetFile(array('asset_file_type' => $sAssetFileType, 'asset_file_path' => $sTmpAssetFilePath)); }
/** * @param \AssetsBundle\AssetFile\AssetFile $oAssetFile * @param scalar $iLastModifiedTime * @return string */ public function getAssetFileBaseUrl(\AssetsBundle\AssetFile\AssetFile $oAssetFile, $iLastModifiedTime = null) { if ($oAssetFile->isAssetFilePathUrl()) { return $oAssetFile->getAssetFilePath(); } $sAssetPath = str_replace(array($this->getCachePath(), DIRECTORY_SEPARATOR), array('', '/'), $oAssetFile->getAssetFilePath()); if ($oAssetFile->getAssetFileType() === \AssetsBundle\AssetFile\AssetFile::ASSET_MEDIA) { return $this->getCacheUrl() . ltrim($sAssetPath, '/'); } if ($iLastModifiedTime === null) { $iLastModifiedTime = $oAssetFile->getAssetFileLastModified(); } return $this->getCacheUrl() . ltrim($sAssetPath, '/') . ($iLastModifiedTime ? (strpos($sAssetPath, '?') === false ? '?' : '&') . $iLastModifiedTime : ''); }
/** * @param \AssetsBundle\AssetFile\AssetFile $oAssetFile * @return string */ public function sanitizeAssetFilePath(\AssetsBundle\AssetFile\AssetFile $oAssetFile) { return $oAssetFile->isAssetFilePathUrl() ? str_replace(array_merge(array('/'), $this->unwantedFilePathChars), '_', implode('/', array_slice(explode('/', preg_replace('/http:\\/\\/|https:\\/\\/|www./', '', $oAssetFile->getAssetFilePath())), 0, 1))) : $oAssetFile->getAssetFilePath(); }
/** * Check if assets configuration is the same as last saved configuration * * @param array $aAssetsType * @return boolean * @throws \RuntimeException * @throws \LogicException */ public function assetsConfigurationHasChanged(array $aAssetsType = null) { $aAssetsType = $aAssetsType ? array_unique($aAssetsType) : array(\AssetsBundle\AssetFile\AssetFile::ASSET_CSS, \AssetsBundle\AssetFile\AssetFile::ASSET_LESS, \AssetsBundle\AssetFile\AssetFile::ASSET_JS, \AssetsBundle\AssetFile\AssetFile::ASSET_MEDIA); //Retrieve saved onfiguration file if (file_exists($sConfigFilePath = $this->getConfigurationFilePath())) { \Zend\Stdlib\ErrorHandler::start(); $aConfig = (include $sConfigFilePath); \Zend\Stdlib\ErrorHandler::stop(true); if ($aConfig === false || !is_array($aConfig)) { throw new \RuntimeException('Unable to get file content from file "' . $sConfigFilePath . '"'); } //Get assets configuration $aAssets = $this->getOptions()->getAssets(); //Check if configuration has changed for each type of asset foreach ($aAssetsType as $sAssetType) { if (!\AssetsBundle\AssetFile\AssetFile::assetFileTypeExists($sAssetType)) { throw new \LogicException('Asset type "' . $sAssetType . '" does not exist'); } if (empty($aAssets[$sAssetType]) && !empty($aConfig[$sAssetType])) { return true; } elseif (!empty($aAssets[$sAssetType])) { if (empty($aConfig[$sAssetType])) { return true; } elseif (array_diff($aAssets[$sAssetType], $aConfig[$sAssetType]) || array_diff($aConfig[$sAssetType], $aAssets[$sAssetType])) { return true; } } } return false; } return true; }
/** * @param \AssetsBundle\AssetFile\AssetFile $oAssetFile * @return string */ public function getCachedFilteredContentFilePath(\AssetsBundle\AssetFile\AssetFile $oAssetFile) { return $this->getAssetFileFilterProcessedDirPath() . DIRECTORY_SEPARATOR . md5($sAssetFilePath = $oAssetFile->getAssetFilePath()); }
/** * @param \AssetsBundle\AssetFile\AssetFile $oAssetFile * @param \AssetsBundle\AssetFile\AssetFile $oSourceAssetFile * @return \AssetsBundle\AssetFile\AssetFile * @throws \LogicException */ public function cacheAssetFile(\AssetsBundle\AssetFile\AssetFile $oAssetFile, \AssetsBundle\AssetFile\AssetFile $oSourceAssetFile = null) { // Define source asset file if (!$oSourceAssetFile) { $oSourceAssetFile = $oAssetFile; } // Check that file need to be cached if ($this->isAssetFileCached($oSourceAssetFile)) { return $oAssetFile->setAssetFilePath($this->getAssetFileCachePath($oSourceAssetFile)); } // Retrieve asset file cache path $sCacheFilePath = $this->getAssetFileCachePath($oSourceAssetFile); // Retrieve cache file directory path $sCacheFileDirPath = dirname($sCacheFilePath); if ($sCacheFileDirPath === '.') { throw new \LogicException('Asset file cache path "' . $sCacheFilePath . '" does not provide a paretn directory'); } // Create directory if not exists if (!is_dir($sCacheFileDirPath)) { \Zend\Stdlib\ErrorHandler::start(); if (!mkdir($sCacheFileDirPath, 0775, true)) { throw new \RuntimeException('Error occured while creating directory "' . $sCacheFileDirPath . '"'); } if ($oException = \Zend\Stdlib\ErrorHandler::stop()) { throw new \RuntimeException('Error occured while creating directory "' . $sCacheFileDirPath . '"', $oException->getCode(), $oException); } } elseif (!is_writable($sCacheFileDirPath)) { \Zend\Stdlib\ErrorHandler::start(); if (!chmod($sCacheFileDirPath, 0775)) { throw new \RuntimeException('Error occured while changing mode on directory "' . $sCacheFileDirPath . '"'); } \Zend\Stdlib\ErrorHandler::stop(true); } // Cache remote asset file if ($oAssetFile->isAssetFilePathUrl()) { \Zend\Stdlib\ErrorHandler::start(); $oAssetFileFileHandle = fopen($oAssetFile->getAssetFilePath(), 'rb'); \Zend\Stdlib\ErrorHandler::stop(true); if (!$oAssetFileFileHandle) { throw new \LogicException('Unable to open asset file "' . $oAssetFile->getAssetFilePath() . '"'); } \Zend\Stdlib\ErrorHandler::start(); file_put_contents($sCacheFilePath, stream_get_contents($oAssetFileFileHandle)); \Zend\Stdlib\ErrorHandler::stop(true); \Zend\Stdlib\ErrorHandler::start(); fclose($oAssetFileFileHandle); \Zend\Stdlib\ErrorHandler::stop(true); } else { \Zend\Stdlib\ErrorHandler::start(); $sAssetFilePath = $oAssetFile->getAssetFilePath(); if (!is_file($sAssetFilePath)) { throw new \LogicException('Asset file "' . $sAssetFilePath . '" does not exits'); } copy($sAssetFilePath, $sCacheFilePath); \Zend\Stdlib\ErrorHandler::stop(true); } return $oAssetFile->setAssetFilePath($sCacheFilePath); }