: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
$this->options['app_key'] = ELFINDER_DROPBOX_APPKEY;
return $this->setError('Required option "app_key" is undefined.');
if (empty($this->options['app_secret'])) {
if (defined('ELFINDER_DROPBOX_APPSECRET') && ELFINDER_DROPBOX_APPSECRET) {
$this->options['app_secret'] = ELFINDER_DROPBOX_APPSECRET;
return $this->setError('Required option "app_secret" is undefined.');
if (isset($this->options['tokens']) && is_array($this->options['tokens']) && !empty($this->options['tokens']['access_token'])) {
$this->options['access_token'] = $this->options['tokens']['access_token'];
if (!$this->options['access_token']) {
return $this->setError('Required option "access_token" or "refresh_token" is undefined.');
// make net mount key for network mount
$aToken = $this->options['access_token'];
$this->netMountKey = md5($aToken . '-' . $this->options['path']);
if ($this->needOnline && !$this->service) {
$app = new DropboxApp($this->options['app_key'], $this->options['app_secret'], $aToken);
$this->service = new Dropbox($app);
$this->service->getCurrentAccount();
} catch (DropboxClientException $e) {
$errors[] = 'Dropbox error: ' . $e->getMessage();
$errors[] = $e->getMessage();
if ($this->needOnline && !$this->service) {
$errors[] = 'Dropbox Service could not be loaded.';
return $this->setError($errors);
$this->options['path'] = strtolower($this->options['path']);
if ($this->options['path'] == 'root') {
$this->options['path'] = '/';
$this->root = $this->options['path'] = $this->_normpath($this->options['path']);
if (empty($this->options['alias'])) {
$this->options['alias'] = sprintf($this->options['aliasFormat'], ($this->options['path'] === '/') ? 'Root' : $this->_basename($this->options['path']));
if (!empty($this->options['netkey'])) {
elFinder::$instance->updateNetVolumeOption($this->options['netkey'], 'alias', $this->options['alias']);
$this->rootName = $this->options['alias'];
if (!empty($this->options['tmpPath'])) {
if ((is_dir($this->options['tmpPath']) || mkdir($this->options['tmpPath'])) && is_writable($this->options['tmpPath'])) {
$this->tmp = $this->options['tmpPath'];
if (!$this->tmp && ($tmp = elFinder::getStaticVar('commonTempPath'))) {
// This driver dose not support `syncChkAsTs`
$this->options['syncChkAsTs'] = false;
// 'lsPlSleep' minmum 10 sec
$this->options['lsPlSleep'] = max(10, $this->options['lsPlSleep']);
// enable command archive
$this->options['useRemoteArchive'] = true;
* Configure after successfull mount.
* @throws elFinderAbortException
protected function configure()
// fallback of $this->tmp
if (!$this->tmp && $this->tmbPathWritable) {
$this->tmp = $this->tmbPath;
if ($this->isMyReload()) {
//$this->_db_getDirectoryData(false);
/*********************************************************************/
/*********************************************************************/
* Close opened connection.
* @param string $path dir path
protected function cacheDir($path)
$this->dirsCache[$path] = [];
$res = $this->service->listFolder($path, $this->FETCH_OPTIONS);
$items = $res->getItems()->all();
foreach ($items as $raw) {
if ($stat = $this->_db_parseRaw($raw)) {
$mountPath = $this->_joinPath($path, $stat['name']);
$stat = $this->updateCache($mountPath, $stat);
if (empty($stat['hidden']) && $path !== $mountPath) {
if (!$hasDir && $stat['mime'] === 'directory') {
$this->dirsCache[$path][] = $mountPath;
if (isset($this->sessionCache['subdirs'])) {
$this->sessionCache['subdirs'][$path] = $hasDir;
return $this->dirsCache[$path];
* Recursive files search.
* @param string $path dir path
* @param string $q search string
* @throws elFinderAbortException
protected function doSearch($path, $q, $mimes)
if (!empty($this->doSearchCurrentQuery['matchMethod']) || $mimes) {
// has custom match method or mimes, use elFinderVolumeDriver::doSearch()
return parent::doSearch($path, $q, $mimes);
$timeout = $this->options['searchTimeout'] ? $this->searchStart + $this->options['searchTimeout'] : 0;
$searchRes = $this->service->search($path, $q, ['start' => 0, 'max_results' => 1000]);
$items = $searchRes->getItems();
$more = $searchRes->hasMoreItems();
if ($timeout && $timeout < time()) {
$this->setError(elFinder::ERROR_SEARCH_TIMEOUT, $this->_path($path));
$searchRes = $this->service->search($path, $q, ['start' => $searchRes->getCursor(), 'max_results' => 1000]);
$more = $searchRes->hasMoreItems();
$items = $items->merge($searchRes->getItems());
foreach ($items as $raw) {
if ($stat = $this->_db_parseRaw($raw->getMetadata())) {
$stat = $this->updateCache($stat['path'], $stat);
if (empty($stat['hidden'])) {
* Copy file/recursive copy dir only in current volume.
* Return new file path or false.
* @param string $src source path
* @param string $dst destination dir path
* @param string $name new file name (optionaly)
* @throws elFinderAbortException
protected function copy($src, $dst, $name)
$srcStat = $this->stat($src);
$target = $this->_joinPath($dst, $name);
$tgtStat = $this->stat($target);
if ($srcStat['mime'] === 'directory') {
return parent::copy($src, $dst, $name);
if ($res = $this->_copy($src, $dst, $name)) {
$this->added[] = $this->stat($target);
* Remove file/ recursive remove dir.
* @param string $path file path
* @param bool $force try to remove even if file locked
* @throws elFinderAbortException
protected function remove($path, $force = false, $recursive = false)
$stat = $this->stat($path);
$stat['realpath'] = $path;
return $this->setError(elFinder::ERROR_RM, $this->_path($path), elFinder::ERROR_FILE_NOT_FOUND);
if (!$force && !empty($stat['locked'])) {
return $this->setError(elFinder::ERROR_LOCKED, $this->_path($path));
if ($stat['mime'] == 'directory') {
if (!$recursive && !$this->_rmdir($path)) {
return $this->setError(elFinder::ERROR_RM, $this->_path($path));
if (!$recursive && !$this->_unlink($path)) {
return $this->setError(elFinder::ERROR_RM, $this->_path($path));
$this->removed[] = $stat;
* Create thumnbnail and return it's URL on success.
* @param string $path file path
* @throws ImagickException
* @throws elFinderAbortException
protected function createTmb($path, $stat)
if (!$stat || !$this->canCreateTmb($path, $stat)) {
$name = $this->tmbname($stat);
$tmb = $this->tmbPath . DIRECTORY_SEPARATOR . $name;
// copy image into tmbPath so some drivers does not store files on local fs
if (!$data = $this->_db_getThumbnail($path)) {
if (!file_put_contents($tmb, $data)) {
$tmbSize = $this->tmbSize;
if (($s = getimagesize($tmb)) == false) {
/* If image smaller or equal thumbnail size - just fitting to thumbnail square */
if ($s[0] <= $tmbSize && $s[1] <= $tmbSize) {
$result = $this->imgSquareFit($tmb, $tmbSize, $tmbSize, 'center', 'middle', $this->options['tmbBgColor'], 'png');
if ($this->options['tmbCrop']) {
/* Resize and crop if image bigger than thumbnail */
if (!(($s[0] > $tmbSize && $s[1] <= $tmbSize) || ($s[0] <= $tmbSize && $s[1] > $tmbSize)) || ($s[0] > $tmbSize && $s[1] > $tmbSize)) {
$result = $this->imgResize($tmb, $tmbSize, $tmbSize, true, false, 'png');
if ($result && ($s = getimagesize($tmb)) != false) {
$x = $s[0] > $tmbSize ? intval(($s[0] - $tmbSize) / 2) : 0;
$y = $s[1] > $tmbSize ? intval(($s[1] - $tmbSize) / 2) : 0;
$result = $this->imgCrop($tmb, $tmbSize, $tmbSize, $x, $y, 'png');
$result = $this->imgResize($tmb, $tmbSize, $tmbSize, true, true, 'png');
$result = $this->imgSquareFit($tmb, $tmbSize, $tmbSize, 'center', 'middle', $this->options['tmbBgColor'], 'png');
* Return thumbnail file name for required file.
* @param array $stat file stat
protected function tmbname($stat)
$name = $this->driverId . '_';
if (isset($this->options['tokens']) && is_array($this->options['tokens'])) {
$name .= $this->options['tokens']['uid'];
return $name . md5($stat['iid']) . $stat['ts'] . '.png';
* Return content URL (for netmout volume driver)
* If file.url == 1 requests from JavaScript client with XHR.
* @param string $hash file hash
* @param array $options options array
public function getContentUrl($hash, $options = [])
if (!empty($options['onetime']) && $this->options['onetimeUrl']) {
return parent::getContentUrl($hash, $options);
if (!empty($options['temporary'])) {
// try make temporary file
$url = parent::getContentUrl($hash, $options);
$file = $this->file($hash);
if (($file = $this->file($hash)) !== false && (!$file['url'] || $file['url'] == 1)) {
$path = $this->decode($hash);
$res = $this->service->postToAPI('/sharing/list_shared_links', ['path' => $path, 'direct_only' => true])->getDecodedBody();
if ($res && !empty($res['links'])) {
foreach ($res['links'] as $link) {
if (isset($link['link_permissions'])
&& isset($link['link_permissions']['requested_visibility'])
&& $link['link_permissions']['requested_visibility']['.tag'] === $this->options['publishPermission']['requested_visibility']) {
$res = $this->service->postToAPI('/sharing/create_shared_link_with_settings', ['path' => $path, 'settings' => $this->options['publishPermission']])->getDecodedBody();
if (isset($res['url'])) {
$url = str_replace('www.dropbox.com', 'dl.dropboxusercontent.com', $url);
$url = str_replace('?dl=0', '', $url);
} catch (DropboxClientException $e) {
return $this->setError('Dropbox error: ' . $e->getMessage());
* Return debug info for client.
if (!empty($this->options['netkey']) && isset($this->options['tokens']) && !empty($this->options['tokens']['uid'])) {
$res['Dropbox uid'] = $this->options['tokens']['uid'];
$res['access_token'] = $this->options['tokens']['access_token'];
/*********************** paths/urls *************************/
* Return parent directory path.
* @param string $path file path
protected function _dirname($path)
list($dirname) = $this->_db_splitPath($path);
* @param string $path file path
protected function _basename($path)
list(, $basename) = $this->_db_splitPath($path);
* Join dir name and file name and retur full path.
* @author Dmitry (dio) Levashov
protected function _joinPath($dir, $name)
return rtrim($dir, '/') . '/' . strtolower($name);
* Return normalized path, this works the same as os.path.normpath() in Python.
* @param string $path path
protected function _normpath($path)
return '/' . ltrim($path, '/');
* Return file path related to root dir.
* @param string $path file path