: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
$result = array('files' => $result);
$result['warning'] = $errors;
* Return file info (used by client "places" ui)
* @param array $args command arguments
* @throws elFinderAbortException
* @author Dmitry Levashov
protected function info($args)
if ($args['compare'] && count($args['targets']) === 1) {
$compare = intval($args['compare']);
$hash = $args['targets'][0];
if ($volume = $this->volume($hash)) {
$standby = (int)$volume->getOption('plStandby');
if (($syncCheckFunc = $volume->getOption('syncCheckFunc')) && is_callable($syncCheckFunc)) {
$_compare = call_user_func_array($syncCheckFunc, array($volume->realpath($hash), $standby, $compare, $volume, $this));
if ($_compare !== false) {
$sleep = max(1, (int)$volume->getOption('tsPlSleep'));
$limit = max(1, $standby / $sleep) + 1;
elFinder::extendTimeLimit(30 + $sleep);
$volume->clearstatcache();
if (($info = $volume->file($hash)) != false) {
if ($info['ts'] != $compare) {
foreach ($args['targets'] as $hash) {
elFinder::checkAborted();
if (($volume = $this->volume($hash)) != false
&& ($info = $volume->file($hash)) != false) {
$info['path'] = $volume->path($hash);
$result = array('files' => $files);
if (!is_null($compare)) {
$result['compare'] = strval($compare);
* Return image dimensions
* @param array $args command arguments
* @throws ImagickException
* @throws elFinderAbortException
* @author Dmitry (dio) Levashov
protected function dim($args)
$target = $args['target'];
if (($volume = $this->volume($target)) != false) {
if ($dim = $volume->dimensions($target, $args)) {
if (is_array($dim) && isset($dim['dim'])) {
$res = array('dim' => $dim);
if ($subImgLink = $volume->getSubstituteImgLink($target, explode('x', $dim))) {
$res['url'] = $subImgLink;
* @param array command arguments
* @throws ImagickException
* @throws elFinderAbortException
* @author Dmitry (dio) Levashov
* @author Alexey Sukhotin
protected function resize($args)
$target = $args['target'];
$width = (int)$args['width'];
$height = (int)$args['height'];
$degree = (int)$args['degree'];
$quality = (int)$args['quality'];
if (($volume = $this->volume($target)) == false
|| ($file = $volume->file($target)) == false) {
return array('error' => $this->error(self::ERROR_RESIZE, '#' . $target, self::ERROR_FILE_NOT_FOUND));
if ($mode !== 'rotate' && ($width < 1 || $height < 1)) {
return array('error' => $this->error(self::ERROR_RESIZESIZE));
return ($file = $volume->resize($target, $width, $height, $x, $y, $mode, $bg, $degree, $quality))
? (!empty($file['losslessRotate']) ? $file : array('changed' => array($file)))
: array('error' => $this->error(self::ERROR_RESIZE, $volume->path($target), $volume->error()));
* @param array $args command arguments
protected function url($args)
$target = $args['target'];
$options = isset($args['options']) ? $args['options'] : array();
if (($volume = $this->volume($target)) != false) {
if (!$volume->commandDisabled('url')) {
$url = $volume->getContentUrl($target, $options);
return $url ? array('url' => $url) : array();
* Output callback result with JavaScript that control elFinder
* or HTTP redirect to callbackWindowURL
* @param array command arguments
* @throws elFinderAbortException
protected function callback($args)
$checkReg = '/[^a-zA-Z0-9;._-]/';
$node = (isset($args['node']) && !preg_match($checkReg, $args['node'])) ? $args['node'] : '';
$json = (isset($args['json']) && json_decode($args['json'])) ? $args['json'] : '{}';
$bind = (isset($args['bind']) && !preg_match($checkReg, $args['bind'])) ? $args['bind'] : '';
$done = (!empty($args['done']));
if ($done || !$this->callbackWindowURL) {
$trigger = 'elf.trigger(\'' . $bind . '\', data);';
$triggerdone = 'elf.trigger(\'' . $bind . 'done\');';
$triggerfail = 'elf.trigger(\'' . $bind . 'fail\', data);';
$trigger = $triggerdone = $triggerfail = '';
$origin = isset($_SERVER['HTTP_ORIGIN'])? str_replace('\'', '\\\'', $_SERVER['HTTP_ORIGIN']) : '*';
var w = window.opener || window.parent || window,
window.open("about:blank","_self").close();
var elf = w.document.getElementById(\'' . $node . '\').elfinder;
var data = ' . $json . ';
data.warning && elf.error(data.warning);
data.removed && data.removed.length && elf.remove(data);
data.added && data.added.length && elf.add(data);
data.changed && data.changed.length && elf.change(data);
w.postMessage && w.postMessage(JSON.stringify({bind:\'' . $bind . '\',data:' . $json . '}), \'' . $origin . '\');
var msg = document.getElementById(\'msg\');
msg.style.display = \'inline\';
$out = '<!DOCTYPE html><html lang="en"><head><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2"><script>' . $script . '</script></head><body><h2 id="msg" style="display:none;"><a href="#">Please close this tab.</a></h2><script>go();</script></body></html>';
header('Content-Type: text/html; charset=utf-8');
header('Content-Length: ' . strlen($out));
header('Cache-Control: private');
header('Pragma: no-cache');
$url = $this->callbackWindowURL;
$url .= ((strpos($url, '?') === false) ? '?' : '&')
. '&node=' . rawurlencode($node)
. (($json !== '{}') ? ('&json=' . rawurlencode($json)) : '')
. ($bind ? ('&bind=' . rawurlencode($bind)) : '')
header('Location: ' . $url);
throw new elFinderAbortException();
* Error handler for send toast message to client side
protected function toastErrorHandler($errno, $errstr, $errfile, $errline)
if (!(error_reporting() & $errno)) {
$toast['mode'] = $this->toastParams['mode'];
$toast['msg'] = $this->toastParams['prefix'] . $errstr;
$this->toastMessages[] = $toast;
* PHP error handler, catch error types only E_WARNING | E_NOTICE | E_USER_WARNING | E_USER_NOTICE
public static function phpErrorHandler($errno, $errstr, $errfile, $errline)
$base = dirname(__FILE__) . DIRECTORY_SEPARATOR;
if (!(error_reporting() & $errno)) {
// Do not report real path
if (strpos($errfile, $base) === 0) {
$errfile = str_replace($base, '', $errfile);
} else if ($pos = strrpos($errfile, '/vendor/')) {
$errfile = substr($errfile, $pos + 1);
$errfile = basename($errfile);
elFinder::$phpErrors[] = "WARNING: $errstr in $errfile line $errline.";
elFinder::$phpErrors[] = "NOTICE: $errstr in $errfile line $errline.";
elFinder::$phpErrors[] = "STRICT: $errstr in $errfile line $errline.";
case E_RECOVERABLE_ERROR:
elFinder::$phpErrors[] = "RECOVERABLE_ERROR: $errstr in $errfile line $errline.";
if (defined('E_DEPRECATED')) {
elFinder::$phpErrors[] = "DEPRECATED: $errstr in $errfile line $errline.";
/***************************************************************************/
/***************************************************************************/
* Return root - file's owner
* @param string file hash
* @return elFinderVolumeDriver|boolean (false)
* @author Dmitry (dio) Levashov
protected function volume($hash)
foreach ($this->volumes as $id => $v) {
if (strpos('' . $hash, $id) === 0) {
return $this->volumes[$id];
* Return files info array
* @param array $data one file info or files info
* @author Dmitry (dio) Levashov
protected function toArray($data)
return isset($data['hash']) || !is_array($data) ? array($data) : $data;
* Return fils hashes list
* @param array $files files info
* @author Dmitry (dio) Levashov
protected function hashes($files)
foreach ($files as $file) {
* Remove from files list hidden files and files with required mime types
* @param array $files files info
* @author Dmitry (dio) Levashov
protected function filter($files)
foreach ($files as $i => $file) {
if (isset($file['hash'])) {
if (isset($exists[$file['hash']]) || !empty($file['hidden']) || !$this->default->mimeAccepted($file['mime'])) {
$exists[$file['hash']] = true;
return array_values($files);
protected function utime()
$time = explode(" ", microtime());
return (double)$time[1] + (double)$time[0];
* Return Network mount volume unique ID
* @param array $netVolumes Saved netvolumes array
* @param string $prefix Id prefix
protected function getNetVolumeUniqueId($netVolumes = null, $prefix = 'nm')
if (is_null($netVolumes)) {
$netVolumes = $this->getNetVolumes();
foreach ($netVolumes as $vOps) {
if (isset($vOps['id']) && strpos($vOps['id'], $prefix) === 0) {
$ids[$vOps['id']] = true;
while (isset($ids[$prefix . ++$i]) && $i < 10000) ;
protected function itemLocked($hash)
if (!elFinder::$commonTempPath) {
$lock = elFinder::$commonTempPath . DIRECTORY_SEPARATOR . self::filenameDecontaminate($hash) . '.lock';
if (file_exists($lock)) {
if (filemtime($lock) + $this->itemLockExpire < time()) {
* @param array|string $hashes
* @param boolean $autoUnlock
protected function itemLock($hashes, $autoUnlock = true)
if (!elFinder::$commonTempPath) {