[ Mini Kiebo ]
Server: Windows NT DESKTOP-5B8S0D4 6.2 build 9200 (Windows 8 Professional Edition) i586
Path:
D:
/
Backup
/
05122024
/
htdocs
/
jurnal-kesmas
/
v1
/
lib
/
pkp
/
lib
/
vendor
/
elcobvg
/
laravel-opcache
/
src
/
[
Home
]
File: Store.php
<?php namespace ElcoBvg\Opcache; use Illuminate\Support\Str; use Illuminate\Cache\TagSet; use Illuminate\Cache\TaggableStore; use Illuminate\Support\Facades\Log; use Illuminate\Contracts\Cache\Store as StoreContract; use Illuminate\Cache\RetrievesMultipleKeys; class Store extends TaggableStore implements StoreContract { use RetrievesMultipleKeys; /** * The file cache directory. * * @var string */ protected $directory; /** * The file cache sub directory * * @var string|null */ protected $subDirectory; /** * String that should be prepended to keys. * * @var string */ protected $prefix; /** * Is OPcache enabled or not. * * @var boolean */ protected $enabled = false; /** * Create a new OPcache store. * * @param string $prefix * @param string $directory */ public function __construct(string $prefix = '', string $directory = '') { // Graceful degradation: if OPcache is not enabled, we're just loading cache files. if (extension_loaded('Zend OPcache')) { $this->enabled = true; } elseif (config('app.debug')) { Log::warning('You do not have the Zend OPcache extension loaded!'); } $this->prefix = Str::slug($prefix ?: config('app.name', 'opcache'), '-'); /* * In case if `OpCache` file path not being set we will use `file` driver path */ $this->directory = $directory ?: config('cache.stores.opcache.path', config('cache.stores.file.path')); } /** * Begin executing a new tags operation. * * @param array|mixed $names * @return \Illuminate\Cache\TaggedCache */ public function tags($names) { $names = is_array($names) ? $names : func_get_args(); /* * Now we are able to flush only tagged cache items */ if (! empty($names)) { $this->setSubDirectory($this->tagsSubDir($names)); } return new Repository($this, new TagSet($this, $names)); } /** * @param array $names * @return string */ protected function tagsSubDir(array $names) { return implode('_', $names); } /** * Determines whether the key exists within the cache. * * @param string $key * @return bool */ protected function exists($key) { if ($this->enabled && opcache_is_script_cached($this->filePath($key))) { return true; } return file_exists($this->filePath($key)); } /** * Retrieve an item from the cache by key. * * @param string $key * @return mixed */ public function get($key) { if ($this->exists($key)) { @include $this->filePath($key); } if (isset($exp) && $exp < time()) { /* * In order to free disc space and memory we need to * delete expired file from our disc and invalidate it from OpCache */ $this->forget($key); return null; } return isset($val) ? $val : null; } /** * Store an item in the cache for a given number of seconds. * * @param string $key * @param mixed $value * @param float|int $seconds * @return bool */ public function put($key, $value, $seconds = 0) { $val = var_export($value, true); // HHVM fails at __set_state, so just use object cast for now if (defined('HHVM_VERSION')) { $val = str_replace('stdClass::__set_state', '(object)', $val); } return $this->writeFile($key, $this->expiration($seconds), $val); } /** * Store an item in the cache if the key doesn't exist. * * @param string $key * @param mixed $value * @param float|int $seconds * @return bool */ public function add($key, $value, $seconds = 0) { if ($this->exists($key)) { return false; } return $this->put($key, $value, $seconds); } /** * Increment the value of an item in the cache. * * @param string $key * @param mixed $value * @return int|bool */ public function increment($key, $value = 1) { $val = (int) $this->get($key) + $value; return $this->put($key, $val) ? $val : false; } /** * Decrement the value of an item in the cache. * * @param string $key * @param mixed $value * @return int|bool */ public function decrement($key, $value = 1) { return $this->increment($key, $value * -1); } /** * Store an item in the cache indefinitely. * * @param string $key * @param mixed $value * @return bool */ public function forever($key, $value) { return $this->put($key, $value, 0); } /** * Remove an item from the cache. * * @param string $key * @return bool */ public function forget($key) { if ($this->enabled) { opcache_invalidate($this->filePath($key), true); } return @unlink($this->filePath($key)); } /** * Remove all items from the cache. * * @return bool */ public function flush() { return $this->clearCacheInDirectory($this->getDirectory()); } /** * @return bool */ public function flushSub() { return $this->clearCacheInDirectory($this->getFullDirectory(), true); } /** * @param $dir * @param bool $removeDirectory * @return bool */ public function clearCacheInDirectory($dir, $removeDirectory = false) { /* * Since we now able to set sub directory to keep files * in separated folders we will need to flush all files recursively */ $directory = new \RecursiveIteratorIterator( new \RecursiveDirectoryIterator($dir), \RecursiveIteratorIterator::CHILD_FIRST ); foreach ($directory as $filename => $file) { if ($file->isDir()) { @rmdir($filename); continue; } if ($this->enabled) { opcache_invalidate($filename, true); } @unlink($filename); } if ($removeDirectory) { return @rmdir($dir); } return true; } /** * Get the cache key prefix. * * @return string */ public function getPrefix() { return $this->prefix; } /** * Get fully qualified file path * * @param string $key * @return string */ public function filePath(string $key) { return $this->prefixPath() . '-' . sha1($key); } /** * Get directory path with prefix * * @return string */ public function prefixPath() { return $this->getFullDirectory() . DIRECTORY_SEPARATOR . $this->prefix; } /** * @return string */ public function getFullDirectory() { $dir = $this->getDirectory(); $subDir = $this->getSubDirectory(); if (is_string($subDir)) { return rtrim($dir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . ltrim($subDir, DIRECTORY_SEPARATOR); } return $dir; } /** * @return string */ public function getDirectory() { return $this->directory; } /** * @param $subDirectory * @return $this */ public function setSubDirectory($subDirectory) { $this->subDirectory = $subDirectory; return $this; } /** * @return null|string */ public function getSubDirectory() { return $this->subDirectory; } /** * Write the cache file to disk * * @param string $key * @param int $exp * @param mixed $val * @return bool */ protected function writeFile(string $key, int $exp, $val) { // Write to temp file first to ensure atomicity. Use crc32 for speed $dir = $this->getFullDirectory(); $this->checkDirectory($dir); $tmp = $dir . DIRECTORY_SEPARATOR . crc32($key) . '-' . uniqid('', true) . '.tmp'; file_put_contents($tmp, '<?php $exp = ' . $exp . '; $val = ' . $val . ';', LOCK_EX); return rename($tmp, $this->filePath($key)); } /** * @param $dir */ protected function checkDirectory($dir) { if (! is_dir($dir)) { mkdir($dir, 0777, true); } } /** * Get the expiration time based on the given seconds. * * @param float|int $seconds * @return int */ protected function expiration($seconds) { return strtotime('+' . ($seconds ?: 9999999999) . ' seconds'); } /** * Extend expiration time with given seconds * * @param string $key * @param int $seconds * @return bool */ public function extendExpiration(string $key, int $seconds = 1) { @include $this->filePath($key); if (isset($exp)) { $extended = strtotime('+' . $seconds . ' seconds', $exp); return $this->writeFile($key, $extended, var_export($val, true)); } return false; } }