: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
: $this->setError(elFinder::ERROR_NOT_DIR);
* Return directory content or false on error
* @param string $hash file hash
* @author Dmitry (dio) Levashov
public function scandir($hash)
if (($dir = $this->dir($hash)) == false) {
$path = $this->decode($hash);
? $this->getScandir($path)
: $this->setError(elFinder::ERROR_PERM_DENIED)) {
if ($this->sessionCaching['subdirs'] && isset($this->sessionCache['subdirs'][$path])) {
$dirs = $this->sessionCache['subdirs'][$path];
if ($dirs !== null || (isset($dir['dirs']) && $dir['dirs'] != 1)) {
if ($dirs || $this->subdirs($hash)) {
$this->updateCache($path, $dir);
* Return dir files names list
* @param string $hash file hash
* @author Dmitry (dio) Levashov
public function ls($hash, $intersect = null)
if (($dir = $this->dir($hash)) == false || !$dir['read']) {
$path = $this->decode($hash);
$check = array_flip($intersect);
foreach ($this->getScandir($path) as $stat) {
if (empty($stat['hidden']) && (!$check || isset($check[$stat['name']])) && $this->mimeAccepted($stat['mime'])) {
$list[$stat['hash']] = $stat['name'];
* Return subfolders for required folder or false on error
* @param string $hash folder hash or empty string to get tree from root folder
* @param int $deep subdir deep
* @param string $exclude dir hash which subfolders must be exluded from result, required to not get stat twice on cwd subfolders
* @author Dmitry (dio) Levashov
public function tree($hash = '', $deep = 0, $exclude = '')
$path = $hash ? $this->decode($hash) : $this->root;
if (($dir = $this->stat($path)) == false || $dir['mime'] != 'directory') {
$dirs = $this->gettree($path, $deep > 0 ? $deep - 1 : $this->treeDeep - 1, $exclude ? $this->decode($exclude) : null);
array_unshift($dirs, $dir);
* Return part of dirs tree from required dir up to root dir
* @param string $hash directory hash
* @param bool|null $lineal only lineal parents
* @throws elFinderAbortException
* @author Dmitry (dio) Levashov
public function parents($hash, $lineal = false)
if (($current = $this->dir($hash)) == false) {
// checks 3rd param `$until` (elFinder >= 2.1.24)
$path = $this->decode($hash);
while ($path && $path != $this->root) {
elFinder::checkAborted();
$path = $this->dirnameCE($path);
if (!($stat = $this->stat($path)) || !empty($stat['hidden']) || !$stat['read']) {
array_unshift($tree, $stat);
foreach ($this->gettree($path, 0) as $dir) {
elFinder::checkAborted();
if (!isset($tree[$dir['hash']])) {
$tree[$dir['hash']] = $dir;
if ($until && $until === $this->encode($path)) {
return $tree ? array_values($tree) : array($current);
* Create thumbnail for required file and return its name or false on failed
* @throws ImagickException
* @throws elFinderAbortException
* @author Dmitry (dio) Levashov
public function tmb($hash)
$path = $this->decode($hash);
$stat = $this->stat($path);
if (isset($stat['tmb'])) {
$res = $stat['tmb'] == "1" ? $this->createTmb($path, $stat) : $stat['tmb'];
list($type) = explode('/', $stat['mime']);
$fallback = $this->options['resourcePath'] . DIRECTORY_SEPARATOR . strtolower($type) . '.png';
if (is_file($fallback)) {
$res = $this->tmbname($stat);
if (!copy($fallback, $this->tmbPath . DIRECTORY_SEPARATOR . $res)) {
// tmb garbage collection
if ($res && $this->options['tmbGcMaxlifeHour'] && $this->options['tmbGcPercentage'] > 0) {
$rand = mt_rand(1, 10000);
if ($rand <= $this->options['tmbGcPercentage'] * 100) {
register_shutdown_function(array('elFinder', 'GlobGC'), $this->tmbPath . DIRECTORY_SEPARATOR . '*.png', $this->options['tmbGcMaxlifeHour'] * 3600);
* Return file size / total directory size
* @param string file hash
* @throws elFinderAbortException
* @author Dmitry (dio) Levashov
public function size($hash)
return $this->countSize($this->decode($hash));
* Open file for reading and return file pointer
* @param string file hash
* @author Dmitry (dio) Levashov
public function open($hash)
if (($file = $this->file($hash)) == false
|| $file['mime'] == 'directory') {
// check extra option for network stream pointer
if (func_num_args() > 1) {
return $this->fopenCE($this->decode($hash), 'rb', $opts);
* @param Resource $fp file pointer
* @param string $hash file hash
* @author Dmitry (dio) Levashov
public function close($fp, $hash)
$this->fcloseCE($fp, $this->decode($hash));
* Create directory and return dir info
* @param string $dsthash destination directory hash
* @param string $name directory name
* @author Dmitry (dio) Levashov
public function mkdir($dsthash, $name)
if ($this->commandDisabled('mkdir')) {
return $this->setError(elFinder::ERROR_PERM_DENIED);
if (!$this->nameAccepted($name, true)) {
return $this->setError(elFinder::ERROR_INVALID_DIRNAME);
if (($dir = $this->dir($dsthash)) == false) {
return $this->setError(elFinder::ERROR_TRGDIR_NOT_FOUND, '#' . $dsthash);
$path = $this->decode($dsthash);
if (!$dir['write'] || !$this->allowCreate($path, $name, true)) {
return $this->setError(elFinder::ERROR_PERM_DENIED);
if (substr($name, 0, 1) === '/' || substr($name, 0, 1) === '\\') {
return $this->setError(elFinder::ERROR_INVALID_DIRNAME);
$dst = $this->joinPathCE($path, $name);
$stat = $this->isNameExists($dst);
return $this->setError(elFinder::ERROR_EXISTS, $name);
$mkpath = $this->convEncOut($this->_mkdir($this->convEncIn($path), $this->convEncIn($name)));
$this->updateSubdirsCache($path, true);
$this->updateSubdirsCache($mkpath, false);
return $mkpath ? $this->stat($mkpath) : false;
* Create empty file and return its info
* @param string $dst destination directory
* @param string $name file name
* @author Dmitry (dio) Levashov
public function mkfile($dst, $name)
if ($this->commandDisabled('mkfile')) {
return $this->setError(elFinder::ERROR_PERM_DENIED);
if (!$this->nameAccepted($name, false)) {
return $this->setError(elFinder::ERROR_INVALID_NAME);
if (substr($name, 0, 1) === '/' || substr($name, 0, 1) === '\\') {
return $this->setError(elFinder::ERROR_INVALID_DIRNAME);
$mimeByName = $this->mimetype($name, true);
if ($mimeByName && !$this->allowPutMime($mimeByName)) {
return $this->setError(elFinder::ERROR_UPLOAD_FILE_MIME, $name);
if (($dir = $this->dir($dst)) == false) {
return $this->setError(elFinder::ERROR_TRGDIR_NOT_FOUND, '#' . $dst);
$path = $this->decode($dst);
if (!$dir['write'] || !$this->allowCreate($path, $name, false)) {
return $this->setError(elFinder::ERROR_PERM_DENIED);
if ($this->isNameExists($this->joinPathCE($path, $name))) {
return $this->setError(elFinder::ERROR_EXISTS, $name);
if ($path = $this->convEncOut($this->_mkfile($this->convEncIn($path), $this->convEncIn($name)))) {
$res = $this->stat($path);
* Rename file and return file info
* @param string $hash file hash
* @param string $name new file name
* @throws elFinderAbortException
* @author Dmitry (dio) Levashov
public function rename($hash, $name)
if ($this->commandDisabled('rename')) {
return $this->setError(elFinder::ERROR_PERM_DENIED);
if (!($file = $this->file($hash))) {
return $this->setError(elFinder::ERROR_FILE_NOT_FOUND);
if ($name === $file['name']) {
if (!empty($this->options['netkey']) && !empty($file['isroot'])) {
// change alias of netmount root
$rootKey = $this->getRootstatCachekey();
if ($this->sessionCaching['rootstat']) {
unset($this->sessionCaching['rootstat'][$rootKey]);
if (elFinder::$instance->updateNetVolumeOption($this->options['netkey'], 'alias', $name)) {
$this->rootName = $this->options['alias'] = $name;
return $this->stat($this->root);
return $this->setError(elFinder::ERROR_TRGDIR_NOT_FOUND, $name);
if (!empty($file['locked'])) {
return $this->setError(elFinder::ERROR_LOCKED, $file['name']);
$isDir = ($file['mime'] === 'directory');
if (!$this->nameAccepted($name, $isDir)) {
return $this->setError($isDir ? elFinder::ERROR_INVALID_DIRNAME : elFinder::ERROR_INVALID_NAME);
$mimeByName = $this->mimetype($name, true);
if ($mimeByName && !$this->allowPutMime($mimeByName)) {
return $this->setError(elFinder::ERROR_UPLOAD_FILE_MIME, $name);
$path = $this->decode($hash);
$dir = $this->dirnameCE($path);
$stat = $this->isNameExists($this->joinPathCE($dir, $name));
return $this->setError(elFinder::ERROR_EXISTS, $name);
if (!$this->allowCreate($dir, $name, ($file['mime'] === 'directory'))) {
return $this->setError(elFinder::ERROR_PERM_DENIED);
$this->rmTmb($file); // remove old name tmbs, we cannot do this after dir move
if ($path = $this->convEncOut($this->_move($this->convEncIn($path), $this->convEncIn($dir), $this->convEncIn($name)))) {
return $this->stat($path);
* Create file copy with suffix "copy number" and return its info
* @param string $hash file hash
* @param string $suffix suffix to add to file name
* @throws elFinderAbortException
* @author Dmitry (dio) Levashov
public function duplicate($hash, $suffix = 'copy')
if ($this->commandDisabled('duplicate')) {
return $this->setError(elFinder::ERROR_COPY, '#' . $hash, elFinder::ERROR_PERM_DENIED);
if (($file = $this->file($hash)) == false) {
return $this->setError(elFinder::ERROR_COPY, elFinder::ERROR_FILE_NOT_FOUND);
$path = $this->decode($hash);
$dir = $this->dirnameCE($path);
$name = $this->uniqueName($dir, $file['name'], sprintf($this->options['duplicateSuffix'], $suffix));
if (!$this->allowCreate($dir, $name, ($file['mime'] === 'directory'))) {
return $this->setError(elFinder::ERROR_PERM_DENIED);
return ($path = $this->copy($path, $dir, $name)) == false
* On success return array with new file stat and with removed file hash (if existed file was replaced)
* @param Resource $fp file pointer
* @param string $dst destination folder hash
* @param string $tmpname file tmp name - required to detect mime type
* @param array $hashes exists files hash array with filename as key
* @throws elFinderAbortException
* @internal param string $src file name
* @author Dmitry (dio) Levashov
public function upload($fp, $dst, $name, $tmpname, $hashes = array())
if ($this->commandDisabled('upload')) {
return $this->setError(elFinder::ERROR_PERM_DENIED);
if (($dir = $this->dir($dst)) == false) {
return $this->setError(elFinder::ERROR_TRGDIR_NOT_FOUND, '#' . $dst);
if (empty($dir['write'])) {
return $this->setError(elFinder::ERROR_PERM_DENIED);
if (!$this->nameAccepted($name, false)) {
return $this->setError(elFinder::ERROR_INVALID_NAME);
if ($this->mimeDetect === 'internal') {
$mime = $this->mimetype($tmpname, $name);
$mime = $this->mimetype($tmpname, $name);
$mimeByName = $this->mimetype($name, true);
if ($mime === 'unknown') {
if (!$this->allowPutMime($mime) || ($mimeByName && !$this->allowPutMime($mimeByName))) {
return $this->setError(elFinder::ERROR_UPLOAD_FILE_MIME, '(' . $mime . ')');
$tmpsize = (int)sprintf('%u', filesize($tmpname));
if ($this->uploadMaxSize > 0 && $tmpsize > $this->uploadMaxSize) {