fix calendar css, take 2. (#213)
[openemr.git] / interface / modules / zend_modules / library / Zend / Cache / Pattern / CaptureCache.php
blob03fa037ac13c60314e8c981a19cbbe90c69e5d4f
1 <?php
2 /**
3 * Zend Framework (http://framework.zend.com/)
5 * @link http://github.com/zendframework/zf2 for the canonical source repository
6 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
7 * @license http://framework.zend.com/license/new-bsd New BSD License
8 */
10 namespace Zend\Cache\Pattern;
12 use Zend\Cache\Exception;
13 use Zend\Stdlib\ErrorHandler;
15 class CaptureCache extends AbstractPattern
17 /**
18 * Start the cache
20 * @param string $pageId Page identifier
21 * @return void
23 public function start($pageId = null)
25 if ($pageId === null) {
26 $pageId = $this->detectPageId();
29 $that = $this;
30 ob_start(function ($content) use ($that, $pageId) {
31 $that->set($content, $pageId);
33 // http://php.net/manual/function.ob-start.php
34 // -> If output_callback returns FALSE original input is sent to the browser.
35 return false;
36 });
38 ob_implicit_flush(0);
41 /**
42 * Write content to page identity
44 * @param string $content
45 * @param null|string $pageId
46 * @throws Exception\LogicException
48 public function set($content, $pageId = null)
50 $publicDir = $this->getOptions()->getPublicDir();
51 if ($publicDir === null) {
52 throw new Exception\LogicException("Option 'public_dir' no set");
55 if ($pageId === null) {
56 $pageId = $this->detectPageId();
59 $path = $this->pageId2Path($pageId);
60 $file = $path . DIRECTORY_SEPARATOR . $this->pageId2Filename($pageId);
62 $this->createDirectoryStructure($publicDir . DIRECTORY_SEPARATOR . $path);
63 $this->putFileContent($publicDir . DIRECTORY_SEPARATOR . $file, $content);
66 /**
67 * Get from cache
69 * @param null|string $pageId
70 * @return string|null
71 * @throws Exception\LogicException
72 * @throws Exception\RuntimeException
74 public function get($pageId = null)
76 $publicDir = $this->getOptions()->getPublicDir();
77 if ($publicDir === null) {
78 throw new Exception\LogicException("Option 'public_dir' no set");
81 if ($pageId === null) {
82 $pageId = $this->detectPageId();
85 $file = $publicDir
86 . DIRECTORY_SEPARATOR . $this->pageId2Path($pageId)
87 . DIRECTORY_SEPARATOR . $this->pageId2Filename($pageId);
89 if (file_exists($file)) {
90 ErrorHandler::start();
91 $content = file_get_contents($file);
92 $error = ErrorHandler::stop();
93 if ($content === false) {
94 throw new Exception\RuntimeException("Failed to read cached pageId '{$pageId}'", 0, $error);
96 return $content;
101 * Checks if a cache with given id exists
103 * @param null|string $pageId
104 * @throws Exception\LogicException
105 * @return bool
107 public function has($pageId = null)
109 $publicDir = $this->getOptions()->getPublicDir();
110 if ($publicDir === null) {
111 throw new Exception\LogicException("Option 'public_dir' no set");
114 if ($pageId === null) {
115 $pageId = $this->detectPageId();
118 $file = $publicDir
119 . DIRECTORY_SEPARATOR . $this->pageId2Path($pageId)
120 . DIRECTORY_SEPARATOR . $this->pageId2Filename($pageId);
122 return file_exists($file);
126 * Remove from cache
128 * @param null|string $pageId
129 * @throws Exception\LogicException
130 * @throws Exception\RuntimeException
131 * @return bool
133 public function remove($pageId = null)
135 $publicDir = $this->getOptions()->getPublicDir();
136 if ($publicDir === null) {
137 throw new Exception\LogicException("Option 'public_dir' no set");
140 if ($pageId === null) {
141 $pageId = $this->detectPageId();
144 $file = $publicDir
145 . DIRECTORY_SEPARATOR . $this->pageId2Path($pageId)
146 . DIRECTORY_SEPARATOR . $this->pageId2Filename($pageId);
148 if (file_exists($file)) {
149 ErrorHandler::start();
150 $res = unlink($file);
151 $err = ErrorHandler::stop();
152 if (!$res) {
153 throw new Exception\RuntimeException("Failed to remove cached pageId '{$pageId}'", 0, $err);
155 return true;
158 return false;
162 * Clear cached pages matching glob pattern
164 * @param string $pattern
165 * @throws Exception\LogicException
167 public function clearByGlob($pattern = '**')
169 $publicDir = $this->getOptions()->getPublicDir();
170 if ($publicDir === null) {
171 throw new Exception\LogicException("Option 'public_dir' no set");
174 $it = new \GlobIterator(
175 $publicDir . '/' . $pattern,
176 \GlobIterator::CURRENT_AS_SELF | \GlobIterator::SKIP_DOTS | \GlobIterator::UNIX_PATHS
178 foreach ($it as $pathname => $entry) {
179 if ($entry->isFile()) {
180 unlink($pathname);
186 * Determine the page to save from the request
188 * @throws Exception\RuntimeException
189 * @return string
191 protected function detectPageId()
193 if (!isset($_SERVER['REQUEST_URI'])) {
194 throw new Exception\RuntimeException("Can't auto-detect current page identity");
197 return $_SERVER['REQUEST_URI'];
201 * Get filename for page id
203 * @param string $pageId
204 * @return string
206 protected function pageId2Filename($pageId)
208 if (substr($pageId, -1) === '/') {
209 return $this->getOptions()->getIndexFilename();
212 return basename($pageId);
216 * Get path for page id
218 * @param string $pageId
219 * @return string
221 protected function pageId2Path($pageId)
223 if (substr($pageId, -1) == '/') {
224 $path = rtrim($pageId, '/');
225 } else {
226 $path = dirname($pageId);
229 // convert requested "/" to the valid local directory separator
230 if ('/' != DIRECTORY_SEPARATOR) {
231 $path = str_replace('/', DIRECTORY_SEPARATOR, $path);
234 return $path;
238 * Write content to a file
240 * @param string $file File complete path
241 * @param string $data Data to write
242 * @return void
243 * @throws Exception\RuntimeException
245 protected function putFileContent($file, $data)
247 $options = $this->getOptions();
248 $locking = $options->getFileLocking();
249 $perm = $options->getFilePermission();
250 $umask = $options->getUmask();
251 if ($umask !== false && $perm !== false) {
252 $perm = $perm & ~$umask;
255 ErrorHandler::start();
257 $umask = ($umask !== false) ? umask($umask) : false;
258 $rs = file_put_contents($file, $data, $locking ? LOCK_EX : 0);
259 if ($umask) {
260 umask($umask);
263 if ($rs === false) {
264 $err = ErrorHandler::stop();
265 throw new Exception\RuntimeException("Error writing file '{$file}'", 0, $err);
268 if ($perm !== false && !chmod($file, $perm)) {
269 $oct = decoct($perm);
270 $err = ErrorHandler::stop();
271 throw new Exception\RuntimeException("chmod('{$file}', 0{$oct}) failed", 0, $err);
274 ErrorHandler::stop();
278 * Creates directory if not already done.
280 * @param string $pathname
281 * @return void
282 * @throws Exception\RuntimeException
284 protected function createDirectoryStructure($pathname)
286 // Directory structure already exists
287 if (file_exists($pathname)) {
288 return;
291 $options = $this->getOptions();
292 $perm = $options->getDirPermission();
293 $umask = $options->getUmask();
294 if ($umask !== false && $perm !== false) {
295 $perm = $perm & ~$umask;
298 ErrorHandler::start();
300 if ($perm === false) {
301 // build-in mkdir function is enough
303 $umask = ($umask !== false) ? umask($umask) : false;
304 $res = mkdir($pathname, ($perm !== false) ? $perm : 0775, true);
306 if ($umask !== false) {
307 umask($umask);
310 if (!$res) {
311 $oct = ($perm === false) ? '775' : decoct($perm);
312 $err = ErrorHandler::stop();
313 throw new Exception\RuntimeException("mkdir('{$pathname}', 0{$oct}, true) failed", 0, $err);
316 if ($perm !== false && !chmod($pathname, $perm)) {
317 $oct = decoct($perm);
318 $err = ErrorHandler::stop();
319 throw new Exception\RuntimeException("chmod('{$pathname}', 0{$oct}) failed", 0, $err);
321 } else {
322 // build-in mkdir function sets permission together with current umask
323 // which doesn't work well on multo threaded webservers
324 // -> create directories one by one and set permissions
326 // find existing path and missing path parts
327 $parts = array();
328 $path = $pathname;
329 while (!file_exists($path)) {
330 array_unshift($parts, basename($path));
331 $nextPath = dirname($path);
332 if ($nextPath === $path) {
333 break;
335 $path = $nextPath;
338 // make all missing path parts
339 foreach ($parts as $part) {
340 $path.= DIRECTORY_SEPARATOR . $part;
342 // create a single directory, set and reset umask immediately
343 $umask = ($umask !== false) ? umask($umask) : false;
344 $res = mkdir($path, ($perm === false) ? 0775 : $perm, false);
345 if ($umask !== false) {
346 umask($umask);
349 if (!$res) {
350 $oct = ($perm === false) ? '775' : decoct($perm);
351 ErrorHandler::stop();
352 throw new Exception\RuntimeException(
353 "mkdir('{$path}', 0{$oct}, false) failed"
357 if ($perm !== false && !chmod($path, $perm)) {
358 $oct = decoct($perm);
359 ErrorHandler::stop();
360 throw new Exception\RuntimeException(
361 "chmod('{$path}', 0{$oct}) failed"
367 ErrorHandler::stop();
371 * Returns the generated file name.
373 * @param null|string $pageId
374 * @return string
376 public function getFilename($pageId = null)
378 if ($pageId === null) {
379 $pageId = $this->detectPageId();
382 $publicDir = $this->getOptions()->getPublicDir();
383 $path = $this->pageId2Path($pageId);
384 $file = $path . DIRECTORY_SEPARATOR . $this->pageId2Filename($pageId);
386 return $publicDir . $file;