Browse Source

improved control over and handling of file and dir permissions

- rename FileHelper::mkdir for API consistency
- changed default permission for directories to 775 instead of 777
- added some properties to classes that deal with files to allow control
  over directory permissions.
tags/2.0.0-beta
Carsten Brandt 11 years ago
parent
commit
4b7f5a728a
  1. 24
      extensions/mutex/yii/mutex/FileMutex.php
  2. 23
      framework/yii/caching/FileCache.php
  3. 14
      framework/yii/helpers/FileHelperBase.php
  4. 19
      framework/yii/log/FileTarget.php
  5. 11
      framework/yii/web/AssetManager.php
  6. 4
      tests/unit/framework/helpers/FileHelperTest.php

24
extensions/mutex/yii/mutex/FileMutex.php

@ -9,6 +9,7 @@ namespace yii\mutex;
use Yii; use Yii;
use yii\base\InvalidConfigException; use yii\base\InvalidConfigException;
use yii\helpers\FileHelper;
/** /**
* @author resurtm <resurtm@gmail.com> * @author resurtm <resurtm@gmail.com>
@ -22,6 +23,19 @@ class FileMutex extends Mutex
*/ */
public $mutexPath = '@runtime/mutex'; public $mutexPath = '@runtime/mutex';
/** /**
* @var integer the permission to be set for newly created mutex files.
* This value will be used by PHP chmod() function. No umask will be applied.
* If not set, the permission will be determined by the current environment.
*/
public $fileMode;
/**
* @var integer the permission to be set for newly created directories.
* This value will be used by PHP chmod() function. No umask will be applied.
* Defaults to 0775, meaning the directory is read-writable by owner and group,
* but read-only for other users.
*/
public $dirMode = 0775;
/**
* @var resource[] stores all opened lock files. Keys are lock names and values are file handles. * @var resource[] stores all opened lock files. Keys are lock names and values are file handles.
*/ */
private $_files = array(); private $_files = array();
@ -39,22 +53,26 @@ class FileMutex extends Mutex
} }
$this->mutexPath = Yii::getAlias($this->mutexPath); $this->mutexPath = Yii::getAlias($this->mutexPath);
if (!is_dir($this->mutexPath)) { if (!is_dir($this->mutexPath)) {
mkdir($this->mutexPath, 0777, true); FileHelper::createDirectory($this->mutexPath, $this->dirMode, true);
} }
} }
/** /**
* This method should be extended by concrete mutex implementations. Acquires lock by given name. * Acquires lock by given name.
* @param string $name of the lock to be acquired. * @param string $name of the lock to be acquired.
* @param integer $timeout to wait for lock to become released. * @param integer $timeout to wait for lock to become released.
* @return boolean acquiring result. * @return boolean acquiring result.
*/ */
protected function acquireLock($name, $timeout = 0) protected function acquireLock($name, $timeout = 0)
{ {
$file = fopen($this->mutexPath . '/' . md5($name) . '.lock', 'w+'); $fileName = $this->mutexPath . '/' . md5($name) . '.lock';
$file = fopen($fileName, 'w+');
if ($file === false) { if ($file === false) {
return false; return false;
} }
if ($this->fileMode !== null) {
@chmod($fileName, $this->fileMode);
}
$waitTime = 0; $waitTime = 0;
while (!flock($file, LOCK_EX | LOCK_NB)) { while (!flock($file, LOCK_EX | LOCK_NB)) {
$waitTime++; $waitTime++;

23
framework/yii/caching/FileCache.php

@ -8,6 +8,7 @@
namespace yii\caching; namespace yii\caching;
use Yii; use Yii;
use yii\helpers\FileHelper;
/** /**
* FileCache implements a cache component using files. * FileCache implements a cache component using files.
@ -45,6 +46,20 @@ class FileCache extends Cache
* This number should be between 0 and 1000000. A value 0 means no GC will be performed at all. * This number should be between 0 and 1000000. A value 0 means no GC will be performed at all.
**/ **/
public $gcProbability = 10; public $gcProbability = 10;
/**
* @var integer the permission to be set for newly created cache files.
* This value will be used by PHP chmod() function. No umask will be applied.
* If not set, the permission will be determined by the current environment.
*/
public $fileMode;
/**
* @var integer the permission to be set for newly created directories.
* This value will be used by PHP chmod() function. No umask will be applied.
* Defaults to 0775, meaning the directory is read-writable by owner and group,
* but read-only for other users.
*/
public $dirMode = 0775;
/** /**
* Initializes this component by ensuring the existence of the cache path. * Initializes this component by ensuring the existence of the cache path.
@ -54,7 +69,7 @@ class FileCache extends Cache
parent::init(); parent::init();
$this->cachePath = Yii::getAlias($this->cachePath); $this->cachePath = Yii::getAlias($this->cachePath);
if (!is_dir($this->cachePath)) { if (!is_dir($this->cachePath)) {
mkdir($this->cachePath, 0777, true); FileHelper::createDirectory($this->cachePath, $this->dirMode, true);
} }
} }
@ -108,10 +123,12 @@ class FileCache extends Cache
$cacheFile = $this->getCacheFile($key); $cacheFile = $this->getCacheFile($key);
if ($this->directoryLevel > 0) { if ($this->directoryLevel > 0) {
@mkdir(dirname($cacheFile), 0777, true); @FileHelper::createDirectory(dirname($cacheFile), $this->dirMode, true);
} }
if (@file_put_contents($cacheFile, $value, LOCK_EX) !== false) { if (@file_put_contents($cacheFile, $value, LOCK_EX) !== false) {
@chmod($cacheFile, 0777); if ($this->fileMode !== null) {
@chmod($cacheFile, $this->fileMode);
}
return @touch($cacheFile, $expire); return @touch($cacheFile, $expire);
} else { } else {
return false; return false;

14
framework/yii/helpers/FileHelperBase.php

@ -133,7 +133,7 @@ class FileHelperBase
* @param string $dst the destination directory * @param string $dst the destination directory
* @param array $options options for directory copy. Valid options are: * @param array $options options for directory copy. Valid options are:
* *
* - dirMode: integer, the permission to be set for newly copied directories. Defaults to 0777. * - dirMode: integer, the permission to be set for newly copied directories. Defaults to 0775.
* - fileMode: integer, the permission to be set for newly copied files. Defaults to the current environment setting. * - fileMode: integer, the permission to be set for newly copied files. Defaults to the current environment setting.
* - filter: callback, a PHP callback that is called for each directory or file. * - filter: callback, a PHP callback that is called for each directory or file.
* The signature of the callback should be: `function ($path)`, where `$path` refers the full path to be filtered. * The signature of the callback should be: `function ($path)`, where `$path` refers the full path to be filtered.
@ -162,7 +162,7 @@ class FileHelperBase
public static function copyDirectory($src, $dst, $options = array()) public static function copyDirectory($src, $dst, $options = array())
{ {
if (!is_dir($dst)) { if (!is_dir($dst)) {
static::mkdir($dst, isset($options['dirMode']) ? $options['dirMode'] : 0777, true); static::createDirectory($dst, isset($options['dirMode']) ? $options['dirMode'] : 0775, true);
} }
$handle = opendir($src); $handle = opendir($src);
@ -302,25 +302,25 @@ class FileHelperBase
} }
/** /**
* Makes directory. * Creates a new directory.
* *
* This method is similar to the PHP `mkdir()` function except that * This method is similar to the PHP `mkdir()` function except that
* it uses `chmod()` to set the permission of the created directory * it uses `chmod()` to set the permission of the created directory
* in order to avoid the impact of the `umask` setting. * in order to avoid the impact of the `umask` setting.
* *
* @param string $path path to be created. * @param string $path path of the directory to be created.
* @param integer $mode the permission to be set for created directory. * @param integer $mode the permission to be set for the created directory.
* @param boolean $recursive whether to create parent directories if they do not exist. * @param boolean $recursive whether to create parent directories if they do not exist.
* @return boolean whether the directory is created successfully * @return boolean whether the directory is created successfully
*/ */
public static function mkdir($path, $mode = 0777, $recursive = true) public static function createDirectory($path, $mode = 0775, $recursive = true)
{ {
if (is_dir($path)) { if (is_dir($path)) {
return true; return true;
} }
$parentDir = dirname($path); $parentDir = dirname($path);
if ($recursive && !is_dir($parentDir)) { if ($recursive && !is_dir($parentDir)) {
static::mkdir($parentDir, $mode, true); static::createDirectory($parentDir, $mode, true);
} }
$result = mkdir($path, $mode); $result = mkdir($path, $mode);
chmod($path, $mode); chmod($path, $mode);

19
framework/yii/log/FileTarget.php

@ -9,6 +9,7 @@ namespace yii\log;
use Yii; use Yii;
use yii\base\InvalidConfigException; use yii\base\InvalidConfigException;
use yii\helpers\FileHelper;
/** /**
* FileTarget records log messages in a file. * FileTarget records log messages in a file.
@ -37,6 +38,19 @@ class FileTarget extends Target
* @var integer number of log files used for rotation. Defaults to 5. * @var integer number of log files used for rotation. Defaults to 5.
*/ */
public $maxLogFiles = 5; public $maxLogFiles = 5;
/**
* @var integer the permission to be set for newly created log files.
* This value will be used by PHP chmod() function. No umask will be applied.
* If not set, the permission will be determined by the current environment.
*/
public $fileMode;
/**
* @var integer the permission to be set for newly created directories.
* This value will be used by PHP chmod() function. No umask will be applied.
* Defaults to 0775, meaning the directory is read-writable by owner and group,
* but read-only for other users.
*/
public $dirMode = 0775;
/** /**
@ -53,7 +67,7 @@ class FileTarget extends Target
} }
$logPath = dirname($this->logFile); $logPath = dirname($this->logFile);
if (!is_dir($logPath)) { if (!is_dir($logPath)) {
@mkdir($logPath, 0777, true); FileHelper::createDirectory($logPath, $this->dirMode, true);
} }
if ($this->maxLogFiles < 1) { if ($this->maxLogFiles < 1) {
$this->maxLogFiles = 1; $this->maxLogFiles = 1;
@ -87,6 +101,9 @@ class FileTarget extends Target
@flock($fp, LOCK_UN); @flock($fp, LOCK_UN);
@fclose($fp); @fclose($fp);
} }
if ($this->fileMode !== null) {
@chmod($this->logFile, $this->fileMode);
}
} }
/** /**

11
framework/yii/web/AssetManager.php

@ -58,16 +58,17 @@ class AssetManager extends Component
public $linkAssets = false; public $linkAssets = false;
/** /**
* @var integer the permission to be set for newly published asset files. * @var integer the permission to be set for newly published asset files.
* This value will be used by PHP chmod() function. * This value will be used by PHP chmod() function. No umask will be applied.
* If not set, the permission will be determined by the current environment. * If not set, the permission will be determined by the current environment.
*/ */
public $fileMode; public $fileMode;
/** /**
* @var integer the permission to be set for newly generated asset directories. * @var integer the permission to be set for newly generated asset directories.
* This value will be used by PHP chmod() function. * This value will be used by PHP chmod() function. No umask will be applied.
* Defaults to 0777, meaning the directory can be read, written and executed by all users. * Defaults to 0775, meaning the directory is read-writable by owner and group,
* but read-only for other users.
*/ */
public $dirMode = 0777; public $dirMode = 0775;
/** /**
* Initializes the component. * Initializes the component.
@ -205,7 +206,7 @@ class AssetManager extends Component
$dstFile = $dstDir . DIRECTORY_SEPARATOR . $fileName; $dstFile = $dstDir . DIRECTORY_SEPARATOR . $fileName;
if (!is_dir($dstDir)) { if (!is_dir($dstDir)) {
mkdir($dstDir, $this->dirMode, true); FileHelper::createDirectory($dstDir, $this->dirMode, true);
} }
if ($this->linkAssets) { if ($this->linkAssets) {

4
tests/unit/framework/helpers/FileHelperTest.php

@ -275,9 +275,9 @@ class FileHelperTest extends TestCase
{ {
$basePath = $this->testFilePath; $basePath = $this->testFilePath;
$dirName = $basePath . DIRECTORY_SEPARATOR . 'test_dir_level_1' . DIRECTORY_SEPARATOR . 'test_dir_level_2'; $dirName = $basePath . DIRECTORY_SEPARATOR . 'test_dir_level_1' . DIRECTORY_SEPARATOR . 'test_dir_level_2';
$this->assertTrue(FileHelper::mkdir($dirName), 'FileHelper::mkdir should return true if directory was created!'); $this->assertTrue(FileHelper::createDirectory($dirName), 'FileHelper::mkdir should return true if directory was created!');
$this->assertTrue(file_exists($dirName), 'Unable to create directory recursively!'); $this->assertTrue(file_exists($dirName), 'Unable to create directory recursively!');
$this->assertTrue(FileHelper::mkdir($dirName), 'FileHelper::mkdir should return true for already existing directories!'); $this->assertTrue(FileHelper::createDirectory($dirName), 'FileHelper::mkdir should return true for already existing directories!');
} }
public function testGetMimeTypeByExtension() public function testGetMimeTypeByExtension()

Loading…
Cancel
Save