Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
Total | |
0.00% |
0 / 1 |
|
22.22% |
2 / 9 |
CRAP | |
69.44% |
50 / 72 |
AbstractAssetFileFilter | |
0.00% |
0 / 1 |
|
22.22% |
2 / 9 |
47.80 | |
69.44% |
50 / 72 |
filterAssetFile | |
0.00% |
0 / 1 |
3.03 | |
85.71% |
12 / 14 |
|||
filterContent | n/a |
0 / 0 |
1 | n/a |
0 / 0 |
|||||
setAssetFileFilterName | |
0.00% |
0 / 1 |
12.00 | |
0.00% |
0 / 6 |
|||
getAssetFileFilterName | |
0.00% |
0 / 1 |
3.33 | |
66.67% |
2 / 3 |
|||
setOptions | |
100.00% |
1 / 1 |
1 | |
100.00% |
2 / 2 |
|||
getOptions | |
0.00% |
0 / 1 |
6.28 | |
28.57% |
2 / 7 |
|||
getCachedFilteredContentFilePath | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
getCachedFilteredContent | |
0.00% |
0 / 1 |
6.47 | |
76.47% |
13 / 17 |
|||
cacheFilteredAssetFileContent | |
0.00% |
0 / 1 |
3.01 | |
91.67% |
11 / 12 |
|||
getAssetFileFilterProcessedDirPath | |
0.00% |
0 / 1 |
3.24 | |
70.00% |
7 / 10 |
<?php | |
namespace AssetsBundle\AssetFile\AssetFileFilter; | |
abstract class AbstractAssetFileFilter extends \Zend\Stdlib\AbstractOptions implements \AssetsBundle\AssetFile\AssetFileFilter\AssetFileFilterInterface | |
{ | |
/** | |
* @var string | |
*/ | |
const EXEC_TIME_PER_CHAR = 7E-5; | |
/** | |
* @var string | |
*/ | |
protected $assetFileFilterName; | |
/** | |
* @var \AssetsBundle\Service\ServiceOptions | |
*/ | |
protected $options; | |
/** | |
* @var string | |
*/ | |
protected $assetFileFilterProcessedDirPath; | |
/** | |
* @param \AssetsBundle\AssetFile\AssetFile $oAssetFile | |
* @throws \LogicException | |
* @throws \InvalidArgumentException | |
* @throws \RuntimeException | |
* @return string | |
*/ | |
public function filterAssetFile(\AssetsBundle\AssetFile\AssetFile $oAssetFile) : string | |
{ | |
// Try to retrieve cached filter rendering | |
if ($sCachedFilterRendering = $this->getCachedFilteredContent($oAssetFile)) { | |
return $sCachedFilterRendering; | |
} | |
$iExecTime = strlen($sContent = $oAssetFile->getAssetFileContents()) * self::EXEC_TIME_PER_CHAR; | |
$iMaxExecutionTime = ini_get('max_execution_time'); | |
set_time_limit(0); | |
try { | |
\Zend\Stdlib\ErrorHandler::start(\E_ALL); | |
$sFilteredContent = $this->filterContent($sContent, $oAssetFile->getAssetFilePath()); | |
\Zend\Stdlib\ErrorHandler::stop(true); | |
} catch (\Throwable $oException) { | |
throw new \RuntimeException('An error occured while running filter "'.$this->getAssetFileFilterName().'" on file\'s content "'.$oAssetFile->getAssetFilePath().'"', $oException->getCode(), $oException); | |
} | |
$sFilteredContent = trim($sFilteredContent); | |
$this->cacheFilteredAssetFileContent($oAssetFile, $sFilteredContent); | |
set_time_limit($iMaxExecutionTime); | |
return $sFilteredContent; | |
} | |
/** | |
* @param string $sContent | |
* @param string $sFilePath | |
* @return string | |
*/ | |
abstract protected function filterContent(string $sContent, string $sFilePath) : string; | |
/** | |
* @param string $sAssetFileFilterName | |
* @return \AssetsBundle\AssetFile\AssetFileFilter\AbstractAssetFileFilter | |
* @throws \InvalidArgumentException | |
*/ | |
public function setAssetFileFilterName(string $sAssetFileFilterName) : \AssetsBundle\AssetFile\AssetFileFilter\AbstractAssetFileFilter | |
{ | |
if (empty($sAssetFileFilterName)) { | |
throw new \InvalidArgumentException('Filter name is empty'); | |
} | |
if (!is_string($sAssetFileFilterName)) { | |
throw new \InvalidArgumentException('Filter name expects string, "' . gettype($sAssetFileFilterName) . '" given'); | |
} | |
$this->assetFileFilterName = $sAssetFileFilterName; | |
return $this; | |
} | |
/** | |
* @return string | |
* @throws \LogicException | |
*/ | |
public function getAssetFileFilterName() : string | |
{ | |
if (is_string($this->assetFileFilterName) && !empty($this->assetFileFilterName)) { | |
return $this->assetFileFilterName; | |
} | |
throw new \LogicException('Filter name is undefined'); | |
} | |
/** | |
* @param \AssetsBundle\Service\ServiceOptions $oOptions | |
* @return \AssetsBundle\AssetFile\AssetFileFilter\AssetFileFilterInterface | |
*/ | |
public function setOptions(\AssetsBundle\Service\ServiceOptions $oOptions) : \AssetsBundle\AssetFile\AssetFileFilter\AssetFileFilterInterface | |
{ | |
$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' | |
); | |
} | |
/** | |
* @param \AssetsBundle\AssetFile\AssetFile $oAssetFile | |
* @return string | |
*/ | |
public function getCachedFilteredContentFilePath(\AssetsBundle\AssetFile\AssetFile $oAssetFile) : string | |
{ | |
return $this->getAssetFileFilterProcessedDirPath() . DIRECTORY_SEPARATOR . md5($sAssetFilePath = $oAssetFile->getAssetFilePath()); | |
} | |
/** | |
* @param \AssetsBundle\AssetFile\AssetFile $oAssetFile | |
* @return bool|string | |
*/ | |
public function getCachedFilteredContent(\AssetsBundle\AssetFile\AssetFile $oAssetFile) | |
{ | |
$sCachedFilteredContentFilePath = $this->getCachedFilteredContentFilePath($oAssetFile); | |
if (!file_exists($sCachedFilteredContentFilePath)) { | |
return false; | |
} | |
$oFilteredAssetFile = new \AssetsBundle\AssetFile\AssetFile(array( | |
'assetFilePath' => $sCachedFilteredContentFilePath, | |
'assetFileType' => $oAssetFile->getAssetFileType() | |
)); | |
if (!$oAssetFile->assetFileExists()) { | |
return false; | |
} | |
// Retrieve cached filtered asset file last modified timestamp | |
$iFilteredAssetFileLastModified = $oFilteredAssetFile->getAssetFileLastModified(); | |
if (!$iFilteredAssetFileLastModified) { | |
return false; | |
} | |
// Retrieve asset file last modified timestamp | |
$iAssetFileLastModified = $oAssetFile->getAssetFileLastModified(); | |
if (!$iAssetFileLastModified) { | |
return false; | |
} | |
// If cached filtered asset file is outdated | |
if ($iFilteredAssetFileLastModified < $iAssetFileLastModified) { | |
return false; | |
} | |
return $oFilteredAssetFile->getAssetFileContents(); | |
} | |
/** | |
* @param \AssetsBundle\AssetFile\AssetFile $oAssetFile | |
* @param string $sFilteredContent | |
* @return \AssetsBundle\AssetFile\AssetFileFilter\AbstractAssetFileFilter | |
* @throws \InvalidArgumentException | |
*/ | |
public function cacheFilteredAssetFileContent(\AssetsBundle\AssetFile\AssetFile $oAssetFile, string $sFilteredContent) : \AssetsBundle\AssetFile\AssetFileFilter\AbstractAssetFileFilter | |
{ | |
if (is_string($sFilteredContent)) { | |
$sCachedFilteredContentFilePath = $this->getCachedFilteredContentFilePath($oAssetFile); | |
$bFileExists = file_exists($sCachedFilteredContentFilePath); | |
\Zend\Stdlib\ErrorHandler::start(\E_ALL); | |
file_put_contents($sCachedFilteredContentFilePath, $sFilteredContent); | |
\Zend\Stdlib\ErrorHandler::stop(true); | |
if (!$bFileExists) { | |
\Zend\Stdlib\ErrorHandler::start(\E_ALL); | |
chmod($sCachedFilteredContentFilePath, $this->getOptions()->getFilesPermissions()); | |
\Zend\Stdlib\ErrorHandler::stop(true); | |
} | |
return $this; | |
} | |
throw new \InvalidArgumentException('Filtered content expects string, "' . gettype($sFilteredContent) . '" given'); | |
} | |
/** | |
* @return string | |
*/ | |
public function getAssetFileFilterProcessedDirPath() : string | |
{ | |
if (!is_dir($this->assetFileFilterProcessedDirPath)) { | |
$this->assetFileFilterProcessedDirPath = $this->getOptions()->getProcessedDirPath() . DIRECTORY_SEPARATOR . strtolower(str_replace( | |
array('/', '<', '>', '?', '*', '"', '|'), | |
'_', | |
$this->getAssetFileFilterName() | |
)); | |
if (!is_dir($this->assetFileFilterProcessedDirPath)) { | |
\Zend\Stdlib\ErrorHandler::start(\E_ALL); | |
mkdir($this->assetFileFilterProcessedDirPath, $this->getOptions()->getDirectoriesPermissions()); | |
\Zend\Stdlib\ErrorHandler::stop(true); | |
} | |
} | |
return $this->assetFileFilterProcessedDirPath; | |
} | |
} |