: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
// fallback of $this->tmp
if (!$this->tmp && $this->tmbPathWritable) {
$this->tmp = $this->tmbPath;
/*********************************************************************/
/*********************************************************************/
* Close opened connection.
* @author Dmitry (dio) Levashov
* Return fileinfo based on filename
* For item ID based path file system
* Please override if needed on each drivers.
* @param string $path file cache
* @throws elFinderAbortException
protected function isNameExists($path)
list(, $name, $parent) = $this->_bd_splitPath($path);
// We can not use it because the search of Box.com there is a time lag.
// ref. https://docs.box.com/reference#searching-for-content
// > Note: If an item is added to Box then it becomes accessible through the search endpoint after ten minutes.
* $url = self::API_URL.'/search?limit=1&offset=0&content_types=name&ancestor_folder_ids='.rawurlencode($pid)
* .'&query='.rawurlencode('"'.$name.'"')
* .'fields='.self::FETCHFIELDS;
* $raw = $this->_bd_fetch($url);
* if (is_array($raw) && count($raw)) {
* return $this->_bd_parseRaw($raw);
$phash = $this->encode($parent);
// do not recursive search
$searchExDirReg = $this->options['searchExDirReg'];
$this->options['searchExDirReg'] = '/.*/';
$search = $this->search($name, array(), $phash);
$this->options['searchExDirReg'] = $searchExDirReg;
if ($f['name'] !== $name) {
* @param string $path dir path
* @author Dmitry Levashov
protected function cacheDir($path)
$this->dirsCache[$path] = array();
$items = $this->_bd_query('0', $fetch_self = true); // get root directory with folder & files
list(, $itemId) = $this->_bd_splitPath($path);
$res = $this->_bd_query($itemId);
if ($stat = $this->_bd_parseRaw($raw)) {
$itemPath = $this->_joinPath($path, $raw->id);
$stat = $this->updateCache($itemPath, $stat);
if (empty($stat['hidden'])) {
if (!$hasDir && $stat['mime'] === 'directory') {
$this->dirsCache[$path][] = $itemPath;
if (isset($this->sessionCache['subdirs'])) {
$this->sessionCache['subdirs'][$path] = $hasDir;
return $this->dirsCache[$path];
* 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)
* @author Dmitry (dio) Levashov
protected function copy($src, $dst, $name)
if ($res = $this->_copy($src, $dst, $name)) {
$this->added[] = $this->stat($res);
return $this->setError(elFinder::ERROR_COPY, $this->_path($src));
* Remove file/ recursive remove dir.
* @param string $path file path
* @param bool $force try to remove even if file locked
* @throws elFinderAbortException
* @author Dmitry (dio) Levashov
protected function remove($path, $force = 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 (!$this->_rmdir($path)) {
return $this->setError(elFinder::ERROR_RM, $this->_path($path));
if (!$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
* @author Dmitry (dio) Levashov
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->_bd_getThumbnail($path)) {
// try get full contents as fallback
if (!$data = $this->_getContents($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
* @author Dmitry (dio) Levashov
protected function tmbname($stat)
return $this->tmbPrefix . $stat['rev'] . $stat['ts'] . '.png';
* @param object $raw data
protected function getSharedWebContentLink($raw)
if ($raw->shared_link->url) {
return sprintf('https://app.box.com/index.php?rm=box_download_shared_file&shared_name=%s&file_id=f_%s', basename($raw->shared_link->url), $raw->id);
} elseif ($raw->shared_link->download_url) {
return $raw->shared_link->download_url;
* @param string $hash file hash
* @param array $options options
public function getContentUrl($hash, $options = array())
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);
if (($file = $this->file($hash)) == false || !$file['url'] || $file['url'] == 1) {
$path = $this->decode($hash);
list(, $itemId) = $this->_bd_splitPath($path);
$params['shared_link']['access'] = 'open'; //open|company|collaborators
$url = self::API_URL . '/files/' . $itemId;
$curl = $this->_bd_prepareCurl(array(
CURLOPT_CUSTOMREQUEST => 'PUT',
CURLOPT_POSTFIELDS => json_encode($params),
$res = $this->_bd_curlExec($curl, true, array(
// The data is sent as JSON as per Box documentation.
'Content-Type: application/json',
if ($url = $this->getSharedWebContentLink($res)) {
/*********************** paths/urls *************************/
* Return parent directory path.
* @param string $path file path
* @author Dmitry (dio) Levashov
protected function _dirname($path)
list(, , $dirname) = $this->_bd_splitPath($path);
* @param string $path file path
* @author Dmitry (dio) Levashov
protected function _basename($path)
list(, $basename) = $this->_bd_splitPath($path);
* Join dir name and file name and retur full path.
* @author Dmitry (dio) Levashov
protected function _joinPath($dir, $name)
if (strval($dir) === '0') {
return $this->_normpath($dir . '/' . $name);
* Return normalized path, this works the same as os.path.normpath() in Python.
* @param string $path path
protected function _normpath($path)
if (DIRECTORY_SEPARATOR !== '/') {
$path = str_replace(DIRECTORY_SEPARATOR, '/', $path);
$path = '/' . ltrim($path, '/');
* Return file path related to root dir.
* @param string $path file path
* @author Dmitry (dio) Levashov
protected function _relpath($path)
* Convert path related to root dir into real path.
* @param string $path file path
* @author Dmitry (dio) Levashov
protected function _abspath($path)
* Return fake path started from root dir.
* @param string $path file path
* @author Dmitry (dio) Levashov
protected function _path($path)
return $this->rootName . $this->_normpath(substr($path, strlen($this->root)));
* Return true if $path is children of $parent.
* @param string $path path to check
* @param string $parent parent path
* @author Dmitry (dio) Levashov
protected function _inpath($path, $parent)
return $path == $parent || strpos($path, $parent . '/') === 0;
/***************** file stat ********************/
* Return stat for given path.
* Stat contains following fields:
* - (int) size file size in b. required
* - (int) ts file modification time in unix time. required
* - (string) mime mimetype. required for folders, others - optionally
* - (bool) read read permissions. required
* - (bool) write write permissions. required
* - (bool) locked is object locked. optionally
* - (bool) hidden is object hidden. optionally
* - (string) alias for symlinks - link target path relative to root path. optionally
* - (string) target for symlinks - link target path. optionally.
* If file does not exists - returns empty array or false.
* @param string $path file path
* @author Dmitry (dio) Levashov
protected function _stat($path)
if ($raw = $this->_bd_getRawItem($path)) {
return $this->_bd_parseRaw($raw);
* Return true if path is dir and has at least one childs directory.
* @param string $path dir path
* @author Dmitry (dio) Levashov
protected function _subdirs($path)
list(, $itemId) = $this->_bd_splitPath($path);
$path = '/folders/' . $itemId . '/items?limit=1&offset=0&fields=' . self::FETCHFIELDS;
$url = self::API_URL . $path;