: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
$target = $args['target'];
$download = !empty($args['download']);
$onetime = !empty($args['onetime']);
//$h304 = 'HTTP/1.1 304 Not Modified';
$h403 = 'HTTP/1.0 403 Access Denied';
$a403 = array('error' => 'Access Denied', 'header' => $h403, 'raw' => true);
$h404 = 'HTTP/1.0 404 Not Found';
$a404 = array('error' => 'File not found', 'header' => $h404, 'raw' => true);
$tmpdir = elFinder::$commonTempPath;
if (!$tmpdir || !is_file($tmpf = $tmpdir . DIRECTORY_SEPARATOR . 'ELF' . $target)) {
$GLOBALS['elFinderTempFiles'][$tmpf] = true;
if ($file = json_decode(file_get_contents($tmpf), true)) {
$src = base64_decode($file['file']);
if (!is_file($src) || !($fp = fopen($src, 'rb'))) {
if (strpos($src, $tmpdir) === 0) {
$GLOBALS['elFinderTempFiles'][$src] = true;
$file['size'] = filesize($src);
if (($volume = $this->volume($target)) == false) {
if ($volume->commandDisabled('file')) {
if (($file = $volume->file($target)) == false) {
if (!empty($_SERVER['HTTP_RANGE'])) {
$opts['httpheaders'] = array('Range: ' . $_SERVER['HTTP_RANGE']);
if (($fp = $volume->open($target, $opts)) == false) {
elFinder::checkAborted();
// allow change MIME type by 'file.pre' callback functions
$mime = isset($args['mime']) ? $args['mime'] : $file['mime'];
if ($download || $onetime) {
$dispInlineRegex = $volume->getOption('dispInlineRegex');
$inlineRegex = '#' . str_replace('#', '\\#', $dispInlineRegex) . '#';
preg_match($inlineRegex, '');
$inlineRegex = '#^(?:(?:image|text)|application/x-shockwave-flash$)#';
$disp = preg_match($inlineRegex, $mime) ? 'inline' : 'attachment';
$filenameEncoded = rawurlencode($file['name']);
if (strpos($filenameEncoded, '%') === false) { // ASCII only
$filename = 'filename="' . $file['name'] . '"';
$ua = isset($_SERVER['HTTP_USER_AGENT'])? $_SERVER['HTTP_USER_AGENT'] : '';
if (preg_match('/MSIE [4-8]/', $ua)) { // IE < 9 do not support RFC 6266 (RFC 2231/RFC 5987)
$filename = 'filename="' . $filenameEncoded . '"';
} elseif (strpos($ua, 'Chrome') === false && strpos($ua, 'Safari') !== false && preg_match('#Version/[3-5]#', $ua)) { // Safari < 6
$filename = 'filename="' . str_replace('"', '', $file['name']) . '"';
} else { // RFC 6266 (RFC 2231/RFC 5987)
$filename = 'filename*=UTF-8\'\'' . $filenameEncoded;
if ($args['cpath'] && $args['reqid']) {
setcookie('elfdl' . $args['reqid'], '1', 0, $args['cpath']);
'Content-Type: ' . $mime,
'Content-Disposition: ' . $disp . '; ' . $filename,
'Content-Transfer-Encoding: binary',
'Content-Length: ' . $file['size'],
'Last-Modified: ' . gmdate('D, d M Y H:i:s T', $file['ts']),
// add cache control headers
if ($cacheHeaders = $volume->getOption('cacheHeaders')) {
$result['header'] = array_merge($result['header'], $cacheHeaders);
$xsendfile = $volume->getOption('xsendfile');
$info = stream_get_meta_data($fp);
if ($path = empty($info['uri']) ? null : $info['uri']) {
$basePath = rtrim($volume->getOption('xsendfilePath'), DIRECTORY_SEPARATOR);
$root = rtrim($volume->getRootPath(), DIRECTORY_SEPARATOR);
if (strpos($path, $root) === 0) {
$path = $basePath . substr($path, strlen($root));
$result['header'][] = $xsendfile . ': ' . $path;
$result['info']['xsendfile'] = $xsendfile;
// add "Content-Location" if file has url data
if (isset($file['url']) && $file['url'] && $file['url'] != 1) {
$result['header'][] = 'Content-Location: ' . $file['url'];
* @param array command arguments
* @throws elFinderAbortException
* @author Dmitry (dio) Levashov
protected function size($args)
foreach ($args['targets'] as $target) {
elFinder::checkAborted();
if (($volume = $this->volume($target)) == false
|| ($file = $volume->file($target)) == false
return array('error' => $this->error(self::ERROR_OPEN, '#' . $target));
$volRes = $volume->size($target);
$sizeInfo = array('size' => 0, 'fileCnt' => 0, 'dirCnt' => 0);
if (!empty($volRes['size'])) {
$sizeInfo['size'] = $volRes['size'];
$size += $volRes['size'];
if (!empty($volRes['files'])) {
$sizeInfo['fileCnt'] = $volRes['files'];
if (!empty($volRes['dirs'])) {
$sizeInfo['dirCnt'] = $volRes['dirs'];
$files += $sizeInfo['fileCnt'];
$dirs += $sizeInfo['dirCnt'];
$sizes[$target] = $sizeInfo;
} else if (is_numeric($volRes)) {
$files = $dirs = 'unknown';
return array('size' => $size, 'fileCnt' => $files, 'dirCnt' => $dirs, 'sizes' => $sizes);
* @param array command arguments
* @author Dmitry (dio) Levashov
protected function mkdir($args)
$target = $args['target'];
if ($name === '' && !$dirs) {
return array('error' => $this->error(self::ERROR_INV_PARAMS, 'mkdir'));
if (strpos($name,'..') !== false) {
return array('error' => $this->error('Invalid request', 'mkdir'));
if (($volume = $this->volume($target)) == false) {
return array('error' => $this->error(self::ERROR_MKDIR, $name, self::ERROR_TRGDIR_NOT_FOUND, '#' . $target));
$maxDirs = $volume->getOption('uploadMaxMkdirs');
if ($maxDirs && $maxDirs < count($dirs)) {
return array('error' => $this->error(self::ERROR_MAX_MKDIRS, $maxDirs));
foreach ($dirs as $dir) {
if(strpos($dir,'..') !== false){
return array('error' => $this->error('Invalid request', 'mkdir'));
$_names = explode('/', trim($dir, '/'));
foreach ($_names as $_key => $_name) {
if (!isset($tgt[$_name])) {
$res = $this->ensureDirsRecursively($volume, $target, $mkdirs);
'added' => $res['stats'],
'hashes' => $res['hashes']
$ret['warning'] = $this->error(self::ERROR_MKDIR, $res['error'][0], $volume->error());
return ($dir = $volume->mkdir($target, $name)) == false
? array('error' => $this->error(self::ERROR_MKDIR, $name, $volume->error()))
: array('added' => array($dir));
* @param array command arguments
* @author Dmitry (dio) Levashov
protected function mkfile($args)
$target = $args['target'];
$name = str_replace('..', '', $args['name']);
if (($volume = $this->volume($target)) == false) {
return array('error' => $this->error(self::ERROR_MKFILE, $name, self::ERROR_TRGDIR_NOT_FOUND, '#' . $target));
return ($file = $volume->mkfile($target, $name)) == false
? array('error' => $this->error(self::ERROR_MKFILE, $name, $volume->error()))
: array('added' => array($file));
* Rename file, Accept multiple items >= API 2.1031
* @throws elFinderAbortException
* @author Dmitry (dio) Levashov
protected function rename($args)
$target = $args['target'];
$query = (!empty($args['q']) && strpos($args['q'], '*') !== false) ? $args['q'] : '';
$targets = !empty($args['targets'])? $args['targets'] : false;
if (!($volume = $this->volume($target))) {
return array('error' => $this->error(self::ERROR_RENAME, '#' . $target, self::ERROR_FILE_NOT_FOUND));
if (strpos($name,'..') !== false) {
return array('error' => $this->error('Invalid request', 'rename'));
array_unshift($targets, $target);
foreach ($targets as $h) {
if ($rm = $volume->file($h)) {
if ($this->itemLocked($h)) {
$rm['realpath'] = $volume->realpath($h);
$res['error'] = array(self::ERROR_RENAME, join(', ', $notfounds), self::ERROR_FILE_NOT_FOUND);
array_push($res['error'], self::ERROR_LOCKED, join(', ', $locked));
$res['warning'] = array();
array_push($res['warning'], self::ERROR_RENAME, join(', ', $notfounds), self::ERROR_FILE_NOT_FOUND);
array_push($res['warning'], self::ERROR_LOCKED, join(', ', $locked));
$splits = elFinder::splitFileExtention($query);
if ($splits[1] && $splits[0] === '*') {
} else if (strlen($splits[0]) > 1) {
if (substr($splits[0], -1) === '*') {
$name = substr($splits[0], 0, strlen($splits[0]) - 1);
} else if (substr($splits[0], 0, 1) === '*') {
$name = substr($splits[0], 1);
if ($type !== 'normal') {
if (!empty($this->listeners['rename.pre'])) {
$_args = array('name' => $name);
foreach ($this->listeners['rename.pre'] as $handler) {
$_res = call_user_func_array($handler, array('rename', &$_args, $this, $volume));
if (!empty($_res['preventexec'])) {
if ($type === 'normal') {
$rname = $volume->uniqueName($volume->realpath($rm['phash']), $name, '', false);
if ($type === 'extention') {
$splits = elFinder::splitFileExtention($rm['name']);
$rname = $splits[0] . '.' . $name;
} else if ($type === 'prefix') {
$rname = $name . $rm['name'];
} else if ($type === 'suffix') {
$splits = elFinder::splitFileExtention($rm['name']);
$rname = $splits[0] . $name . ($splits[1] ? ('.' . $splits[1]) : '');
$rname = $volume->uniqueName($volume->realpath($rm['phash']), $rname, '', true);
if ($file = $volume->rename($rm['hash'], $rname)) {
$res['error'] = $this->error(self::ERROR_RENAME, join(', ', $errs), $volume->error());
array_push($res['warning'], self::ERROR_RENAME, join(', ', $errs), $volume->error());
$res['removed'] = $removed;
if (!($rm = $volume->file($target))) {
return array('error' => $this->error(self::ERROR_RENAME, '#' . $target, self::ERROR_FILE_NOT_FOUND));
if ($this->itemLocked($target)) {
return array('error' => $this->error(self::ERROR_LOCKED, $rm['name']));
$rm['realpath'] = $volume->realpath($target);
$file = $volume->rename($target, $name);
return array('error' => $this->error(self::ERROR_RENAME, $rm['name'], $volume->error()));
if ($file['hash'] !== $rm['hash']) {
return array('added' => array($file), 'removed' => array($rm));
return array('changed' => array($file));
* Duplicate file - create copy with "copy %d" suffix
* @param array $args command arguments
* @throws elFinderAbortException
* @author Dmitry (dio) Levashov
protected function duplicate($args)
$targets = is_array($args['targets']) ? $args['targets'] : array();
$suffix = empty($args['suffix']) ? 'copy' : $args['suffix'];
$this->itemLock($targets);
foreach ($targets as $target) {
elFinder::checkAborted();
if (($volume = $this->volume($target)) == false
|| ($src = $volume->file($target)) == false) {
$result['warning'] = $this->error(self::ERROR_COPY, '#' . $target, self::ERROR_FILE_NOT_FOUND);
if (($file = $volume->duplicate($target, $suffix)) == false) {
$result['warning'] = $this->error($volume->error());
* @param array command arguments
* @throws elFinderAbortException
* @author Dmitry (dio) Levashov
protected function rm($args)
$targets = is_array($args['targets']) ? $args['targets'] : array();
$result = array('removed' => array());
foreach ($targets as $target) {
elFinder::checkAborted();
if (($volume = $this->volume($target)) == false) {
$result['warning'] = $this->error(self::ERROR_RM, '#' . $target, self::ERROR_FILE_NOT_FOUND);
if ($this->itemLocked($target)) {
$rm = $volume->file($target);