: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
$stat['perm'] = trim($stat['perm']);
// if not exists owner in LS ftp ==> isowner = true
// if is defined as option : 'owner' => true isowner = true
// if exist owner in LS ftp and 'owner' => False isowner = result of owner(file) == user(logged with ftp)
$owner_computed = isset($stat['owner']) ? ($this->options['owner'] ? true : ($stat['owner'] == $this->options['user'])) : true;
$read = ($owner_computed && $perm[0][0]) || $perm[1][0] || $perm[2][0];
$stat['read'] = $stat['mime'] == 'directory' ? $read && (($owner_computed && $perm[0][2]) || $perm[1][2] || $perm[2][2]) : $read;
$stat['write'] = ($owner_computed && $perm[0][1]) || $perm[1][1] || $perm[2][1];
if ($this->options['statOwner']) {
$stat['isowner'] = $owner_computed;
unset($stat['owner'], $stat['group'], $stat['perm']);
* Return true if path is dir and has at least one childs directory
* @param string $path dir path
* @author Dmitry (dio) Levashov
protected function _subdirs($path)
foreach ($this->ftpRawList($path) 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);
$name = isset($info[8]) ? trim($info[8]) : '';
if ($name && $name !== '.' && $name !== '..' && substr(strtolower($info[0]), 0, 1) === 'd') {
* Return object width and height
* Ususaly used for images, but can be realize for video etc...
* @param string $path file path
* @param string $mime file mime type
* @throws ImagickException
* @throws elFinderAbortException
* @author Dmitry (dio) Levashov
protected function _dimensions($path, $mime)
if ($imgsize = $this->getImageSize($path, $mime)) {
$ret = array('dim' => $imgsize['dimensions']);
if (!empty($imgsize['url'])) {
$ret['url'] = $imgsize['url'];
/******************** file/dir content *********************/
* Return files list in directory.
* @param string $path dir path
* @author Dmitry (dio) Levashov
* @author Cem (DiscoFever)
protected function _scandir($path)
foreach ($this->ftpRawList($path) as $str) {
if (($stat = $this->parseRaw($str, $path, true))) {
$files[] = $this->_joinPath($path, $stat['name']);
* Open file and return file pointer
* @param string $path file path
* @throws elFinderAbortException
* @internal param bool $write open file for writing
* @author Dmitry (dio) Levashov
protected function _fopen($path, $mode = 'rb')
// try ftp stream wrapper
if ($this->options['mode'] === 'passive' && ini_get('allow_url_fopen')) {
$url = ($this->isFTPS ? 'ftps' : 'ftp') . '://' . $this->options['user'] . ':' . $this->options['pass'] . '@' . $this->options['host'] . ':' . $this->options['port'] . $path;
if (strtolower($mode[0]) === 'w') {
$context = stream_context_create(array('ftp' => array('overwrite' => true)));
$fp = fopen($url, $mode, false, $context);
$fp = fopen($url, $mode);
$local = $this->getTempFile($path);
$fp = fopen($local, 'wb');
$ret = ftp_nb_fget($this->connect, $fp, $path, FTP_BINARY);
while ($ret === FTP_MOREDATA) {
elFinder::extendTimeLimit();
$ret = ftp_nb_continue($this->connect);
if ($ret === FTP_FINISHED) {
$fp = fopen($local, $mode);
is_file($local) && unlink($local);
* @param resource $fp file pointer
* @author Dmitry (dio) Levashov
protected function _fclose($fp, $path = '')
is_resource($fp) && fclose($fp);
unlink($this->getTempFile($path));
/******************** file/dir manipulations *************************/
* Create dir and return created dir path or false on failed
* @param string $path parent dir path
* @param string $name new directory name
* @author Dmitry (dio) Levashov
protected function _mkdir($path, $name)
$path = $this->_joinPath($path, $name);
if (ftp_mkdir($this->connect, $path) === false) {
$this->options['dirMode'] && ftp_chmod($this->connect, $this->options['dirMode'], $path);
* Create file and return it's path or false on failed
* @param string $path parent dir path
* @param string $name new file name
* @author Dmitry (dio) Levashov
protected function _mkfile($path, $name)
$path = $this->_joinPath($path, $name);
$local = $this->getTempFile();
$res = touch($local) && ftp_put($this->connect, $path, $local, FTP_ASCII);
return $res ? $path : false;
* Create symlink. FTP driver does not support symlinks.
* @param string $target link target
* @param string $path symlink path
* @author Dmitry (dio) Levashov
protected function _symlink($target, $path, $name)
* Copy file into another file
* @param string $source source file path
* @param string $targetDir target directory path
* @param string $name new file name
* @author Dmitry (dio) Levashov
protected function _copy($source, $targetDir, $name)
$local = $this->getTempFile();
$target = $this->_joinPath($targetDir, $name);
if (ftp_get($this->connect, $local, $source, FTP_BINARY)
&& ftp_put($this->connect, $target, $local, $this->ftpMode($target))) {
* Move file into another parent dir.
* Return new file path or false.
* @param string $source source file path
* @param string $name file name
* @internal param string $target target dir path
* @author Dmitry (dio) Levashov
protected function _move($source, $targetDir, $name)
$target = $this->_joinPath($targetDir, $name);
return ftp_rename($this->connect, $source, $target) ? $target : false;
* @param string $path file path
* @author Dmitry (dio) Levashov
protected function _unlink($path)
return ftp_delete($this->connect, $path);
* @param string $path dir path
* @author Dmitry (dio) Levashov
protected function _rmdir($path)
return ftp_rmdir($this->connect, $path);
* Create new file and write into it from file pointer.
* Return new file path or false on error.
* @param resource $fp file pointer
* @param string $dir target dir path
* @param string $name file name
* @param array $stat file stat (required by some virtual fs)
* @author Dmitry (dio) Levashov
protected function _save($fp, $dir, $name, $stat)
$path = $this->_joinPath($dir, $name);
return ftp_fput($this->connect, $path, $fp, $this->ftpMode($path))
* @param string $path file path
* @throws elFinderAbortException
* @author Dmitry (dio) Levashov
protected function _getContents($path)
if (($fp = $this->_fopen($path))) {
$contents .= fread($fp, 8192);
$this->_fclose($fp, $path);
* Write a string to a file
* @param string $path file path
* @param string $content new file content
* @author Dmitry (dio) Levashov
protected function _filePutContents($path, $content)
$local = $this->getTempFile();
if (file_put_contents($local, $content, LOCK_EX) !== false
&& ($fp = fopen($local, 'rb'))) {
$file = $this->stat($this->convEncOut($path, false));
if (!empty($file['thash'])) {
$path = $this->decode($file['thash']);
$res = ftp_fput($this->connect, $path, $fp, $this->ftpMode($path));
file_exists($local) && unlink($local);
* Detect available archivers
* @throws elFinderAbortException
protected function _checkArchivers()
$this->archivers = $this->getArchivers();
protected function _chmod($path, $mode)
$modeOct = is_string($mode) ? octdec($mode) : octdec(sprintf("%04o", $mode));
return ftp_chmod($this->connect, $modeOct, $path);
* Extract files from archive
* @param string $path archive path
* @param array $arc archiver command and arguments (same as in $this->archivers)
* @throws elFinderAbortException
* @author Dmitry (dio) Levashov,
* @author Alexey Sukhotin
protected function _extract($path, $arc)
$basename = $this->_basename($path);
$localPath = $dir . DIRECTORY_SEPARATOR . $basename;
if (!ftp_get($this->connect, $localPath, $path, FTP_BINARY)) {
$this->rmdirRecursive($dir);
$this->unpackArchive($localPath, $arc);
// find symlinks and check extracted items
$checkRes = $this->checkExtractItems($dir);
if ($checkRes['symlinks']) {
$this->rmdirRecursive($dir);
return $this->setError(array_merge($this->error, array(elFinder::ERROR_ARC_SYMLINKS)));
$this->archiveSize = $checkRes['totalSize'];
if ($checkRes['rmNames']) {
foreach ($checkRes['rmNames'] as $name) {
$this->addError(elFinder::ERROR_SAVE, $name);
$filesToProcess = self::listFilesInDirectory($dir, true);
// no files - extract error ?
if (empty($filesToProcess)) {
$this->rmdirRecursive($dir);
if ($this->options['maxArcFilesSize'] > 0 && $this->options['maxArcFilesSize'] < $this->archiveSize) {
$this->rmdirRecursive($dir);
return $this->setError(elFinder::ERROR_ARC_MAXSIZE);
$extractTo = $this->extractToNewdir; // 'auto', ture or false
// archive contains one item - extract in archive dir
$src = $dir . DIRECTORY_SEPARATOR . $filesToProcess[0];
if (($extractTo === 'auto' || !$extractTo) && count($filesToProcess) === 1 && is_file($src)) {
$name = $filesToProcess[0];
} else if ($extractTo === 'auto' || $extractTo) {
// for several files - create new directory
// create unique name for directory
$splits = elFinder::splitFileExtention(basename($path));
$test = $this->_joinPath(dirname($path), $name);
if ($this->stat($test)) {
$name = $this->uniqueName(dirname($path), $name, '-', false);
if ($name !== '' && is_file($src)) {
$result = $this->_joinPath(dirname($path), $name);
if (!ftp_put($this->connect, $result, $src, FTP_BINARY)) {
$this->rmdirRecursive($dir);
$dstDir = $this->_dirname($path);
if (is_dir($src) && $name) {
$target = $this->_joinPath($dstDir, $name);
$_stat = $this->_stat($target);
if (!$this->options['copyJoin']) {
if ($_stat['mime'] === 'directory') {