: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
if (!$_stat && (!$dstDir = $this->_mkdir($dstDir, $name))) {
$this->rmdirRecursive($dir);
foreach ($filesToProcess as $name) {
$name = rtrim($name, DIRECTORY_SEPARATOR);
$src = $dir . DIRECTORY_SEPARATOR . $name;
$target = $this->_joinPath($this->_joinPath($dstDir, $p), $name);
$_stat = $this->_stat($target);
if (!$this->options['copyJoin']) {
if ($_stat['mime'] === 'directory') {
if (!$_stat && (!$target = $this->_mkdir($this->_joinPath($dstDir, $p), $name))) {
$this->rmdirRecursive($dir);
$target = $this->_joinPath($dstDir, $name);
if (!ftp_put($this->connect, $target, $src, FTP_BINARY)) {
$this->rmdirRecursive($dir);
$this->rmdirRecursive($dir);
is_dir($dir) && $this->rmdirRecursive($dir);
return $result ? $result : false;
* Create archive and return its path
* @param string $dir target dir
* @param array $files files names list
* @param string $name archive name
* @param array $arc archiver options
* @throws elFinderAbortException
* @author Dmitry (dio) Levashov,
* @author Alexey Sukhotin
protected function _archive($dir, $files, $name, $arc)
$tmpDir = $this->tempDir();
if (!$this->ftp_download_files($dir, $files, $tmpDir)) {
$this->rmdirRecursive($tmpDir);
$remoteArchiveFile = false;
if ($path = $this->makeArchive($tmpDir, $files, $name, $arc)) {
$remoteArchiveFile = $this->_joinPath($dir, $name);
if (!ftp_put($this->connect, $remoteArchiveFile, $path, FTP_BINARY)) {
$remoteArchiveFile = false;
if (!$this->rmdirRecursive($tmpDir)) {
return $remoteArchiveFile;
* Create writable temporary directory and return path to it.
* @return string path to the new temporary directory or false in case of error.
private function tempDir()
$tempPath = tempnam($this->tmp, 'elFinder');
$this->setError(elFinder::ERROR_CREATING_TEMP_DIR, $this->tmp);
$success = unlink($tempPath);
$this->setError(elFinder::ERROR_CREATING_TEMP_DIR, $this->tmp);
$success = mkdir($tempPath, 0700, true);
$this->setError(elFinder::ERROR_CREATING_TEMP_DIR, $this->tmp);
* Gets an array of absolute remote FTP paths of files and
* folders in $remote_directory omitting symbolic links.
* @param $remote_directory string remote FTP path to scan for file and folders recursively
* @param $targets array Array of target item. `null` is to get all of items
* @return array of elements each of which is an array of two elements:
* <li>$item['path'] - absolute remote FTP path</li>
* <li>$item['type'] - either 'f' for file or 'd' for directory</li>
protected function ftp_scan_dir($remote_directory, $targets = null)
$buff = $this->ftpRawList($remote_directory);
if ($targets && is_array($targets)) {
$targets = array_flip($targets);
foreach ($buff as $str) {
$info = preg_split("/\s+/", $str, 9);
if (!isset($this->ftpOsUnix)) {
$this->ftpOsUnix = !preg_match('/\d/', substr($info[0], 0, 1));
$info = $this->normalizeRawWindows($str);
$type = substr($info[0], 0, 1);
if ($name !== '.' && $name !== '..' && (!$targets || isset($targets[$name]))) {
case 'l' : //omit symbolic links
$remote_file_path = $this->_joinPath($remote_directory, $name);
$item['path'] = $remote_file_path;
$item['type'] = 'd'; // normal file
$items = array_merge($items, $this->ftp_scan_dir($remote_file_path));
$remote_file_path = $this->_joinPath($remote_directory, $name);
$item['path'] = $remote_file_path;
$item['type'] = 'f'; // normal file
* Downloads specified files from remote directory
* if there is a directory among files it is downloaded recursively (omitting symbolic links).
* @param $remote_directory string remote FTP path to a source directory to download from.
* @param array $files list of files to download from remote directory.
* @param $dest_local_directory string destination folder to store downloaded files.
* @return bool true on success and false on failure.
private function ftp_download_files($remote_directory, array $files, $dest_local_directory)
$contents = $this->ftp_scan_dir($remote_directory, $files);
$this->setError(elFinder::ERROR_FTP_DOWNLOAD_FILE, $remote_directory);
$remoteDirLen = strlen($remote_directory);
foreach ($contents as $item) {
$relative_path = substr($item['path'], $remoteDirLen);
$local_path = $dest_local_directory . DIRECTORY_SEPARATOR . $relative_path;
$success = mkdir($local_path);
$success = ftp_get($this->connect, $local_path, $item['path'], FTP_BINARY);
$this->setError(elFinder::ERROR_FTP_DOWNLOAD_FILE, $remote_directory);
* Delete local directory recursively.
* @param $dirPath string to directory to be erased.
* @return bool true on success and false on failure.
private function deleteDir($dirPath)
$success = unlink($dirPath);
foreach (array_reverse(elFinderVolumeFTP::listFilesInDirectory($dirPath, false)) as $path) {
$path = $dirPath . DIRECTORY_SEPARATOR . $path;
} else if (is_dir($path)) {
$success = unlink($path);
$success = rmdir($dirPath);
$this->setError(elFinder::ERROR_RM, $dirPath);
* Returns array of strings containing all files and folders in the specified local directory.
* @return array array of files and folders names relative to the $path
* or an empty array if the directory $path is empty,
* false if $path is not a directory or does not exist.
* @internal param string $path path to directory to scan.
private static function listFilesInDirectory($dir, $omitSymlinks, $prefix = '')
$excludes = array(".", "..");
$files = self::localScandir($dir);
foreach ($files as $file) {
if (!in_array($file, $excludes)) {
$path = $dir . DIRECTORY_SEPARATOR . $file;
$result[] = $prefix . $file;
} else if (is_dir($path)) {
$result[] = $prefix . $file . DIRECTORY_SEPARATOR;
$subs = elFinderVolumeFTP::listFilesInDirectory($path, $omitSymlinks, $prefix . $file . DIRECTORY_SEPARATOR);
$result = array_merge($result, $subs);
$result[] = $prefix . $file;