Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
Total | |
0.00% |
0 / 1 |
|
33.33% |
4 / 12 |
CRAP | |
62.50% |
85 / 136 |
AssetFilesConfiguration | |
0.00% |
0 / 1 |
|
33.33% |
4 / 12 |
362.77 | |
62.50% |
85 / 136 |
getConfigurationKey | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
getAssetFiles | |
0.00% |
0 / 1 |
24.36 | |
91.43% |
32 / 35 |
|||
addAssetFile | |
100.00% |
1 / 1 |
1 | |
100.00% |
2 / 2 |
|||
addAssetFileFromOptions | |
0.00% |
0 / 1 |
5.51 | |
72.73% |
8 / 11 |
|||
getAssetFileFromFilePath | |
0.00% |
0 / 1 |
6.20 | |
63.64% |
7 / 11 |
|||
getAssetFilesPathFromDirectory | |
0.00% |
0 / 1 |
12.57 | |
84.21% |
16 / 19 |
|||
getAssetRelativePath | |
0.00% |
0 / 1 |
20.00 | |
0.00% |
0 / 12 |
|||
assetsConfigurationHasChanged | |
0.00% |
0 / 1 |
119.43 | |
14.29% |
3 / 21 |
|||
getConfigurationFilePath | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
saveAssetFilesConfiguration | |
0.00% |
0 / 1 |
4.16 | |
78.57% |
11 / 14 |
|||
setOptions | |
100.00% |
1 / 1 |
1 | |
100.00% |
2 / 2 |
|||
getOptions | |
0.00% |
0 / 1 |
6.28 | |
28.57% |
2 / 7 |
<?php | |
namespace AssetsBundle\AssetFile; | |
class AssetFilesConfiguration | |
{ | |
/** | |
* @var array | |
*/ | |
protected $assetFiles = array(); | |
/** | |
* @return string | |
*/ | |
public function getConfigurationKey() : string | |
{ | |
return $this->getOptions()->getModuleName() . '-' . $this->getOptions()->getControllerName() . '-' . $this->getOptions()->getActionName(); | |
} | |
/** | |
* @param string $sAssetFileType : (optionnal) | |
* @return array | |
* @throws \InvalidArgumentException | |
*/ | |
public function getAssetFiles($sAssetFileType = null) : array | |
{ | |
if ($sAssetFileType && !\AssetsBundle\AssetFile\AssetFile::assetFileTypeExists($sAssetFileType)) { | |
throw new \InvalidArgumentException('Asset file type "' . $sAssetFileType . '" is not valid'); | |
} | |
//Check if assets configuration is already set | |
$sConfigurationKey = $this->getConfigurationKey(); | |
if (isset($this->assetFiles[$sConfigurationKey])) { | |
if ($sAssetFileType) { | |
return $this->assetFiles[$sConfigurationKey][$sAssetFileType]; | |
} | |
return $this->assetFiles[$sConfigurationKey]; | |
} | |
//Define default assets | |
$aAssets = $this->assetFiles[$sConfigurationKey] = array_fill_keys( | |
\AssetsBundle\AssetFile\AssetFile::ALL_ASSET_TYPES, | |
array() | |
); | |
// Common configuration | |
$aCommonConfiguration = $this->getOptions()->getAssets(); | |
foreach (\AssetsBundle\AssetFile\AssetFile::ALL_ASSET_TYPES as $sAssetType) { | |
if (!empty($aCommonConfiguration[$sAssetType]) && is_array($aCommonConfiguration[$sAssetType])) { | |
$aAssets[$sAssetType] = array_merge($aAssets[$sAssetType], $aCommonConfiguration[$sAssetType]); | |
} | |
} | |
// Module configuration | |
if (isset($aCommonConfiguration[$sModuleName = $this->getOptions()->getModuleName()])) { | |
$aModuleConfiguration = $aCommonConfiguration[$sModuleName]; | |
foreach (\AssetsBundle\AssetFile\AssetFile::ALL_ASSET_TYPES as $sAssetType) { | |
if (!empty($aModuleConfiguration[$sAssetType]) && is_array($aModuleConfiguration[$sAssetType])) { | |
$aAssets[$sAssetType] = array_merge($aAssets[$sAssetType], $aModuleConfiguration[$sAssetType]); | |
} | |
} | |
// Controller configuration | |
if (isset($aModuleConfiguration[$sControllerName = $this->getOptions()->getControllerName()])) { | |
$aControllerConfiguration = $aModuleConfiguration[$sControllerName]; | |
foreach (\AssetsBundle\AssetFile\AssetFile::ALL_ASSET_TYPES as $sAssetType) { | |
if (!empty($aControllerConfiguration[$sAssetType]) && is_array($aControllerConfiguration[$sAssetType])) { | |
$aAssets[$sAssetType] = array_merge($aAssets[$sAssetType], $aControllerConfiguration[$sAssetType]); | |
} | |
} | |
// Action configuration | |
if (isset($aControllerConfiguration[$sActionName = $this->getOptions()->getActionName()])) { | |
$aActionConfiguration = $aControllerConfiguration[$sActionName]; | |
foreach (\AssetsBundle\AssetFile\AssetFile::ALL_ASSET_TYPES as $sAssetType) { | |
if (!empty($aActionConfiguration[$sAssetType]) && is_array($aActionConfiguration[$sAssetType])) { | |
$aAssets[$sAssetType] = array_merge($aAssets[$sAssetType], $aActionConfiguration[$sAssetType]); | |
} | |
} | |
} | |
} | |
} | |
// bRetrieve asset files from configuration | |
foreach ($aAssets as $sAssetFileTypeKey => $aAssetFiles) { | |
foreach (array_unique($aAssetFiles) as $sAssetFilePath) { | |
$this->addAssetFileFromOptions(is_array($sAssetFilePath) ? array_merge(array('asset_file_type' => $sAssetFileTypeKey, $sAssetFilePath)) : array('asset_file_path' => $sAssetFilePath, 'asset_file_type' => $sAssetFileTypeKey)); | |
} | |
} | |
if ($sAssetFileType) { | |
return $this->assetFiles[$sConfigurationKey][$sAssetFileType]; | |
} | |
return $this->assetFiles[$sConfigurationKey]; | |
} | |
/** | |
* @param \AssetsBundle\AssetFile\AssetFile $oAssetFile | |
* @return \AssetsBundle\AssetFile\AssetFilesConfiguration | |
*/ | |
public function addAssetFile(\AssetsBundle\AssetFile\AssetFile $oAssetFile) : \AssetsBundle\AssetFile\AssetFilesConfiguration | |
{ | |
$this->assetFiles[$this->getConfigurationKey()][$oAssetFile->getAssetFileType()][$oAssetFile->getAssetFilePath()] = $oAssetFile; | |
return $this; | |
} | |
/** | |
* @param array $aAssetFileOptions | |
* @return \AssetsBundle\AssetFile\AssetFilesConfiguration | |
* @throws \InvalidArgumentException | |
*/ | |
public function addAssetFileFromOptions(array $aAssetFileOptions) : \AssetsBundle\AssetFile\AssetFilesConfiguration | |
{ | |
if (empty($aAssetFileOptions['asset_file_type'])) { | |
throw new \InvalidArgumentException('Asset file type is empty'); | |
} | |
// Initialize asset file | |
$oAssetFile = new \AssetsBundle\AssetFile\AssetFile(); | |
$oAssetFile->setAssetFileType($aAssetFileOptions['asset_file_type']); | |
unset($aAssetFileOptions['asset_file_type']); | |
// Retrieve asset file path | |
if (empty($aAssetFileOptions['asset_file_path'])) { | |
throw new \InvalidArgumentException('Asset file path is empty'); | |
} | |
if (!is_string($aAssetFileOptions['asset_file_path'])) { | |
throw new \InvalidArgumentException('Asset file path expects string, "' . gettype($aAssetFileOptions['asset_file_path']) . '" given'); | |
} | |
// Retrieve asset file realpath | |
$sAssetRealPath = $this->getOptions()->getRealPath($aAssetFileOptions['asset_file_path'])? : $aAssetFileOptions['asset_file_path']; | |
return $this->getAssetFileFromFilePath($oAssetFile, $sAssetRealPath); | |
} | |
/** | |
* @param \AssetsBundle\AssetFile\AssetFile $oAssetFile | |
* @param string $sAssetRealPath | |
* @return \AssetsBundle\AssetFile\AssetFilesConfiguration | |
*/ | |
public function getAssetFileFromFilePath(\AssetsBundle\AssetFile\AssetFile $oAssetFile, string $sAssetRealPath) : \AssetsBundle\AssetFile\AssetFilesConfiguration | |
{ | |
if (is_dir($sAssetRealPath)) { | |
foreach ($this->getAssetFilesPathFromDirectory($sAssetRealPath, $oAssetFile->getAssetFileType()) as $sChildAssetRealPath) { | |
$this->getAssetFileFromFilePath($oAssetFile, $sChildAssetRealPath); | |
} | |
return $this; | |
} | |
// Handle path with wildcard | |
elseif (strpos($sAssetRealPath, '*') !== false) { | |
$oGlobIterator = new \GlobIterator($sAssetRealPath); | |
foreach ($oGlobIterator as $oItem) { | |
$this->getAssetFileFromFilePath($oAssetFile, $oItem->getRealPath()); | |
} | |
return $this; | |
} | |
$oNewAssetFile = clone $oAssetFile; | |
return $this->addAssetFile($oNewAssetFile->setAssetFilePath($sAssetRealPath)); | |
} | |
/** | |
* Retrieve assets from a directory | |
* | |
* @param string $sDirPath | |
* @param string $sAssetType | |
* @throws \InvalidArgumentException | |
* @return array | |
*/ | |
protected function getAssetFilesPathFromDirectory(string $sDirPath, string $sAssetType) : array | |
{ | |
if (!is_string($sDirPath) || !($sDirPath = $this->getOptions()->getRealPath($sDirPath)) && !is_dir($sDirPath)) { | |
throw new \InvalidArgumentException('Directory not found : ' . $sDirPath); | |
} | |
if (!\AssetsBundle\AssetFile\AssetFile::assetFileTypeExists($sAssetType)) { | |
throw new \InvalidArgumentException('Asset\'s type is undefined : ' . $sAssetType); | |
} | |
$oDirIterator = new \DirectoryIterator($sDirPath); | |
$aAssets = array(); | |
$bRecursiveSearch = $this->getOptions()->allowsRecursiveSearch(); | |
// Defined expected extensions for the given type | |
if ($sAssetType === \AssetsBundle\AssetFile\AssetFile::ASSET_MEDIA) { | |
$aExpectedExtensions = $this->getOptions()->getMediaExt(); | |
} else { | |
$aExpectedExtensions = array(\AssetsBundle\AssetFile\AssetFile::getAssetFileDefaultExtension($sAssetType)); | |
} | |
foreach ($oDirIterator as $oFile) { | |
if ($oFile->isFile()) { | |
if (in_array(strtolower(pathinfo($oFile->getFilename(), PATHINFO_EXTENSION)), $aExpectedExtensions, true)) { | |
$aAssets[] = $oFile->getPathname(); | |
} | |
} elseif ($oFile->isDir() && !$oFile->isDot() && $bRecursiveSearch) { | |
$aAssets = array_merge( | |
$aAssets, | |
$this->getAssetFilesPathFromDirectory($oFile->getPathname(), $sAssetType) | |
); | |
} | |
} | |
return $aAssets; | |
} | |
/** | |
* Retrieve asset relative path | |
* | |
* @param string $sAssetPath | |
* @throws \InvalidArgumentException | |
* @return string | |
*/ | |
public function getAssetRelativePath(string $sAssetPath) : string | |
{ | |
if (!($sAssetRealPath = $this->getOptions()->getRealPath($sAssetPath))) { | |
throw new \InvalidArgumentException('File "' . $sAssetPath . '" does not exist'); | |
} | |
// If asset is already a cache file | |
$sCachePath = $this->getOptions()->getCachePath(); | |
return strpos($sAssetRealPath, $sCachePath) !== false ? str_ireplace( | |
array($sCachePath, '.less'), | |
array('', '.css'), | |
$sAssetRealPath | |
) : ( | |
$this->getOptions()->hasAssetsPath() ? str_ireplace( | |
array($this->getOptions()->getAssetsPath(), getcwd(), DIRECTORY_SEPARATOR), | |
array('', '', '_'), | |
$sAssetRealPath | |
) : str_ireplace( | |
array(getcwd(), DIRECTORY_SEPARATOR), | |
array('', '_'), | |
$sAssetRealPath | |
) | |
); | |
} | |
/** | |
* Check if assets configuration is the same as last saved configuration | |
* | |
* @param array $aAssetsType | |
* @return bool | |
* @throws \RuntimeException | |
* @throws \LogicException | |
*/ | |
public function assetsConfigurationHasChanged(array $aAssetsType = null) : bool | |
{ | |
$aAssetsType = $aAssetsType ? array_unique($aAssetsType) : \AssetsBundle\AssetFile\AssetFile::ALL_ASSET_TYPES; | |
// Retrieve saved onfiguration file | |
if (file_exists($sConfigFilePath = $this->getConfigurationFilePath())) { | |
\Zend\Stdlib\ErrorHandler::start(\E_ALL); | |
$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; | |
} | |
if (!empty($aAssets[$sAssetType])) { | |
if (empty($aConfig[$sAssetType])) { | |
return true; | |
} | |
if ( | |
array_diff($aAssets[$sAssetType], $aConfig[$sAssetType]) | |
|| array_diff($aConfig[$sAssetType], $aAssets[$sAssetType]) | |
) { | |
return true; | |
} | |
} | |
} | |
return false; | |
} | |
return true; | |
} | |
/** | |
* Retrieve configuration file name for the current request | |
* | |
* @return string | |
*/ | |
public function getConfigurationFilePath() : string | |
{ | |
return $this->getOptions()->getProcessedDirPath() . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . $this->getOptions()->getCacheFileName() . '.conf'; | |
} | |
/** | |
* Save current asset configuration into conf file | |
* | |
* @return \AssetsBundle\AssetFile\AssetFilesConfiguration | |
*/ | |
public function saveAssetFilesConfiguration() : \AssetsBundle\AssetFile\AssetFilesConfiguration | |
{ | |
// Retrieve configuration file path | |
$sConfigurationFilePath = $this->getConfigurationFilePath(); | |
$bFileExists = file_exists($sConfigurationFilePath); | |
// Create dir if needed | |
if (!($bFileExists = file_exists($sConfigurationFilePath)) && !is_dir($sConfigurationFileDirPath = dirname($sConfigurationFilePath))) { | |
\Zend\Stdlib\ErrorHandler::start(\E_ALL); | |
mkdir($sConfigurationFileDirPath, $this->getOptions()->getDirectoriesPermissions()); | |
\Zend\Stdlib\ErrorHandler::stop(true); | |
} | |
\Zend\Stdlib\ErrorHandler::start(\E_ALL); | |
file_put_contents($sConfigurationFilePath, '<?php' . PHP_EOL . 'return ' . var_export($this->getOptions()->getAssets(), 1) . ';'); | |
\Zend\Stdlib\ErrorHandler::stop(true); | |
if (!$bFileExists) { | |
\Zend\Stdlib\ErrorHandler::start(\E_ALL); | |
chmod($sConfigurationFilePath, $this->getOptions()->getFilesPermissions()); | |
\Zend\Stdlib\ErrorHandler::stop(true); | |
} | |
return $this; | |
} | |
/** | |
* @param \AssetsBundle\Service\ServiceOptions $oOptions | |
* @return \AssetsBundle\AssetFile\AssetFilesConfiguration | |
*/ | |
public function setOptions(\AssetsBundle\Service\ServiceOptions $oOptions) : \AssetsBundle\AssetFile\AssetFilesConfiguration | |
{ | |
$this->options = $oOptions; | |
return $this; | |
} | |
/** | |
* @return \AssetsBundle\Service\ServiceOptions | |
* @throws \LogicException | |
*/ | |
public function getOptions() : \AssetsBundle\Service\ServiceOptions | |
{ | |
if ($this->options instanceof \AssetsBundle\Service\ServiceOptions) { | |
return $this->options; | |
} | |
throw new \LogicException( | |
'Property "options" expects an instance of "\AssetsBundle\Service\ServiceOptions", "'.( | |
is_object($this->options) | |
? get_class($this->options) | |
: gettype($this->options) | |
).'" defined' | |
); | |
} | |
} |