mirror of
				https://github.com/yiisoft/yii2.git
				synced 2025-11-04 14:46:19 +08:00 
			
		
		
		
	Fixes #13465: Added yii\helpers\FileHelper::findDirectory() method
				
					
				
			This commit is contained in:
		@ -4,6 +4,7 @@ Yii Framework 2 Change Log
 | 
				
			|||||||
2.0.14 under development
 | 
					2.0.14 under development
 | 
				
			||||||
------------------------
 | 
					------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Enh #13465: Added `yii\helpers\FileHelper::findDirectory()` method (ArsSirek, developeruz)
 | 
				
			||||||
- Enh #8527: Added `yii\i18n\Locale` component having `getCurrencySymbol()` method (amarox, samdark)
 | 
					- Enh #8527: Added `yii\i18n\Locale` component having `getCurrencySymbol()` method (amarox, samdark)
 | 
				
			||||||
- Enh #14546: Added `dataDirectory` property into `BaseActiveFixture` (leandrogehlen)
 | 
					- Enh #14546: Added `dataDirectory` property into `BaseActiveFixture` (leandrogehlen)
 | 
				
			||||||
- Bug #15522: Fixed `yii\db\ActiveRecord::refresh()` method does not use an alias in the condition (vladis84)
 | 
					- Bug #15522: Fixed `yii\db\ActiveRecord::refresh()` method does not use an alias in the condition (vladis84)
 | 
				
			||||||
 | 
				
			|||||||
@ -459,20 +459,10 @@ class BaseFileHelper
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    public static function findFiles($dir, $options = [])
 | 
					    public static function findFiles($dir, $options = [])
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (!is_dir($dir)) {
 | 
					        $dir = self::clearDir($dir);
 | 
				
			||||||
            throw new InvalidParamException("The dir argument must be a directory: $dir");
 | 
					        $options = self::setBasePath($dir, $options);
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        $dir = rtrim($dir, DIRECTORY_SEPARATOR);
 | 
					 | 
				
			||||||
        if (!isset($options['basePath'])) {
 | 
					 | 
				
			||||||
            // this should be done only once
 | 
					 | 
				
			||||||
            $options['basePath'] = realpath($dir);
 | 
					 | 
				
			||||||
            $options = static::normalizeOptions($options);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        $list = [];
 | 
					        $list = [];
 | 
				
			||||||
        $handle = opendir($dir);
 | 
					        $handle = self::openDir($dir);
 | 
				
			||||||
        if ($handle === false) {
 | 
					 | 
				
			||||||
            throw new InvalidParamException("Unable to open directory: $dir");
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        while (($file = readdir($handle)) !== false) {
 | 
					        while (($file = readdir($handle)) !== false) {
 | 
				
			||||||
            if ($file === '.' || $file === '..') {
 | 
					            if ($file === '.' || $file === '..') {
 | 
				
			||||||
                continue;
 | 
					                continue;
 | 
				
			||||||
@ -491,6 +481,83 @@ class BaseFileHelper
 | 
				
			|||||||
        return $list;
 | 
					        return $list;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Returns the directories found under the specified directory and subdirectories.
 | 
				
			||||||
 | 
					     * @param string $dir the directory under which the files will be looked for.
 | 
				
			||||||
 | 
					     * @param array $options options for directory searching. Valid options are:
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * - `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 callback can return one of the following values:
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     *   * `true`: the directory will be returned
 | 
				
			||||||
 | 
					     *   * `false`: the directory will NOT be returned
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * - `recursive`: boolean, whether the files under the subdirectories should also be looked for. Defaults to `true`.
 | 
				
			||||||
 | 
					     * @return array directories found under the directory, in no particular order. Ordering depends on the files system used.
 | 
				
			||||||
 | 
					     * @throws InvalidParamException if the dir is invalid.
 | 
				
			||||||
 | 
					     * @since 2.0.14
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static function findDirectory($dir, $options = [])
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $dir = self::clearDir($dir);
 | 
				
			||||||
 | 
					        $options = self::setBasePath($dir, $options);
 | 
				
			||||||
 | 
					        $list = [];
 | 
				
			||||||
 | 
					        $handle = self::openDir($dir);
 | 
				
			||||||
 | 
					        while (($file = readdir($handle)) !== false) {
 | 
				
			||||||
 | 
					            if ($file === '.' || $file === '..') {
 | 
				
			||||||
 | 
					                continue;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            $path = $dir . DIRECTORY_SEPARATOR . $file;
 | 
				
			||||||
 | 
					            if (is_dir($path) && static::filterPath($path, $options)) {
 | 
				
			||||||
 | 
					                $list[] = $path;
 | 
				
			||||||
 | 
					                if (!isset($options['recursive']) || $options['recursive']) {
 | 
				
			||||||
 | 
					                    $list = array_merge($list, static::findDirectory($path, $options));
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        closedir($handle);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $list;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					     * @param string $dir
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private static function setBasePath($dir, $options)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (!isset($options['basePath'])) {
 | 
				
			||||||
 | 
					            // this should be done only once
 | 
				
			||||||
 | 
					            $options['basePath'] = realpath($dir);
 | 
				
			||||||
 | 
					            $options = static::normalizeOptions($options);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $options;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					     * @param string $dir
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private static function openDir($dir)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $handle = opendir($dir);
 | 
				
			||||||
 | 
					        if ($handle === false) {
 | 
				
			||||||
 | 
					            throw new InvalidParamException("Unable to open directory: $dir");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return $handle;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					     * @param string $dir
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private static function clearDir($dir)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (!is_dir($dir)) {
 | 
				
			||||||
 | 
					            throw new InvalidParamException("The dir argument must be a directory: $dir");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return rtrim($dir, DIRECTORY_SEPARATOR);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Checks if the given file path satisfies the filtering options.
 | 
					     * Checks if the given file path satisfies the filtering options.
 | 
				
			||||||
     * @param string $path the path of the file or directory to be checked
 | 
					     * @param string $path the path of the file or directory to be checked
 | 
				
			||||||
 | 
				
			|||||||
@ -882,4 +882,44 @@ class FileHelperTest extends TestCase
 | 
				
			|||||||
        $this->assertFileNotExists($dstDirName . DIRECTORY_SEPARATOR . 'dir2');
 | 
					        $this->assertFileNotExists($dstDirName . DIRECTORY_SEPARATOR . 'dir2');
 | 
				
			||||||
        $this->assertFileNotExists($dstDirName . DIRECTORY_SEPARATOR . 'dir3');
 | 
					        $this->assertFileNotExists($dstDirName . DIRECTORY_SEPARATOR . 'dir3');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function testFindDirectory()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $dirName = 'test_dir';
 | 
				
			||||||
 | 
					        $this->createFileStructure([
 | 
				
			||||||
 | 
					            $dirName => [
 | 
				
			||||||
 | 
					               'test_sub_dir' => [
 | 
				
			||||||
 | 
					                    'file_1.txt' => 'sub dir file 1 content',
 | 
				
			||||||
 | 
					                ],
 | 
				
			||||||
 | 
					                'second_sub_dir' => [
 | 
				
			||||||
 | 
					                    'file_1.txt' => 'sub dir file 2 content',
 | 
				
			||||||
 | 
					                ],
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					        ]);
 | 
				
			||||||
 | 
					        $basePath = $this->testFilePath;
 | 
				
			||||||
 | 
					        $dirName = $basePath . DIRECTORY_SEPARATOR . $dirName;
 | 
				
			||||||
 | 
					        $expectedFiles = [
 | 
				
			||||||
 | 
					            $dirName . DIRECTORY_SEPARATOR . 'test_sub_dir',
 | 
				
			||||||
 | 
					            $dirName . DIRECTORY_SEPARATOR . 'second_sub_dir'
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $foundFiles = FileHelper::findDirectory($dirName);
 | 
				
			||||||
 | 
					        sort($expectedFiles);
 | 
				
			||||||
 | 
					        sort($foundFiles);
 | 
				
			||||||
 | 
					        $this->assertEquals($expectedFiles, $foundFiles);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $expectedFiles = [
 | 
				
			||||||
 | 
					            $dirName . DIRECTORY_SEPARATOR . 'second_sub_dir'
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					        $options = [
 | 
				
			||||||
 | 
					            'filter' => function ($path) {
 | 
				
			||||||
 | 
					                return 'second_sub_dir' == basename($path);
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					        $foundFiles = FileHelper::findDirectory($dirName, $options);
 | 
				
			||||||
 | 
					        sort($expectedFiles);
 | 
				
			||||||
 | 
					        sort($foundFiles);
 | 
				
			||||||
 | 
					        $this->assertEquals($expectedFiles, $foundFiles);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user