/** * Creates and returns folder for concrete file. * @param string $filename base name of file for which must be returned folder. * @return string folder name of the directory for the `$filename`. * It is NOT full path to directory, only last part (folder name). */ public function getFileFolder($filename) { $rootDirectory = rtrim($this->getRootDirectory(), '\\/'); if (false === ($rootDirChilds = @scandir($rootDirectory, SCANDIR_SORT_NONE))) { throw new InvalidConfigException("Unable to scan directory: {$rootDirectory}"); } $rootDirChilds = array_filter($rootDirChilds, function ($dir) use($rootDirectory) { return $dir !== '.' && $dir !== '..' && is_dir("{$rootDirectory}/{$dir}"); }); if (count($rootDirChilds) > 1) { shuffle($rootDirChilds); } $fsFilename = FileSystemHelper::encodeFilename($filename); $dir = false; foreach ($rootDirChilds as $dir) { switch (true) { case FileSystemHelper::fileExists("{$rootDirectory}/{$dir}", $fsFilename, false): // no break // no break case FileSystemHelper::directoryFilesCount("{$rootDirectory}/{$dir}") > $this->maxSubdirFilesCount: $dir = false; break; default: break 2; } } // generate new subdir name while ($dir === false) { $dir = $this->generateRandomString($this->subdirsLength); $dirpath = "{$rootDirectory}/{$dir}"; if (FileSystemHelper::fileExists($rootDirectory, $dir, false)) { $dir = false; } elseif (!FileSystemHelper::createDirectory($dirpath, $this->makeDirMode, false)) { throw new InvalidConfigException("Cannot create directory: {$dirpath}"); } } return $dir; }