123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301 |
- <?php
- // Copyright (c) 2010-2017 Combodo SARL
- //
- // This file is part of iTop.
- //
- // iTop is free software; you can redistribute it and/or modify
- // it under the terms of the GNU Affero General Public License as published by
- // the Free Software Foundation, either version 3 of the License, or
- // (at your option) any later version.
- //
- // iTop is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU Affero General Public License for more details.
- //
- // You should have received a copy of the GNU Affero General Public License
- // along with iTop. If not, see <http://www.gnu.org/licenses/>
- //
- /**
- * Date: 27/09/2017
- */
- /**
- * @param string $cache_type
- * @param bool $limited
- * @return array|bool
- */
- function apc_cache_info($cache_type = '', $limited = false)
- {
- $aInfo = array();
- $sRootCacheDir = apc_emul_get_cache_filename('');
- $aInfo['cache_list'] = apc_emul_get_cache_entries($sRootCacheDir);
- return $aInfo;
- }
- function apc_emul_get_cache_entries($sEntry)
- {
- $aResult = array();
- if (is_dir($sEntry))
- {
- $aFiles = array_diff(scandir($sEntry), array('.', '..'));
- foreach($aFiles as $sFile)
- {
- $sSubFile = $sEntry.'/'.$sFile;
- $aResult = array_merge($aResult, apc_emul_get_cache_entries($sSubFile));
- }
- }
- else
- {
- $sKey = basename($sEntry);
- if (strpos($sKey, '-') === 0)
- {
- $sKey = substr($sKey, 1);
- }
- $aResult[] = array('info' => $sKey);
- }
- return $aResult;
- }
- /**
- * @param array|string $key
- * @param $var
- * @param int $ttl
- * @return array|bool
- */
- function apc_store($key, $var = NULL, $ttl = 0)
- {
- if (is_array($key))
- {
- $aResult = array();
- foreach($key as $sKey => $value)
- {
- $aResult[] = apc_emul_store_unit($sKey, $value, $ttl);
- }
- return $aResult;
- }
- return apc_emul_store_unit($key, $var, $ttl);
- }
- /**
- * @param string $sKey
- * @param $value
- * @param int $iTTL time to live
- * @return bool
- */
- function apc_emul_store_unit($sKey, $value, $iTTL)
- {
- if ($iTTL > 0)
- {
- // hint for ttl management
- $sKey = '-'.$sKey;
- }
- $sFilename = apc_emul_get_cache_filename($sKey);
- // try to create the folder
- $sDirname = dirname($sFilename);
- if (!file_exists($sDirname))
- {
- if (!@mkdir($sDirname, 0755, true))
- {
- return false;
- }
- }
- $bRes = !(@file_put_contents($sFilename, serialize($value), LOCK_EX) === false);
- apc_emul_manage_new_entry($sFilename);
- return $bRes;
- }
- /**
- * @param $key string|array
- * @return mixed
- */
- function apc_fetch($key)
- {
- if (is_array($key))
- {
- $aResult = array();
- foreach($key as $sKey)
- {
- $aResult[$sKey] = apc_emul_fetch_unit($sKey);
- }
- return $aResult;
- }
- return apc_emul_fetch_unit($key);
- }
- /**
- * @param $sKey
- * @return bool|mixed
- */
- function apc_emul_fetch_unit($sKey)
- {
- // Try the 'TTLed' version
- $sValue = apc_emul_readcache_locked(apc_emul_get_cache_filename('-'.$sKey));
- if ($sValue === false)
- {
- $sValue = apc_emul_readcache_locked(apc_emul_get_cache_filename($sKey));
- if ($sValue === false)
- {
- return false;
- }
- }
- $oRes = @unserialize($sValue);
- return $oRes;
- }
- function apc_emul_readcache_locked($sFilename)
- {
- $file = @fopen($sFilename, 'r');
- if ($file === false)
- {
- return false;
- }
- flock($file, LOCK_SH);
- $sContent = @fread($file, @filesize($sFilename));
- flock($file, LOCK_UN);
- fclose($file);
- return $sContent;
- }
- /**
- * @param string $cache_type
- * @return bool
- */
- function apc_clear_cache($cache_type = '')
- {
- $sRootCacheDir = apc_emul_get_cache_filename('');
- apc_emul_delete_entry($sRootCacheDir);
- return true;
- }
- function apc_emul_delete_entry($sCache)
- {
- if (is_dir($sCache))
- {
- $aFiles = array_diff(scandir($sCache), array('.', '..'));
- foreach($aFiles as $sFile)
- {
- $sSubFile = $sCache.'/'.$sFile;
- if (!apc_emul_delete_entry($sSubFile))
- {
- return false;
- }
- }
- if (!@rmdir($sCache))
- {
- return false;
- }
- }
- else
- {
- if (!@unlink($sCache))
- {
- return false;
- }
- }
- return true;
- }
- /**
- * @param $key
- * @return bool|string[]
- */
- function apc_delete($key)
- {
- return apc_emul_delete_entry(apc_emul_get_cache_filename($key));
- }
- function apc_emul_get_cache_filename($sKey)
- {
- $sPath = str_replace(array(' ', '/', '\\', '.'), '-', $sKey);
- return utils::GetCachePath().'apc-emul/'.$sPath;
- }
- /** Manage the cache files when a new cache entry is added
- * @param string $sNewFilename new cache file added
- */
- function apc_emul_manage_new_entry($sNewFilename)
- {
- // Check only once per request
- static $aFilesByTime = null;
- static $iFileCount = 0;
- $iMaxFiles = MetaModel::GetConfig()->Get('apc_cache_emulation.max_entries');
- if ($iMaxFiles == 0)
- {
- return;
- }
- if (!$aFilesByTime)
- {
- $sRootCacheDir = apc_emul_get_cache_filename('');
- $aFilesByTime = apc_emul_list_files_time($sRootCacheDir);
- $iFileCount = count($aFilesByTime);
- if ($iMaxFiles !== 0)
- {
- asort($aFilesByTime);
- }
- }
- else
- {
- $aFilesByTime[$sNewFilename] = time();
- $iFileCount++;
- }
- if ($iFileCount > $iMaxFiles)
- {
- $iFileNbToRemove = $iFileCount - $iMaxFiles;
- foreach($aFilesByTime as $sFileToRemove => $iTime)
- {
- @unlink($sFileToRemove);
- if ($iFileNbToRemove-- === 0)
- {
- break;
- }
- }
- $aFilesByTime = array_slice($aFilesByTime, $iFileCount - $iMaxFiles, null, true);
- $iFileCount = $iMaxFiles;
- }
- }
- /** Get the list of files with their associated access time
- * @param string $sCheck Directory to scan
- * @param array $aFilesByTime used by recursion
- * @return array
- */
- function apc_emul_list_files_time($sCheck, &$aFilesByTime = array())
- {
- // Garbage collection
- $aFiles = array_diff(@scandir($sCheck), array('.', '..'));
- foreach($aFiles as $sFile)
- {
- $sSubFile = $sCheck.'/'.$sFile;
- if (is_dir($sSubFile))
- {
- apc_emul_list_files_time($sSubFile, $aFilesByTime);
- }
- else
- {
- $iTime = apc_emul_get_file_time($sSubFile);
- if ($iTime !== false)
- {
- $aFilesByTime[$sSubFile] = $iTime;
- }
- }
- }
- return $aFilesByTime;
- }
- /** Get the file access time if TTL is managed
- * @param string $sFilename
- * @return bool|int returns the file atime or false if not relevant
- */
- function apc_emul_get_file_time($sFilename)
- {
- if (strpos(basename($sFilename), '-') === 0)
- {
- return @fileatime($sFilename);
- }
- return false;
- }
|