: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
* Assign elFinder session wrapper object
* @param $session elFinderSessionInterface
public function setSession($session)
$this->session = $session;
* Get elFinder sesson wrapper object
* @return object The session object
public function getSession()
* Save session cache data
* Calls this function before umount this volume on elFinder::exec()
public function saveSessionCache()
$this->session->set($this->id, $this->sessionCache);
* Return debug info for client
* @author Dmitry (dio) Levashov
'name' => strtolower(substr(get_class($this), strlen('elfinderdriver'))),
'mimeDetect' => $this->mimeDetect,
'imgLib' => $this->imgLib
* @param string $hash file or folder hash to chmod
* @param string $mode octal string representing new permissions
public function chmod($hash, $mode)
if ($this->commandDisabled('chmod')) {
return $this->setError(elFinder::ERROR_PERM_DENIED);
if (!($file = $this->file($hash))) {
return $this->setError(elFinder::ERROR_FILE_NOT_FOUND);
if (!$this->options['allowChmodReadOnly']) {
if (!$this->attr($this->decode($hash), 'write', null, ($file['mime'] === 'directory'))) {
return $this->setError(elFinder::ERROR_PERM_DENIED, $file['name']);
$path = $this->decode($hash);
if ($this->convEncOut(!$this->_chmod($this->convEncIn($path), $mode))) {
return $this->setError(elFinder::ERROR_PERM_DENIED, $file['name']);
if ($path == $this->root) {
$this->rootModified = true;
if ($file = $this->stat($path)) {
if ($file['mime'] === 'directory' && $write !== $file['write']) {
foreach ($this->getScandir($path) as $stat) {
if ($this->mimeAccepted($stat['mime'])) {
return $this->setError(elFinder::ERROR_FILE_NOT_FOUND);
* stat a file or folder for elFinder cmd exec
* @param string $hash file or folder hash to chmod
public function fstat($hash)
$path = $this->decode($hash);
return $this->stat($path);
* Clear PHP stat cache & all of inner stat caches
public function clearstatcache()
* Clear inner stat caches for target hash
public function clearcaches($hash = null)
$path = $this->decode($hash);
unset($this->cache[$path], $this->dirsCache[$path]);
* Return true if volume available for read or write,
* @throws elFinderAbortException
* @author Dmitry (dio) Levashov
* @author Alexey Sukhotin
public function mount(array $opts)
$this->options = array_merge($this->options, $opts);
if (!isset($this->options['path']) || $this->options['path'] === '') {
return $this->setError('Path undefined.');
return $this->setError('Session wrapper dose not set. Need to `$volume->setSession(elFinderSessionInterface);` before mount.');
if (!($this->session instanceof elFinderSessionInterface)) {
return $this->setError('Session wrapper instance must be "elFinderSessionInterface".');
if (!empty($this->options['driverId'])) {
$this->driverId = $this->options['driverId'];
$this->id = $this->driverId . (!empty($this->options['id']) ? $this->options['id'] : elFinder::$volumesCnt++) . '_';
$this->root = $this->normpathCE($this->options['path']);
$this->separator = isset($this->options['separator']) ? $this->options['separator'] : DIRECTORY_SEPARATOR;
if (!empty($this->options['winHashFix'])) {
$this->separatorForHash = ($this->separator !== '/') ? '/' : '';
$this->systemRoot = isset($this->options['systemRoot']) ? $this->options['systemRoot'] : $this->separator;
$this->ARGS = $_SERVER['REQUEST_METHOD'] === 'POST' ? $_POST : $_GET;
$argInit = !empty($this->ARGS['init']);
if (!is_bool($this->needOnline)) {
$this->session->set($this->id, array());
$this->sessionCache = $this->session->get($this->id, array());
// default file attribute
'read' => isset($this->options['defaults']['read']) ? !!$this->options['defaults']['read'] : true,
'write' => isset($this->options['defaults']['write']) ? !!$this->options['defaults']['write'] : true,
'locked' => isset($this->options['defaults']['locked']) ? !!$this->options['defaults']['locked'] : false,
'hidden' => isset($this->options['defaults']['hidden']) ? !!$this->options['defaults']['hidden'] : false
$this->attributes[] = array(
'pattern' => '~^' . preg_quote($this->separator) . '$~',
if (!empty($this->options['attributes']) && is_array($this->options['attributes'])) {
foreach ($this->options['attributes'] as $a) {
// attributes must contain pattern and at least one rule
if (!empty($a['pattern']) || (is_array($a) && count($a) > 1)) {
$this->attributes[] = $a;
if (!empty($this->options['accessControl']) && is_callable($this->options['accessControl'])) {
$this->access = $this->options['accessControl'];
$this->today = mktime(0, 0, 0, date('m'), date('d'), date('Y'));
$this->yesterday = $this->today - 86400;
if (!empty($this->options['encoding']) && strtoupper($this->options['encoding']) !== 'UTF-8') {
$this->encoding = $this->options['encoding'];
// check some options is arrays
$this->uploadAllow = isset($this->options['uploadAllow']) && is_array($this->options['uploadAllow'])
? $this->options['uploadAllow']
$this->uploadDeny = isset($this->options['uploadDeny']) && is_array($this->options['uploadDeny'])
? $this->options['uploadDeny']
$this->options['uiCmdMap'] = (isset($this->options['uiCmdMap']) && is_array($this->options['uiCmdMap']))
? $this->options['uiCmdMap']
if (is_string($this->options['uploadOrder'])) { // telephat_mode on, compatibility with 1.x
$parts = explode(',', isset($this->options['uploadOrder']) ? $this->options['uploadOrder'] : 'deny,allow');
$this->uploadOrder = array(trim($parts[0]), trim($parts[1]));
} else { // telephat_mode off
$this->uploadOrder = !empty($this->options['uploadOrder']) ? $this->options['uploadOrder'] : array('deny', 'allow');
if (!empty($this->options['uploadMaxSize'])) {
$this->uploadMaxSize = elFinder::getIniBytes('', $this->options['uploadMaxSize']);
// Set maximum to PHP_INT_MAX
if (!defined('PHP_INT_MAX')) {
define('PHP_INT_MAX', 2147483647);
if ($this->uploadMaxSize < 1 || $this->uploadMaxSize > PHP_INT_MAX) {
$this->uploadMaxSize = PHP_INT_MAX;
// Set to get maximum size to 50% of memory_limit
$memLimit = elFinder::getIniBytes('memory_limit') / 2;
$this->getMaxSize = empty($this->options['getMaxSize']) ? $memLimit : min($memLimit, elFinder::getIniBytes('', $this->options['getMaxSize']));
$this->disabled = isset($this->options['disabled']) && is_array($this->options['disabled'])
? array_values(array_diff($this->options['disabled'], array('open'))) // 'open' is required
$this->cryptLib = $this->options['cryptLib'];
$this->mimeDetect = $this->options['mimeDetect'];
// find available mimetype detect method
$regexp = '/text\/x\-(php|c\+\+)/';
if (class_exists('finfo', false)) {
$tmpFileInfo = explode(';', finfo_file(finfo_open(FILEINFO_MIME), __FILE__));
if ($tmpFileInfo && preg_match($regexp, array_shift($tmpFileInfo))) {
if (function_exists('mime_content_type')) {
$_mimetypes = explode(';', mime_content_type(__FILE__));
if (preg_match($regexp, array_shift($_mimetypes))) {
$auto_types[] = 'mime_content_type';
$auto_types[] = 'internal';
$type = strtolower($this->options['mimeDetect']);
if (!in_array($type, $auto_types)) {
$type = array_shift($auto_types);
$this->mimeDetect = $type;
if ($this->mimeDetect == 'finfo') {
$this->finfo = finfo_open(FILEINFO_MIME);
} else if ($this->mimeDetect == 'internal' && !elFinderVolumeDriver::$mimetypesLoaded) {
// load mimes from external file for mimeDetect == 'internal'
// based on Alexey Sukhotin idea and patch: http://elrte.org/redmine/issues/163
// file must be in file directory or in parent one
elFinderVolumeDriver::loadMimeTypes(!empty($this->options['mimefile']) ? $this->options['mimefile'] : '');
$this->rootName = empty($this->options['alias']) ? $this->basenameCE($this->root) : $this->options['alias'];
// This get's triggered if $this->root == '/' and alias is empty.
// Maybe modify _basename instead?
if ($this->rootName === '') $this->rootName = $this->separator;
$this->_checkArchivers();
$root = $this->stat($this->root);
return $this->setError('Root folder does not exist.');
if (!$root['read'] && !$root['write']) {
return $this->setError('Root folder has not read and write permissions.');
// check startPath - path to open by default instead of root
$startPath = $this->options['startPath'] ? $this->normpathCE($this->options['startPath']) : '';
$start = $this->stat($startPath);
&& $start['mime'] == 'directory'
&& empty($start['hidden'])
&& $this->inpathCE($startPath, $this->root)) {
$this->startPath = $startPath;
if (substr($this->startPath, -1, 1) == $this->options['separator']) {
$this->startPath = substr($this->startPath, 0, -1);
$this->options['URL'] = '';
$this->options['tmbURL'] = '';
$this->options['tmbPath'] = '';
array_unshift($this->attributes, array(
$this->treeDeep = $this->options['treeDeep'] > 0 ? (int)$this->options['treeDeep'] : 1;
$this->tmbSize = $this->options['tmbSize'] > 0 ? (int)$this->options['tmbSize'] : 48;
$this->URL = $this->options['URL'];
if ($this->URL && preg_match("|[^/?&=]$|", $this->URL)) {
$dirUrlOwn = strtolower($this->options['dirUrlOwn']);
if ($dirUrlOwn === 'auto') {
$this->options['dirUrlOwn'] = $this->URL ? false : true;
} else if ($dirUrlOwn === 'hide') {
$this->options['dirUrlOwn'] = 'hide';
$this->options['dirUrlOwn'] = (bool)$this->options['dirUrlOwn'];
$this->tmbURL = !empty($this->options['tmbURL']) ? $this->options['tmbURL'] : '';
if ($this->tmbURL && $this->tmbURL !== 'self' && preg_match("|[^/?&=]$|", $this->tmbURL)) {
$this->nameValidator = !empty($this->options['acceptedName']) && (is_string($this->options['acceptedName']) || is_callable($this->options['acceptedName']))
? $this->options['acceptedName']
$this->dirnameValidator = !empty($this->options['acceptedDirname']) && (is_callable($this->options['acceptedDirname']) || (is_string($this->options['acceptedDirname']) && preg_match($this->options['acceptedDirname'], '') !== false))
? $this->options['acceptedDirname']
// enabling archivers['create'] with options['useRemoteArchive']
if ($this->options['useRemoteArchive'] && empty($this->archivers['create']) && $this->getTempPath()) {
$_archivers = $this->getArchivers();
$this->archivers['create'] = $_archivers['create'];
// manual control archive types to create
if (!empty($this->options['archiveMimes']) && is_array($this->options['archiveMimes'])) {
foreach ($this->archivers['create'] as $mime => $v) {
if (!in_array($mime, $this->options['archiveMimes'])) {
unset($this->archivers['create'][$mime]);
if (!empty($this->options['archivers']['create']) && is_array($this->options['archivers']['create'])) {
foreach ($this->options['archivers']['create'] as $mime => $conf) {
if (strpos($mime, 'application/') === 0
&& !isset($this->archivers['create'][$mime])) {
$this->archivers['create'][$mime] = $conf;
if (!empty($this->options['archivers']['extract']) && is_array($this->options['archivers']['extract'])) {
foreach ($this->options['archivers']['extract'] as $mime => $conf) {
if (strpos($mime, 'application/') === 0
&& !isset($this->archivers['extract'][$mime])) {
$this->archivers['extract'][$mime] = $conf;
if (!empty($this->options['noSessionCache']) && is_array($this->options['noSessionCache'])) {
foreach ($this->options['noSessionCache'] as $_key) {
$this->sessionCaching[$_key] = false;
unset($this->sessionCache[$_key]);
if ($this->sessionCaching['subdirs']) {
if (!isset($this->sessionCache['subdirs'])) {
$this->sessionCache['subdirs'] = array();
// Normalize disabled (array_merge`for type array of JSON)
$this->disabled = array_values(array_unique($this->disabled));
if ($this->options['syncMinMs'] !== 0) {
$this->options['syncMinMs'] = max($this->options[$this->options['syncChkAsTs'] ? 'tsPlSleep' : 'lsPlSleep'] * 1000, intval($this->options['syncMinMs']));
// ` copyJoin` is required for the trash function
if ($this->options['trashHash'] && empty($this->options['copyJoin'])) {
$this->options['trashHash'] = '';
if (elFinder::$tmpLinkPath && !$this->options['tmpLinkPath']) {
if (is_writeable(elFinder::$tmpLinkPath)) {
$this->options['tmpLinkPath'] = elFinder::$tmpLinkPath;
elFinder::$tmpLinkPath = '';
if ($this->options['tmpLinkPath'] && is_writable($this->options['tmpLinkPath'])) {
$this->tmpLinkPath = realpath($this->options['tmpLinkPath']);
} else if (!$this->tmpLinkPath && $this->tmbURL && $this->tmbPath) {
$this->tmpLinkPath = $this->tmbPath;
$this->options['tmpLinkUrl'] = $this->tmbURL;
} else if (!$this->options['URL'] && is_writable('../files/.tmb')) {
$this->tmpLinkPath = realpath('../files/.tmb');
$this->options['tmpLinkUrl'] = '';
if (!elFinder::$tmpLinkPath) {
elFinder::$tmpLinkPath = $this->tmpLinkPath;
elFinder::$tmpLinkUrl = '';
if (elFinder::$tmpLinkUrl && !$this->options['tmpLinkUrl']) {
$this->options['tmpLinkUrl'] = elFinder::$tmpLinkUrl;
if ($this->options['tmpLinkUrl']) {
$this->tmpLinkUrl = $this->options['tmpLinkUrl'];
if ($this->tmpLinkPath && !$this->tmpLinkUrl) {
while ($cur !== $this->systemRoot && strpos($this->tmpLinkPath, $cur) !== 0) {
list($req) = explode('?', $_SERVER['REQUEST_URI']);