: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
* Return fake path started from root dir
* @param string $path file path
* @author Dmitry (dio) Levashov
protected function _path($path)
return $this->rootName . ($path == $this->root ? '' : $this->separator . $this->_relpath($path));
* Return true if $path is children of $parent
* @param string $path path to check
* @param string $parent parent path
* @author Dmitry (dio) Levashov
protected function _inpath($path, $parent)
$real_path = $this->getFullPath($path, $cwd);
$real_parent = $this->getFullPath($parent, $cwd);
if ($real_path && $real_parent) {
return $real_path === $real_parent || strpos($real_path, rtrim($real_parent, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR) === 0;
/***************** file stat ********************/
* Return stat for given path.
* Stat contains following fields:
* - (int) size file size in b. required
* - (int) ts file modification time in unix time. required
* - (string) mime mimetype. required for folders, others - optionally
* - (bool) read read permissions. required
* - (bool) write write permissions. required
* - (bool) locked is object locked. optionally
* - (bool) hidden is object hidden. optionally
* - (string) alias for symlinks - link target path relative to root path. optionally
* - (string) target for symlinks - link target path. optionally
* If file does not exists - returns empty array or false.
* @param string $path file path
* @author Dmitry (dio) Levashov
protected function _stat($path)
if (!file_exists($path) && !is_link($path)) {
//Verifies the given path is the root or is inside the root. Prevents directory traveral.
if (!$this->_inpath($path, $this->root)) {
$stat['isowner'] = false;
if ($path != $this->root && is_link($path)) {
if (!$this->options['followSymLinks']) {
if (!($target = $this->readlink($path))
$stat['mime'] = 'symlink-broken';
$target = readlink($path);
$ostat = $this->getOwnerStat($lstat['uid'], $lstat['gid']);
$linkreadable = !empty($ostat['isowner']);
$stat['alias'] = $this->_path($target);
$stat['target'] = $target;
$readable = is_readable($path);
$size = sprintf('%u', filesize($path));
$stat['ts'] = filemtime($path);
$stat['perm'] = substr((string)decoct($fstat['mode']), -4);
$stat = array_merge($stat, $this->getOwnerStat($uid, $gid));
if (($dir = is_dir($path)) && $this->options['detectDirIcon']) {
$favicon = $path . DIRECTORY_SEPARATOR . $this->options['detectDirIcon'];
if ($this->URL && file_exists($favicon)) {
$stat['icon'] = $this->URL . str_replace(DIRECTORY_SEPARATOR, '/', substr($favicon, strlen($this->root) + 1));
if (!isset($stat['mime'])) {
$stat['mime'] = $dir ? 'directory' : $this->mimetype($path);
$stat['read'] = ($linkreadable || $readable) ? null : false;
$stat['write'] = is_writable($path) ? null : false;
if (is_null($stat['read'])) {
} else if (isset($size)) {
if ($this->options['statCorrector']) {
call_user_func_array($this->options['statCorrector'], array(&$stat, $path, $this->statOwner, $this));
* Get stat `owner`, `group` and `isowner` by `uid` and `gid`
* Sub-fuction of _stat() and _scandir()
protected function getOwnerStat($uid, $gid)
$names = array('uid' => array(), 'gid' => array());
if (is_callable('posix_getuid')) {
$phpuid = posix_getuid();
$stat['isowner'] = ($phpuid == $uid);
if (isset($names['uid'][$uid])) {
$stat['owner'] = $names['uid'][$uid];
} else if (is_callable('posix_getpwuid')) {
$pwuid = posix_getpwuid($uid);
$stat['owner'] = $names['uid'][$uid] = $pwuid['name'];
$stat['owner'] = $names['uid'][$uid] = $uid;
if (isset($names['gid'][$gid])) {
$stat['group'] = $names['gid'][$gid];
} else if (is_callable('posix_getgrgid')) {
$grgid = posix_getgrgid($gid);
$stat['group'] = $names['gid'][$gid] = $grgid['name'];
$stat['group'] = $names['gid'][$gid] = $gid;
* 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)
if (is_dir($path) && is_readable($path)) {
if (class_exists('FilesystemIterator', false)) {
$dirItr = new ParentIterator(
new RecursiveDirectoryIterator($path,
FilesystemIterator::SKIP_DOTS |
FilesystemIterator::CURRENT_AS_SELF |
(defined('RecursiveDirectoryIterator::FOLLOW_SYMLINKS') ?
RecursiveDirectoryIterator::FOLLOW_SYMLINKS : 0)
if ($dirItr->hasChildren()) {
$name = $dirItr->getSubPathName();
while ($dirItr->valid()) {
if (!$this->attr($path . DIRECTORY_SEPARATOR . $name, 'read', null, true)) {
$name = $dirItr->getSubPathName();
$path = strtr($path, array('[' => '\\[', ']' => '\\]', '*' => '\\*', '?' => '\\?'));
return (bool)glob(rtrim($path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . '*', GLOB_ONLYDIR);
* Return object width and height
* Usualy used for images, but can be realize for video etc...
* @param string $path file path
* @param string $mime file mime type
* @author Dmitry (dio) Levashov
protected function _dimensions($path, $mime)
return strpos($mime, 'image') === 0 && is_readable($path) && filesize($path) && ($s = getimagesize($path)) !== false
/******************** file/dir content *********************/
* Return symlink target file
* @param string $path link path
* @author Dmitry (dio) Levashov
protected function readlink($path)
if (!($target = readlink($path))) {
if (strpos($target, $this->systemRoot) !== 0) {
$target = $this->_joinPath(dirname($path), $target);
if (!file_exists($target)) {
* Return files list in directory.
* @param string $path dir path
* @throws elFinderAbortException
* @author Dmitry (dio) Levashov
protected function _scandir($path)
elFinder::checkAborted();
$dirWritable = is_writable($path);
$followSymLinks = $this->options['followSymLinks'];
$dirItr = new DirectoryIterator($path);
} catch (UnexpectedValueException $e) {
foreach ($dirItr as $file) {
$files[] = $fpath = $file->getPathname();
$stat['isowner'] = false;
if (!($target = $this->readlink($fpath))
$stat['mime'] = 'symlink-broken';
$target = readlink($_path);
$ostat = $this->getOwnerStat($lstat['uid'], $lstat['gid']);
$linkreadable = !empty($ostat['isowner']);
$stat['alias'] = $this->_path($target);
$stat['target'] = $target;
$stat['alias'] = $this->_path($target);
$stat['target'] = $target;
$stat['mime'] = $dir ? 'directory' : $this->mimetype($stat['alias']);
if (($dir = $file->isDir()) && $this->options['detectDirIcon']) {
$path = $file->getPathname();
$favicon = $path . DIRECTORY_SEPARATOR . $this->options['detectDirIcon'];
if ($this->URL && file_exists($favicon)) {
$stat['icon'] = $this->URL . str_replace(DIRECTORY_SEPARATOR, '/', substr($favicon, strlen($this->root) + 1));
$stat['mime'] = $dir ? 'directory' : $this->mimetype($fpath);
$size = sprintf('%u', $file->getSize());
$stat['ts'] = $file->getMTime();
if ($this->statOwner && !$linkreadable) {
$uid = $file->getOwner();
$gid = $file->getGroup();
$stat['perm'] = substr((string)decoct($file->getPerms()), -4);
$stat = array_merge($stat, $this->getOwnerStat($uid, $gid));
$stat['read'] = ($linkreadable || $file->isReadable()) ? null : false;
$stat['write'] = $file->isWritable() ? null : false;
$stat['locked'] = $dirWritable ? null : true;
if (is_null($stat['read'])) {
$stat['size'] = $dir ? 0 : $size;
if ($this->options['statCorrector']) {
call_user_func_array($this->options['statCorrector'], array(&$stat, $fpath, $this->statOwner, $this));
$cache[] = array($fpath, $stat);
} catch (RuntimeException $e) {
$cache = $this->convEncOut($cache, false);
$this->updateCache($d[0], $d[1]);
* Open file and return file pointer
* @param string $path file path
* @internal param bool $write open file for writing
* @author Dmitry (dio) Levashov
protected function _fopen($path, $mode = 'rb')
return fopen($path, $mode);
* @param resource $fp file pointer
* @author Dmitry (dio) Levashov
protected function _fclose($fp, $path = '')
return (is_resource($fp) && fclose($fp));
/******************** 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);
chmod($path, $this->options['dirMode']);
* 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);
if (($fp = fopen($path, 'w'))) {
chmod($path, $this->options['fileMode']);
* @param string $source file to link to
* @param string $targetDir folder to create link in
* @param string $name symlink name
* @author Dmitry (dio) Levashov
protected function _symlink($source, $targetDir, $name)
return $this->localFileSystemSymlink($source, $this->_joinPath($targetDir, $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)
$mtime = filemtime($source);
$target = $this->_joinPath($targetDir, $name);
if ($ret = copy($source, $target)) {
isset($this->options['keepTimestamp']['copy']) && $mtime && touch($target, $mtime);
* Move file into another parent dir.
* Return new file path or false.
* @param string $source source file path