/bitrix/modules/main/classes/general/cache_files_cleaner.php
https://gitlab.com/neuser/bitrix-core · PHP · 324 lines · 286 code · 26 blank · 12 comment · 42 complexity · 521f2e52c36ea68c068db79943c31b93 MD5 · raw file
- <?
- class CFileCacheCleaner
- {
- private $_CacheType;
- private $_arPath;
- private $_CurrentBase;
- private $_CurrentPath;
- private $_obFileTree;
- function __construct($CacheType)
- {
- global $DB;
- $this->_CacheType = $CacheType;
- switch($this->_CacheType)
- {
- case "menu":
- $this->_arPath = array(
- BX_PERSONAL_ROOT.'/managed_cache/'.$DB->type.'/menu/',
- );
- break;
- case "managed":
- $this->_arPath = array(
- BX_PERSONAL_ROOT.'/managed_cache/',
- BX_PERSONAL_ROOT.'/stack_cache/',
- );
- break;
- case "html":
- $this->_arPath = array(
- BX_PERSONAL_ROOT.'/html_pages/',
- );
- break;
- case "expired":
- $this->_arPath = array(
- BX_PERSONAL_ROOT.'/cache/',
- BX_PERSONAL_ROOT.'/managed_cache/',
- BX_PERSONAL_ROOT.'/stack_cache/',
- );
- break;
- default:
- $this->_arPath = array(
- BX_PERSONAL_ROOT.'/cache/',
- BX_PERSONAL_ROOT.'/managed_cache/',
- BX_PERSONAL_ROOT.'/stack_cache/',
- BX_PERSONAL_ROOT.'/html_pages/',
- );
- break;
- }
- }
- function InitPath($PathToCheck)
- {
- if($PathToCheck <> '')
- {
- $PathToCheck = preg_replace("#[\\\\\\/]+#", "/", "/".$PathToCheck);
- //Check if path does not contain any injection
- if(preg_match('#/\\.\\.#', $PathToCheck) || preg_match('#\\.\\./#', $PathToCheck))
- return false;
- $base = "";
- foreach($this->_arPath as $path)
- {
- if(preg_match('#^'.$path.'#', $PathToCheck))
- {
- $base = $path;
- break;
- }
- }
- if($base <> '')
- {
- $this->_CurrentBase = $base;
- $this->_CurrentPath = mb_substr($PathToCheck, mb_strlen($base));
- return true;
- }
- else
- {
- return false;
- }
- }
- else
- {
- $this->_CurrentBase = $this->_arPath[0];
- $this->_CurrentPath = "";
- return true;
- }
- }
- function Start()
- {
- if($this->_CurrentBase)
- {
- $this->_obFileTree = new _CFileTree($_SERVER["DOCUMENT_ROOT"].$this->_CurrentBase);
- $this->_obFileTree->Start($this->_CurrentPath);
- }
- }
- function GetNextFile()
- {
- if(is_object($this->_obFileTree))
- {
- $file = $this->_obFileTree->GetNextFile();
- //Check if current cache subdirectory cleaned
- if($file === false)
- {
- //Skip all checked bases
- $arPath = $this->_arPath;
- while(count($arPath) > 0)
- {
- $CurBase = array_shift($arPath);
- if($CurBase == $this->_CurrentBase)
- break;
- }
- //There is at least one cache directory not checked yet
- //so try to find a file inside
- while(count($arPath) > 0)
- {
- $this->_CurrentBase = array_shift($arPath);
- $this->_CurrentPath = "";
- $this->_obFileTree = new _CFileTree($_SERVER["DOCUMENT_ROOT"].$this->_CurrentBase);
- $this->_obFileTree->Start($this->_CurrentPath);
- $file = $this->_obFileTree->GetNextFile();
- if($file !== false)
- return $file;
- }
- return false;
- }
- return $file;
- }
- else
- {
- return false;
- }
- }
- function GetFileExpiration($FileName)
- {
- if(preg_match('#^'.$_SERVER["DOCUMENT_ROOT"].BX_PERSONAL_ROOT.'/html_pages/.*\\.html$#', $FileName))
- {
- return 1;//like an very old file
- }
- elseif(preg_match('#\\.~\\d+/#', $FileName)) //delayed delete files
- {
- return 1;//like an very old file
- }
- elseif(mb_substr($FileName, -4) == ".php")
- {
- $fd = fopen($FileName, "rb");
- if($fd)
- {
- $header = fread($fd, 150);
- fclose($fd);
- if(preg_match("/dateexpire\s*=\s*'([\d]+)'/im", $header, $match))
- return doubleval($match[1]);
- }
- }
- elseif(mb_substr($FileName, -5) == ".html")
- {
- $fd = fopen($FileName, "rb");
- if($fd)
- {
- $header = fread($fd, 26);
- fclose($fd);
- if(mb_substr($header, 0, 2) == "BX")
- return doubleval(mb_substr($header, 14, 12));
- }
- }
- return false;
- }
- }
- class _CFileTree
- {
- var $_in_path = '/';
- var $_path = '';
- var $_dir = false;
- function __construct($in_path="/")
- {
- $this->_in_path = preg_replace("#[\\\\\\/]+#", "/", $in_path);
- }
- function Start($path="/")
- {
- $this->_path = preg_replace("#[\\\\\\/]+#", "/", $this->_in_path.trim($path, "/"));
- if(!$this->FileExists($this->_path) || is_file($this->_path))
- {
- $last = self::ExtractFileFromPath($this->_path);
- $this->_dir = $this->ReadDir($this->_path);
- if(is_array($this->_dir))
- {
- while(count($this->_dir))
- {
- if(strcmp($this->_dir[0], $last) > 0)
- break;
- array_shift($this->_dir);
- }
- }
- }
- }
- function FileExists($file)
- {
- if(function_exists('accelerator_reset'))
- {
- if(is_dir($file))
- return true;
- $fd = @fopen($file, "rb");
- if($fd)
- {
- fclose($fd);
- return true;
- }
- else
- {
- return false;
- }
- }
- else
- {
- return file_exists($file);
- }
- }
- function GetNextFile()
- {
- if(!is_array($this->_dir))
- {
- $this->_dir = $this->ReadDir($this->_path);
- if(!is_array($this->_dir))
- return false;
- }
- $next = current($this->_dir);
- next($this->_dir);
- if($next === false)
- {
- //try to go up dir tree
- if($this->GoUp())
- return $this->GetNextFile();
- else
- return false;
- }
- elseif(is_file($next))
- {
- //it's our target
- return $next;
- }
- else
- {
- //it's dir or link try to go deeper
- $this->_path = $next;
- $this->_dir = false;
- return true;
- }
- }
- public static function ExtractFileFromPath(&$path)
- {
- $arPath = explode("/", $path);
- $last = array_pop($arPath);
- $path = implode("/", $arPath);
- return $path."/".$last;
- }
- function GoUp()
- {
- $last_dir = self::ExtractFileFromPath($this->_path);
- //We are not going to go up any more
- if(mb_strlen($this->_path."/") < mb_strlen($this->_in_path))
- return false;
- $this->_dir = $this->ReadDir($this->_path);
- //This should't be happen so try to goup one more level
- if(!is_array($this->_dir))
- return $this->GoUp();
- //Skip all dirs till current
- while(count($this->_dir))
- {
- if(strcmp($this->_dir[0], $last_dir) > 0)
- break;
- array_shift($this->_dir);
- }
- if(count($this->_dir))
- return true; //there is more work to do
- else
- return $this->GoUp(); // try to go upper
- }
- function ReadDir($dir)
- {
- $dir = rtrim($dir, "/");
- if(is_dir($dir))
- {
- $dh = opendir($dir);
- if($dh)
- {
- $result = array();
- while(($f = readdir($dh)) !== false)
- {
- if($f == "." || $f == "..")
- continue;
- $result[] = $dir."/".$f;
- }
- closedir($dh);
- sort($result);
- //try to delete an empty directory
- if(count($result) == 0)
- @rmdir($dir);
- return $result;
- }
- }
- return false;
- }
- }
- ?>