1<?php 2/** 3 * Zend Framework (http://framework.zend.com/) 4 * 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 */ 9 10namespace Zend\Cache\Storage\Adapter; 11 12use Traversable; 13use Zend\Cache\Exception; 14 15/** 16 * These are options specific to the Filesystem adapter 17 */ 18class FilesystemOptions extends AdapterOptions 19{ 20 /** 21 * Directory to store cache files 22 * 23 * @var null|string The cache directory 24 * or NULL for the systems temporary directory 25 */ 26 protected $cacheDir = null; 27 28 /** 29 * Call clearstatcache enabled? 30 * 31 * @var bool 32 */ 33 protected $clearStatCache = true; 34 35 /** 36 * How much sub-directaries should be created? 37 * 38 * @var int 39 */ 40 protected $dirLevel = 1; 41 42 /** 43 * Permission creating new directories 44 * 45 * @var false|int 46 */ 47 protected $dirPermission = 0700; 48 49 /** 50 * Lock files on writing 51 * 52 * @var bool 53 */ 54 protected $fileLocking = true; 55 56 /** 57 * Permission creating new files 58 * 59 * @var false|int 60 */ 61 protected $filePermission = 0600; 62 63 /** 64 * Overwrite default key pattern 65 * 66 * Defined in AdapterOptions 67 * 68 * @var string 69 */ 70 protected $keyPattern = '/^[a-z0-9_\+\-]*$/Di'; 71 72 /** 73 * Namespace separator 74 * 75 * @var string 76 */ 77 protected $namespaceSeparator = '-'; 78 79 /** 80 * Don't get 'fileatime' as 'atime' on metadata 81 * 82 * @var bool 83 */ 84 protected $noAtime = true; 85 86 /** 87 * Don't get 'filectime' as 'ctime' on metadata 88 * 89 * @var bool 90 */ 91 protected $noCtime = true; 92 93 /** 94 * Umask to create files and directories 95 * 96 * @var false|int 97 */ 98 protected $umask = false; 99 100 /** 101 * Constructor 102 * 103 * @param array|Traversable|null $options 104 * @return FilesystemOptions 105 * @throws Exception\InvalidArgumentException 106 */ 107 public function __construct($options = null) 108 { 109 // disable file/directory permissions by default on windows systems 110 if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN') { 111 $this->filePermission = false; 112 $this->dirPermission = false; 113 } 114 115 parent::__construct($options); 116 } 117 118 /** 119 * Set cache dir 120 * 121 * @param string $cacheDir 122 * @return FilesystemOptions 123 * @throws Exception\InvalidArgumentException 124 */ 125 public function setCacheDir($cacheDir) 126 { 127 if ($cacheDir !== null) { 128 if (!is_dir($cacheDir)) { 129 throw new Exception\InvalidArgumentException( 130 "Cache directory '{$cacheDir}' not found or not a directory" 131 ); 132 } elseif (!is_writable($cacheDir)) { 133 throw new Exception\InvalidArgumentException( 134 "Cache directory '{$cacheDir}' not writable" 135 ); 136 } elseif (!is_readable($cacheDir)) { 137 throw new Exception\InvalidArgumentException( 138 "Cache directory '{$cacheDir}' not readable" 139 ); 140 } 141 142 $cacheDir = rtrim(realpath($cacheDir), DIRECTORY_SEPARATOR); 143 } else { 144 $cacheDir = sys_get_temp_dir(); 145 } 146 147 $this->triggerOptionEvent('cache_dir', $cacheDir); 148 $this->cacheDir = $cacheDir; 149 return $this; 150 } 151 152 /** 153 * Get cache dir 154 * 155 * @return null|string 156 */ 157 public function getCacheDir() 158 { 159 if ($this->cacheDir === null) { 160 $this->setCacheDir(null); 161 } 162 163 return $this->cacheDir; 164 } 165 166 /** 167 * Set clear stat cache 168 * 169 * @param bool $clearStatCache 170 * @return FilesystemOptions 171 */ 172 public function setClearStatCache($clearStatCache) 173 { 174 $clearStatCache = (bool) $clearStatCache; 175 $this->triggerOptionEvent('clear_stat_cache', $clearStatCache); 176 $this->clearStatCache = $clearStatCache; 177 return $this; 178 } 179 180 /** 181 * Get clear stat cache 182 * 183 * @return bool 184 */ 185 public function getClearStatCache() 186 { 187 return $this->clearStatCache; 188 } 189 190 /** 191 * Set dir level 192 * 193 * @param int $dirLevel 194 * @return FilesystemOptions 195 * @throws Exception\InvalidArgumentException 196 */ 197 public function setDirLevel($dirLevel) 198 { 199 $dirLevel = (int) $dirLevel; 200 if ($dirLevel < 0 || $dirLevel > 16) { 201 throw new Exception\InvalidArgumentException( 202 "Directory level '{$dirLevel}' must be between 0 and 16" 203 ); 204 } 205 $this->triggerOptionEvent('dir_level', $dirLevel); 206 $this->dirLevel = $dirLevel; 207 return $this; 208 } 209 210 /** 211 * Get dir level 212 * 213 * @return int 214 */ 215 public function getDirLevel() 216 { 217 return $this->dirLevel; 218 } 219 220 /** 221 * Set permission to create directories on unix systems 222 * 223 * @param false|string|int $dirPermission FALSE to disable explicit permission or an octal number 224 * @return FilesystemOptions 225 * @see setUmask 226 * @see setFilePermission 227 * @link http://php.net/manual/function.chmod.php 228 */ 229 public function setDirPermission($dirPermission) 230 { 231 if ($dirPermission !== false) { 232 if (is_string($dirPermission)) { 233 $dirPermission = octdec($dirPermission); 234 } else { 235 $dirPermission = (int) $dirPermission; 236 } 237 238 // validate 239 if (($dirPermission & 0700) != 0700) { 240 throw new Exception\InvalidArgumentException( 241 'Invalid directory permission: need permission to execute, read and write by owner' 242 ); 243 } 244 } 245 246 if ($this->dirPermission !== $dirPermission) { 247 $this->triggerOptionEvent('dir_permission', $dirPermission); 248 $this->dirPermission = $dirPermission; 249 } 250 251 return $this; 252 } 253 254 /** 255 * Get permission to create directories on unix systems 256 * 257 * @return false|int 258 */ 259 public function getDirPermission() 260 { 261 return $this->dirPermission; 262 } 263 264 /** 265 * Set file locking 266 * 267 * @param bool $fileLocking 268 * @return FilesystemOptions 269 */ 270 public function setFileLocking($fileLocking) 271 { 272 $fileLocking = (bool) $fileLocking; 273 $this->triggerOptionEvent('file_locking', $fileLocking); 274 $this->fileLocking = $fileLocking; 275 return $this; 276 } 277 278 /** 279 * Get file locking 280 * 281 * @return bool 282 */ 283 public function getFileLocking() 284 { 285 return $this->fileLocking; 286 } 287 288 /** 289 * Set permission to create files on unix systems 290 * 291 * @param false|string|int $filePermission FALSE to disable explicit permission or an octal number 292 * @return FilesystemOptions 293 * @see setUmask 294 * @see setDirPermission 295 * @link http://php.net/manual/function.chmod.php 296 */ 297 public function setFilePermission($filePermission) 298 { 299 if ($filePermission !== false) { 300 if (is_string($filePermission)) { 301 $filePermission = octdec($filePermission); 302 } else { 303 $filePermission = (int) $filePermission; 304 } 305 306 // validate 307 if (($filePermission & 0600) != 0600) { 308 throw new Exception\InvalidArgumentException( 309 'Invalid file permission: need permission to read and write by owner' 310 ); 311 } elseif ($filePermission & 0111) { 312 throw new Exception\InvalidArgumentException( 313 "Invalid file permission: Cache files shoudn't be executable" 314 ); 315 } 316 } 317 318 if ($this->filePermission !== $filePermission) { 319 $this->triggerOptionEvent('file_permission', $filePermission); 320 $this->filePermission = $filePermission; 321 } 322 323 return $this; 324 } 325 326 /** 327 * Get permission to create files on unix systems 328 * 329 * @return false|int 330 */ 331 public function getFilePermission() 332 { 333 return $this->filePermission; 334 } 335 336 /** 337 * Set namespace separator 338 * 339 * @param string $namespaceSeparator 340 * @return FilesystemOptions 341 */ 342 public function setNamespaceSeparator($namespaceSeparator) 343 { 344 $namespaceSeparator = (string) $namespaceSeparator; 345 $this->triggerOptionEvent('namespace_separator', $namespaceSeparator); 346 $this->namespaceSeparator = $namespaceSeparator; 347 return $this; 348 } 349 350 /** 351 * Get namespace separator 352 * 353 * @return string 354 */ 355 public function getNamespaceSeparator() 356 { 357 return $this->namespaceSeparator; 358 } 359 360 /** 361 * Set no atime 362 * 363 * @param bool $noAtime 364 * @return FilesystemOptions 365 */ 366 public function setNoAtime($noAtime) 367 { 368 $noAtime = (bool) $noAtime; 369 $this->triggerOptionEvent('no_atime', $noAtime); 370 $this->noAtime = $noAtime; 371 return $this; 372 } 373 374 /** 375 * Get no atime 376 * 377 * @return bool 378 */ 379 public function getNoAtime() 380 { 381 return $this->noAtime; 382 } 383 384 /** 385 * Set no ctime 386 * 387 * @param bool $noCtime 388 * @return FilesystemOptions 389 */ 390 public function setNoCtime($noCtime) 391 { 392 $noCtime = (bool) $noCtime; 393 $this->triggerOptionEvent('no_ctime', $noCtime); 394 $this->noCtime = $noCtime; 395 return $this; 396 } 397 398 /** 399 * Get no ctime 400 * 401 * @return bool 402 */ 403 public function getNoCtime() 404 { 405 return $this->noCtime; 406 } 407 408 /** 409 * Set the umask to create files and directories on unix systems 410 * 411 * Note: On multithreaded webservers it's better to explicit set file and dir permission. 412 * 413 * @param false|string|int $umask FALSE to disable umask or an octal number 414 * @return FilesystemOptions 415 * @see setFilePermission 416 * @see setDirPermission 417 * @link http://php.net/manual/function.umask.php 418 * @link http://en.wikipedia.org/wiki/Umask 419 */ 420 public function setUmask($umask) 421 { 422 if ($umask !== false) { 423 if (is_string($umask)) { 424 $umask = octdec($umask); 425 } else { 426 $umask = (int) $umask; 427 } 428 429 // validate 430 if ($umask & 0700) { 431 throw new Exception\InvalidArgumentException( 432 'Invalid umask: need permission to execute, read and write by owner' 433 ); 434 } 435 436 // normalize 437 $umask = $umask & ~0002; 438 } 439 440 if ($this->umask !== $umask) { 441 $this->triggerOptionEvent('umask', $umask); 442 $this->umask = $umask; 443 } 444 445 return $this; 446 } 447 448 /** 449 * Get the umask to create files and directories on unix systems 450 * 451 * @return false|int 452 */ 453 public function getUmask() 454 { 455 return $this->umask; 456 } 457} 458