Update Provider.php

This commit is contained in:
Anton 2020-04-12 07:39:43 +03:00 committed by GitHub
parent 8e2d64f4a6
commit f928710ba9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 110 additions and 92 deletions

View File

@ -9,178 +9,196 @@
*/ */
namespace Fenom; namespace Fenom;
use InvalidArgumentException;
use RecursiveIteratorIterator;
use RecursiveDirectoryIterator;
/** /**
* Base template provider * Base template provider.
*
* @author Ivan Shalganov * @author Ivan Shalganov
*/ */
class Provider implements ProviderInterface class Provider implements ProviderInterface
{ {
private $_path; /**
* @var string template directory
protected $_clear_cache = false; */
protected $path;
/**
* @var string template extension
*/
protected $extension = 'tpl';
/** /**
* Clean directory from files * @var bool
*/
protected $clear_cache = false;
/**
* Cleans directory from files and sub directories.
* *
* @param string $path * @param string $path
* @return void
*/ */
public static function clean($path) public static function clean($path)
{ {
if (is_file($path)) { if (is_file($path)) {
unlink($path); unlink($path);
} elseif (is_dir($path)) { } else {
$iterator = iterator_to_array( $iterator = new RecursiveIteratorIterator(
new \RecursiveIteratorIterator( new RecursiveDirectoryIterator(
new \RecursiveDirectoryIterator($path, $path,
\FilesystemIterator::KEY_AS_PATHNAME | \FilesystemIterator::CURRENT_AS_FILEINFO | \FilesystemIterator::SKIP_DOTS), RecursiveDirectoryIterator::CURRENT_AS_FILEINFO | RecursiveDirectoryIterator::SKIP_DOTS
\RecursiveIteratorIterator::CHILD_FIRST ),
) RecursiveIteratorIterator::CHILD_FIRST
); );
foreach ($iterator as $file) { /* @var \SplFileInfo $info */
/* @var \splFileInfo $file */ foreach ($iterator as $info) {
if ($file->isFile()) { if ($info->isFile()) {
if (strpos($file->getBasename(), ".") !== 0) { unlink($info->getRealPath());
unlink($file->getRealPath()); } else {
} rmdir($info->getRealPath());
} elseif ($file->isDir()) {
rmdir($file->getRealPath());
} }
} }
} }
} }
/** /**
* Recursive remove directory * Removes directory or file.
* *
* @param string $path * @param string $path template directory
* @return void
*/ */
public static function rm($path) public static function rm($path)
{ {
self::clean($path); static::clean($path);
if (is_dir($path)) { if (is_dir($path)) {
rmdir($path); rmdir($path);
} }
} }
/** /**
* @param string $template_dir directory of templates * @param string $template_dir template directory
* @throws \LogicException if directory doesn't exists * @param string|null $extension template extension
* @throws InvalidArgumentException if directory doesn't exists
*/ */
public function __construct($template_dir) public function __construct($template_dir, $extension = null)
{ {
if ($_dir = realpath($template_dir)) { $path = realpath($template_dir)
$this->_path = $_dir; if (! $path) {
} else { throw new InvalidArgumentException("Template directory {$template_dir} doesn't exists");
throw new \LogicException("Template directory {$template_dir} doesn't exists");
} }
$this->path = $path . DIRECTORY_SEPARATOR;
if ($extension !== null) {
$this->extension = strtolower($extension);
}
} }
/**
* Get template path.
* @param string $tpl
* @param bool $throw
* @return string|null
* @throws InvalidArgumentException template not found
*/
protected function getTemplatePath($tpl, $throw = true)
{
$path = realpath($this->path . $tpl);
if ($throw && ! $path) {
throw new InvalidArgumentException("Template $tpl not found");
}
return $path;
}
/** /**
* Disable PHP cache for files. PHP cache some operations with files then script works. * Disable PHP cache for files. PHP cache some operations with files then script works.
* @see http://php.net/manual/en/function.clearstatcache.php * @link https://www.php.net/manual/en/function.clearstatcache.php
* @param bool $status * @param bool $status
* @return $this
*/ */
public function setClearCachedStats($status = true) { public function setClearCachedStats($status = true)
$this->_clear_cache = $status; {
$this->clear_cache = (bool) $status;
return $this;
} }
/** /**
* Get source and mtime of template by name * @inheritDoc
* @param string $tpl
* @param int $time load last modified time
* @return string
*/ */
public function getSource($tpl, &$time) public function getSource($tpl, &$time)
{ {
$tpl = $this->_getTemplatePath($tpl); $path = $this->getTemplatePath($tpl);
if($this->_clear_cache) { if ($this->clear_cache) {
clearstatcache(true, $tpl); clearstatcache(true, $path);
} }
$time = filemtime($tpl); $time = filemtime($path);
return file_get_contents($tpl); return file_get_contents($path);
} }
/** /**
* Get last modified of template by name * @inheritDoc
* @param string $tpl
* @return int
*/ */
public function getLastModified($tpl) public function getLastModified($tpl)
{ {
$tpl = $this->_getTemplatePath($tpl); $path = $this->getTemplatePath($tpl);
if($this->_clear_cache) { if ($this->clear_cache) {
clearstatcache(true, $tpl); clearstatcache(true, $path);
} }
return filemtime($tpl); return filemtime($path);
} }
/** /**
* Get all names of templates from provider. * {@inheritDoc}
* * @param string $extension deprecated, set extension in constructor
* @param string $extension all templates must have this extension, default .tpl
* @return array|\Iterator
*/ */
public function getList($extension = "tpl") public function getList($extension = null)
{ {
$list = array(); $list = array();
$iterator = new \RecursiveIteratorIterator( $path_len = strlen($this->path) + 1;
new \RecursiveDirectoryIterator($this->_path, $extension = $extension ? strtolower($extension) : $this->extension;
\FilesystemIterator::CURRENT_AS_FILEINFO | \FilesystemIterator::SKIP_DOTS), $iterator = new RecursiveIteratorIterator(
\RecursiveIteratorIterator::CHILD_FIRST new RecursiveDirectoryIterator(
$this->path,
RecursiveDirectoryIterator::CURRENT_AS_FILEINFO | RecursiveDirectoryIterator::SKIP_DOTS
)
); );
$path_len = strlen($this->_path); /* @var \SplFileInfo $info */
foreach ($iterator as $file) { foreach ($iterator as $info) {
/* @var \SplFileInfo $file */ if ($info->isFile() && strtolower($info->getExtension()) == $extension) {
if ($file->isFile() && $file->getExtension() == $extension) { $list[] = substr($info->getRealPath(), $path_len);
$list[] = substr($file->getPathname(), $path_len + 1);
} }
} }
return $list; return $list;
} }
/** /**
* Get template path * @inheritDoc
* @param $tpl
* @return string
* @throws \RuntimeException
*/
protected function _getTemplatePath($tpl)
{
$path = realpath($this->_path . "/" . $tpl);
if ($path && strpos($path, $this->_path) === 0) {
return $path;
} else {
throw new \RuntimeException("Template $tpl not found");
}
}
/**
* @param string $tpl
* @return bool
*/ */
public function templateExists($tpl) public function templateExists($tpl)
{ {
return ($path = realpath($this->_path . "/" . $tpl)) && strpos($path, $this->_path) === 0; return (bool) $this->getTemplatePath($tpl, false);
} }
/** /**
* Verify templates (check change time) * @inheritDoc
*
* @param array $templates [template_name => modified, ...] By conversation, you may trust the template's name
* @return bool
*/ */
public function verify(array $templates) public function verify(array $templates)
{ {
foreach ($templates as $template => $mtime) { foreach ($templates as $template => $mtime) {
$template = $this->_path . '/' . $template; $path = $this->getTemplatePath($template, false);
if($this->_clear_cache) { if (! $path) {
clearstatcache(true, $template); return false;
} }
if (@filemtime($template) !== $mtime) { if ($this->clear_cache) {
clearstatcache(true, $path);
}
if (filemtime($path) != $mtime) {
return false; return false;
} }
} }
return true; return true;
} }
} }