: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
unset($this->listeners[$cmd][$i]);
* Trigger binded functions
* @param string $cmd binded command name
* @param array $vars variables to pass to listeners
* @param array $errors array into which the error is written
public function trigger($cmd, $vars, &$errors)
if (!empty($this->listeners[$cmd])) {
foreach ($this->listeners[$cmd] as $handler) {
$_res = call_user_func_array($handler, $vars);
if ($_res && is_array($_res)) {
$_err = !empty($_res['error'])? $_res['error'] : (!empty($_res['warning'])? $_res['warning'] : null);
$errors = array_merge($errors, $_err);
$errors[] = (string)$_err;
throw new elFinderTriggerException();
* Return true if command exists
* @param string command name
* @author Dmitry (dio) Levashov
public function commandExists($cmd)
return $this->loaded && isset($this->commands[$cmd]) && method_exists($this, $cmd);
* Return root - file's owner (public func of volume())
* @param string file hash
* @return elFinderVolumeDriver
public function getVolume($hash)
return $this->volume($hash);
* Return command required arguments info
* @param string command name
* @author Dmitry (dio) Levashov
public function commandArgsList($cmd)
if ($this->commandExists($cmd)) {
$list = $this->commands[$cmd];
private function session_expires()
if (!$last = $this->session->get(':LAST_ACTIVITY')) {
$this->session->set(':LAST_ACTIVITY', time());
if (($this->timeout > 0) && (time() - $last > $this->timeout)) {
$this->session->set(':LAST_ACTIVITY', time());
* Exec command and return result
* @param string $cmd command name
* @param array $args command arguments
* @throws elFinderAbortException|Exception
* @author Dmitry (dio) Levashov
public function exec($cmd, $args)
// set error handler of WARNING, NOTICE
set_error_handler('elFinder::phpErrorHandler', E_WARNING | E_NOTICE | E_USER_WARNING | E_USER_NOTICE);
// set current request args
self::$currentArgs = $args;
return array('error' => $this->error(self::ERROR_CONF, self::ERROR_CONF_NO_VOL));
if ($this->session_expires()) {
return array('error' => $this->error(self::ERROR_SESSION_EXPIRES));
if (!$this->commandExists($cmd)) {
return array('error' => $this->error(self::ERROR_UNKNOWN_CMD));
$args['reqid'] = preg_replace('[^0-9a-fA-F]', '', !empty($args['reqid']) ? $args['reqid'] : (!empty($_SERVER['HTTP_X_ELFINDERREQID']) ? $_SERVER['HTTP_X_ELFINDERREQID'] : ''));
return array('error' => 0);
// make flag file and set self::$abortCheckFile
$this->abort(array('makeFile' => $args['reqid']));
if (!empty($args['mimes']) && is_array($args['mimes'])) {
foreach ($this->volumes as $id => $v) {
$this->volumes[$id]->setMimesFilter($args['mimes']);
// regist shutdown function as fallback
register_shutdown_function(array($this, 'itemAutoUnlock'));
// detect destination dirHash and volume
$dst = !empty($args['target']) ? $args['target'] : (!empty($args['dst']) ? $args['dst'] : '');
$dstVolume = $this->volume($dst);
} else if (isset($args['targets']) && is_array($args['targets']) && isset($args['targets'][0])) {
$dst = $args['targets'][0];
$dstVolume = $this->volume($dst);
if ($dstVolume && ($_stat = $dstVolume->file($dst)) && !empty($_stat['phash'])) {
} else if ($cmd === 'open') {
// for initial open without args `target`
$dstVolume = $this->default;
$dst = $dstVolume->defaultPath();
// call pre handlers for this command
$args['sessionCloseEarlier'] = isset($this->sessionUseCmds[$cmd]) ? false : $this->sessionCloseEarlier;
if (!empty($this->listeners[$cmd . '.pre'])) {
foreach ($this->listeners[$cmd . '.pre'] as $handler) {
$_res = call_user_func_array($handler, array($cmd, &$args, $this, $dstVolume));
if (!empty($_res['preventexec'])) {
$result = array('error' => true);
if ($cmd === 'upload' && !empty($args['node'])) {
$result['callback'] = array(
if (!empty($_res['results']) && is_array($_res['results'])) {
$result = array_merge($result, $_res['results']);
// unlock session data for multiple access
if ($this->sessionCloseEarlier && $args['sessionCloseEarlier']) {
elFinder::$sessionClosed = true;
if (substr(PHP_OS, 0, 3) === 'WIN') {
elFinder::extendTimeLimit(300);
if (!is_array($result)) {
$result = $this->$cmd($args);
} catch (elFinderAbortException $e) {
$error_res = json_decode($e->getMessage());
$message = isset($error_res->error->message) ? $error_res->error->message : $e->getMessage();
'error' => htmlspecialchars($message),
if ($this->throwErrorOnExec) {
if ($dst && $dstVolume && (!empty($result['added']) || !empty($result['removed']))) {
foreach ($this->volumes as $volume) {
$removed = $volume->removed();
if (!isset($result['removed'])) {
$result['removed'] = array();
$result['removed'] = array_merge($result['removed'], $removed);
if (!$changeDst && $dst && $dstVolume && $volume === $dstVolume) {
$added = $volume->added();
if (!isset($result['added'])) {
$result['added'] = array();
$result['added'] = array_merge($result['added'], $added);
if (!$changeDst && $dst && $dstVolume && $volume === $dstVolume) {
$volume->resetResultStat();
if ($dstDir = $dstVolume->dir($dst)) {
if (!isset($result['changed'])) {
$result['changed'] = array();
$result['changed'][] = $dstDir;
// call handlers for this command
if (!empty($this->listeners[$cmd])) {
foreach ($this->listeners[$cmd] as $handler) {
if (call_user_func_array($handler, array($cmd, &$result, $args, $this, $dstVolume))) {
// handler return true to force sync client after command completed
// replace removed files info with removed files hashes
if (!empty($result['removed'])) {
foreach ($result['removed'] as $file) {
$removed[] = $file['hash'];
$result['removed'] = array_unique($removed);
// remove hidden files and filter files by mimetypes
if (!empty($result['added'])) {
$result['added'] = $this->filter($result['added']);
// remove hidden files and filter files by mimetypes
if (!empty($result['changed'])) {
$result['changed'] = $this->filter($result['changed']);
if ($this->toastMessages) {
$result['toasts'] = array_merge(((isset($result['toasts']) && is_array($result['toasts']))? $result['toasts'] : array()), $this->toastMessages);
if ($this->debug || !empty($args['debug'])) {
$result['debug'] = array(
'time' => $this->utime() - $this->time,
'memory' => (function_exists('memory_get_peak_usage') ? ceil(memory_get_peak_usage() / 1024) . 'Kb / ' : '') . ceil(memory_get_usage() / 1024) . 'Kb / ' . ini_get('memory_limit'),
'upload' => $this->uploadDebug,
'mountErrors' => $this->mountErrors
foreach ($this->volumes as $id => $volume) {
$result['debug']['volumes'][] = $volume->debug();
// remove sesstion var 'urlContentSaveIds'
if ($this->removeContentSaveIds) {
$urlContentSaveIds = $this->session->get('urlContentSaveIds', array());
foreach (array_keys($this->removeContentSaveIds) as $contentSaveId) {
if (isset($urlContentSaveIds[$contentSaveId])) {
unset($urlContentSaveIds[$contentSaveId]);
if ($urlContentSaveIds) {
$this->session->set('urlContentSaveIds', $urlContentSaveIds);
$this->session->remove('urlContentSaveIds');
foreach ($this->volumes as $volume) {
$volume->saveSessionCache();
if ($this->customData !== null) {
$result['customData'] = $this->customData ? json_encode($this->customData) : '';
if (!empty($result['debug'])) {
$result['debug']['backendErrors'] = elFinder::$phpErrors;
elFinder::$phpErrors = array();
if (!empty($result['callback'])) {
$result['callback']['json'] = json_encode($result);
$this->callback($result['callback']);
* @param string $hash file hash
* @author Dmitry (dio) Levashov
public function realpath($hash)
if (($volume = $this->volume($hash)) == false) {
return $volume->realpath($hash);
* @param string|array $key The key or data array
* @param mixed $val The value
* @return self ( elFinder instance )
public function setCustomData($key, $val = null)
foreach ($key as $k => $v) {
$this->customData[$k] = $v;
$this->customData[$key] = $val;
* @param string $key The key
* @return self ( elFinder instance )
public function removeCustomData($key)
$this->customData[$key] = null;
* Update sesstion value of a NetVolume option
* @param string $optionKey
public function updateNetVolumeOption($netKey, $optionKey, $val)
$netVolumes = $this->getNetVolumes();
if (is_string($netKey) && isset($netVolumes[$netKey]) && is_string($optionKey)) {
$netVolumes[$netKey][$optionKey] = $val;
$this->saveNetVolumes($netVolumes);
* remove of session var "urlContentSaveIds"
public function removeUrlContentSaveId($id)
$this->removeContentSaveIds[$id] = true;
* Return network volumes config.
* @author Dmitry (dio) Levashov
protected function getNetVolumes()
if ($data = $this->session->get('netvolume', array())) {
* Save network volumes config.
* @param array $volumes volumes config
* @author Dmitry (dio) Levashov
protected function saveNetVolumes($volumes)
$this->session->set('netvolume', $volumes);
* @param string $key netvolume key
* @param object $volume volume driver instance
protected function removeNetVolume($key, $volume)
$netVolumes = $this->getNetVolumes();
if (is_object($volume) && method_exists($volume, 'netunmount')) {
$res = $volume->netunmount($netVolumes, $key);
$volume->clearSessionCache();
if (is_string($key) && isset($netVolumes[$key])) {
unset($netVolumes[$key]);
$this->saveNetVolumes($netVolumes);
* Get plugin instance & set to $this->plugins
* @param string $name Plugin name (dirctory name)
* @param array $opts Plugin options (optional)
* @return object | bool Plugin object instance Or false
protected function getPluginInstance($name, $opts = array())
$key = strtolower($name);
if (!isset($this->plugins[$key])) {