- <?php
- /**
- * Zend Framework (http://framework.zend.com/)
- *
- * @link http://github.com/zendframework/zf2 for the canonical source repository
- * @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- */
-
- namespace Zend\Cache\Pattern;
-
- use Zend\Cache\Exception;
- use Zend\Stdlib\ErrorHandler;
-
- class CaptureCache extends AbstractPattern
- {
- /**
- * Start the cache
- *
- * @param string $pageId Page identifier
- * @return void
- */
- public function start($pageId = null)
- {
- if ($pageId === null) {
- $pageId = $this->detectPageId();
- }
-
- $that = $this;
- ob_start(function ($content) use ($that, $pageId) {
- $that->set($content, $pageId);
-
- // http://php.net/manual/function.ob-start.php
- // -> If output_callback returns FALSE original input is sent to the browser.
- return false;
- });
-
- ob_implicit_flush(false);
- }
-
- /**
- * Write content to page identity
- *
- * @param string $content
- * @param null|string $pageId
- * @throws Exception\LogicException
- */
- public function set($content, $pageId = null)
- {
- $publicDir = $this->getOptions()->getPublicDir();
- if ($publicDir === null) {
- throw new Exception\LogicException("Option 'public_dir' no set");
- }
-
- if ($pageId === null) {
- $pageId = $this->detectPageId();
- }
-
- $path = $this->pageId2Path($pageId);
- $file = $path . DIRECTORY_SEPARATOR . $this->pageId2Filename($pageId);
-
- $this->createDirectoryStructure($publicDir . DIRECTORY_SEPARATOR . $path);
- $this->putFileContent($publicDir . DIRECTORY_SEPARATOR . $file, $content);
- }
-
- /**
- * Get from cache
- *
- * @param null|string $pageId
- * @return bool|string
- * @throws Exception\LogicException
- * @throws Exception\RuntimeException
- */
- public function get($pageId = null)
- {
- $publicDir = $this->getOptions()->getPublicDir();
- if ($publicDir === null) {
- throw new Exception\LogicException("Option 'public_dir' no set");
- }
-
- if ($pageId === null) {
- $pageId = $this->detectPageId();
- }
-
- $file = $publicDir
- . DIRECTORY_SEPARATOR . $this->pageId2Path($pageId)
- . DIRECTORY_SEPARATOR . $this->pageId2Filename($pageId);
-
- if (file_exists($file)) {
- ErrorHandler::start();
- $content = file_get_contents($file);
- $error = ErrorHandler::stop();
- if ($content === false) {
- throw new Exception\RuntimeException(
- "Failed to read cached pageId '{$pageId}'", 0, $error
- );
- }
- return $content;
- }
- }
-
- /**
- * Checks if a cache with given id exists
- *
- * @param null|string $pageId
- * @throws Exception\LogicException
- * @return bool
- */
- public function has($pageId = null)
- {
- $publicDir = $this->getOptions()->getPublicDir();
- if ($publicDir === null) {
- throw new Exception\LogicException("Option 'public_dir' no set");
- }
-
- if ($pageId === null) {
- $pageId = $this->detectPageId();
- }
-
- $file = $publicDir
- . DIRECTORY_SEPARATOR . $this->pageId2Path($pageId)
- . DIRECTORY_SEPARATOR . $this->pageId2Filename($pageId);
-
- return file_exists($file);
- }
-
- /**
- * Remove from cache
- *
- * @param null|string $pageId
- * @throws Exception\LogicException
- * @throws Exception\RuntimeException
- * @return bool
- */
- public function remove($pageId = null)
- {
- $publicDir = $this->getOptions()->getPublicDir();
- if ($publicDir === null) {
- throw new Exception\LogicException("Option 'public_dir' no set");
- }
-
- if ($pageId === null) {
- $pageId = $this->detectPageId();
- }
-
- $file = $publicDir
- . DIRECTORY_SEPARATOR . $this->pageId2Path($pageId)
- . DIRECTORY_SEPARATOR . $this->pageId2Filename($pageId);
-
- if (file_exists($file)) {
- ErrorHandler::start();
- $res = unlink($file);
- $err = ErrorHandler::stop();
- if (!$res) {
- throw new Exception\RuntimeException(
- "Failed to remove cached pageId '{$pageId}'", 0, $err
- );
- }
- return true;
- }
-
- return false;
- }
-
- /**
- * Clear cached pages matching glob pattern
- *
- * @param string $pattern
- * @throws Exception\LogicException
- */
- public function clearByGlob($pattern = '**')
- {
- $publicDir = $this->getOptions()->getPublicDir();
- if ($publicDir === null) {
- throw new Exception\LogicException("Option 'public_dir' no set");
- }
-
- $it = new \GlobIterator(
- $publicDir . '/' . $pattern,
- \GlobIterator::CURRENT_AS_SELF | \GlobIterator::SKIP_DOTS | \GlobIterator::UNIX_PATHS
- );
- foreach ($it as $pathname => $entry) {
- if ($entry->isFile()) {
- unlink($pathname);
- }
- }
- }
-
- /**
- * Determine the page to save from the request
- *
- * @throws Exception\RuntimeException
- * @return string
- */
- protected function detectPageId()
- {
- if (!isset($_SERVER['REQUEST_URI'])) {
- throw new Exception\RuntimeException("Can't auto-detect current page identity");
- }
-
- return $_SERVER['REQUEST_URI'];
- }
-
- /**
- * Get filename for page id
- *
- * @param string $pageId
- * @return string
- */
- protected function pageId2Filename($pageId)
- {
- if (substr($pageId, -1) === '/') {
- return $this->getOptions()->getIndexFilename();
- }
-
- return basename($pageId);
- }
-
- /**
- * Get path for page id
- *
- * @param string $pageId
- * @return string
- */
- protected function pageId2Path($pageId)
- {
- if (substr($pageId, -1) == '/') {
- $path = rtrim($pageId, '/');
- } else {
- $path = dirname($pageId);
- }
-
- // convert requested "/" to the valid local directory separator
- if ('/' != DIRECTORY_SEPARATOR) {
- $path = str_replace('/', DIRECTORY_SEPARATOR, $path);
- }
-
- return $path;
- }
-
- /**
- * Write content to a file
- *
- * @param string $file File complete path
- * @param string $data Data to write
- * @return void
- * @throws Exception\RuntimeException
- */
- protected function putFileContent($file, $data)
- {
- $options = $this->getOptions();
- $locking = $options->getFileLocking();
- $perm = $options->getFilePermission();
- $umask = $options->getUmask();
- if ($umask !== false && $perm !== false) {
- $perm = $perm & ~$umask;
- }
-
- ErrorHandler::start();
-
- $umask = ($umask !== false) ? umask($umask) : false;
- $rs = file_put_contents($file, $data, $locking ? LOCK_EX : 0);
- if ($umask) {
- umask($umask);
- }
-
- if ($rs === false) {
- $err = ErrorHandler::stop();
- throw new Exception\RuntimeException(
- "Error writing file '{$file}'", 0, $err
- );
- }
-
- if ($perm !== false && !chmod($file, $perm)) {
- $oct = decoct($perm);
- $err = ErrorHandler::stop();
- throw new Exception\RuntimeException("chmod('{$file}', 0{$oct}) failed", 0, $err);
- }
-
- ErrorHandler::stop();
- }
-
- /**
- * Creates directory if not already done.
- *
- * @param string $pathname
- * @return void
- * @throws Exception\RuntimeException
- */
- protected function createDirectoryStructure($pathname)
- {
- // Directory structure already exists
- if (file_exists($pathname)) {
- return;
- }
-
- $options = $this->getOptions();
- $perm = $options->getDirPermission();
- $umask = $options->getUmask();
- if ($umask !== false && $perm !== false) {
- $perm = $perm & ~$umask;
- }
-
- ErrorHandler::start();
-
- if ($perm === false) {
- // build-in mkdir function is enough
-
- $umask = ($umask !== false) ? umask($umask) : false;
- $res = mkdir($pathname, ($perm !== false) ? $perm : 0777, true);
-
- if ($umask !== false) {
- umask($umask);
- }
-
- if (!$res) {
- $oct = ($perm === false) ? '777' : decoct($perm);
- $err = ErrorHandler::stop();
- throw new Exception\RuntimeException(
- "mkdir('{$pathname}', 0{$oct}, true) failed", 0, $err
- );
- }
-
- if ($perm !== false && !chmod($pathname, $perm)) {
- $oct = decoct($perm);
- $err = ErrorHandler::stop();
- throw new Exception\RuntimeException(
- "chmod('{$pathname}', 0{$oct}) failed", 0, $err
- );
- }
-
- } else {
- // build-in mkdir function sets permission together with current umask
- // which doesn't work well on multo threaded webservers
- // -> create directories one by one and set permissions
-
- // find existing path and missing path parts
- $parts = array();
- $path = $pathname;
- while (!file_exists($path)) {
- array_unshift($parts, basename($path));
- $nextPath = dirname($path);
- if ($nextPath === $path) {
- break;
- }
- $path = $nextPath;
- }
-
- // make all missing path parts
- foreach ($parts as $part) {
- $path.= DIRECTORY_SEPARATOR . $part;
-
- // create a single directory, set and reset umask immediately
- $umask = ($umask !== false) ? umask($umask) : false;
- $res = mkdir($path, ($perm === false) ? 0777 : $perm, false);
- if ($umask !== false) {
- umask($umask);
- }
-
- if (!$res) {
- $oct = ($perm === false) ? '777' : decoct($perm);
- ErrorHandler::stop();
- throw new Exception\RuntimeException(
- "mkdir('{$path}', 0{$oct}, false) failed"
- );
- }
-
- if ($perm !== false && !chmod($path, $perm)) {
- $oct = decoct($perm);
- ErrorHandler::stop();
- throw new Exception\RuntimeException(
- "chmod('{$path}', 0{$oct}) failed"
- );
- }
- }
- }
-
- ErrorHandler::stop();
- }
-
- /**
- * Returns the generated file name.
- *
- * @param null|string $pageId
- * @return string
- */
- public function getFilename($pageId = null)
- {
- if ($pageId === null) {
- $pageId = $this->detectPageId();
- }
-
- $publicDir = $this->getOptions()->getPublicDir();
- $path = $this->pageId2Path($pageId);
- $file = $path . DIRECTORY_SEPARATOR . $this->pageId2Filename($pageId);
-
- return $publicDir . $file;
- }
- }
# |
Change |
User |
Description |
Committed |
|
#1
|
18334 |
Liz Lam |
initial add of jambox |
9 years ago
|
|