: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
* 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)
$this->_gd_getDirectoryData();
$path = $this->_normpath(substr($path, strlen($this->root)));
$paths = explode('/', $path);
foreach ($paths as $_p) {
$names[] = isset($this->names[$_p]) ? $this->names[$_p] : $_p;
return $this->rootName . implode('/', $names);
* 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->_gd_getFile($path)) {
$stat = $this->_gd_parseRaw($raw);
if ($path === $this->root) {
$stat['expires'] = $this->expires;
* 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)
if ($this->directories === null) {
$this->_gd_getDirectoryData();
list(, $itemId) = $this->_gd_splitPath($path);
return isset($this->directories[$itemId]);
* Return object width and height
* Ususaly used for images, but can be realize for video etc...
* @param string $path file path
* @param string $mime file mime type
* @throws ImagickException
* @throws elFinderAbortException
* @author Dmitry (dio) Levashov
protected function _dimensions($path, $mime)
if (strpos($mime, 'image') !== 0) {
if ($file = $this->_gd_getFile($path)) {
if (isset($file['imageMediaMetadata'])) {
$ret = array('dim' => $file['imageMediaMetadata']['width'] . 'x' . $file['imageMediaMetadata']['height']);
if (func_num_args() > 2) {
if (!empty($args['substitute'])) {
$tmbSize = intval($args['substitute']);
$srcSize = explode('x', $ret['dim']);
if ($srcSize[0] && $srcSize[1]) {
if (min(($tmbSize / $srcSize[0]), ($tmbSize / $srcSize[1])) < 1) {
if ($this->_gd_isPublished($file)) {
$tmbSize = strval($tmbSize);
$ret['url'] = 'https://drive.google.com/thumbnail?authuser=0&sz=s' . $tmbSize . '&id=' . $file['id'];
} elseif ($subImgLink = $this->getSubstituteImgLink(elFinder::$currentArgs['target'], $srcSize)) {
$ret['url'] = $subImgLink;
/******************** file/dir content *********************/
* Return files list in directory.
* @param string $path dir path
* @author Dmitry (dio) Levashov
* @author Cem (DiscoFever)
protected function _scandir($path)
return isset($this->dirsCache[$path])
? $this->dirsCache[$path]
: $this->cacheDir($path);
* Open file and return file pointer.
* @param string $path file path
* @param bool $write open file for writing
* @author Dmitry (dio) Levashov
protected function _fopen($path, $mode = 'rb')
if ($mode === 'rb' || $mode === 'r') {
if ($file = $this->_gd_getFile($path)) {
if ($dlurl = $this->_gd_getDownloadUrl($file)) {
$token = $this->client->getAccessToken();
if (!$token && $this->client->isUsingApplicationDefaultCredentials()) {
$this->client->fetchAccessTokenWithAssertion();
$token = $this->client->getAccessToken();
$access_token = $token['access_token'];
if ($token = json_decode($this->client->getAccessToken())) {
$access_token = $token->access_token;
'headers' => array('Authorization: Bearer ' . $access_token),
// to support range request
if (func_num_args() > 2) {
if (!empty($opts['httpheaders'])) {
$data['headers'] = array_merge($opts['httpheaders'], $data['headers']);
return elFinder::getStreamByUrl($data);
* @param resource $fp file pointer
* @author Dmitry (dio) Levashov
protected function _fclose($fp, $path = '')
is_resource($fp) && fclose($fp);
unlink($this->getTempFile($path));
/******************** file/dir manipulations *************************/
* Create dir and return created dir path or false on failed.
* @param string $path parent dir path
* @param string $name new directory name
* @author Dmitry (dio) Levashov
protected function _mkdir($path, $name)
$path = $this->_joinPath($path, $name);
list($parentId, , $parent) = $this->_gd_splitPath($path);
$file = new \Google_Service_Drive_DriveFile();
$file->setMimeType(self::DIRMIME);
$file->setParents([$parentId]);
//create the Folder in the Parent
$obj = $this->service->files->create($file);
if ($obj instanceof Google_Service_Drive_DriveFile) {
$path = $this->_joinPath($parent, $obj['id']);
$this->_gd_getDirectoryData(false);
return $this->setError('GoogleDrive error: ' . $e->getMessage());
* Create file and return it's path or false on failed.
* @param string $path parent dir path
* @param string $name new file name
* @author Dmitry (dio) Levashov
protected function _mkfile($path, $name)
return $this->_save($this->tmpfile(), $path, $name, []);
* Create symlink. FTP driver does not support symlinks.
* @param string $target link target
* @param string $path symlink path
* @author Dmitry (dio) Levashov
protected function _symlink($target, $path, $name)
* Copy file into another file.
* @param string $source source file path
* @param string $targetDir target directory path
* @param string $name new file name
* @author Dmitry (dio) Levashov
protected function _copy($source, $targetDir, $name)
$source = $this->_normpath($source);
$targetDir = $this->_normpath($targetDir);
$file = new \Google_Service_Drive_DriveFile();
list(, $parentId) = $this->_gd_splitPath($targetDir);
$file->setParents([$parentId]);
list(, $srcId) = $this->_gd_splitPath($source);
$file = $this->service->files->copy($srcId, $file, ['fields' => self::FETCHFIELDS_GET]);
return $this->setError('GoogleDrive error: ' . $e->getMessage());
* Move file into another parent dir.
* Return new file path or false.
* @param string $source source file path
* @param string $target target dir path
* @param string $name file name
* @author Dmitry (dio) Levashov
protected function _move($source, $targetDir, $name)
list($removeParents, $itemId) = $this->_gd_splitPath($source);
$target = $this->_normpath($targetDir . '/' . $itemId);
//moving and renaming a file or directory
$files = new \Google_Service_Drive_DriveFile();
//Set new Parent and remove old parent
list(, $addParents) = $this->_gd_splitPath($targetDir);
$opts = ['addParents' => $addParents, 'removeParents' => $removeParents];
$file = $this->service->files->update($itemId, $files, $opts);
if ($file->getMimeType() === self::DIRMIME) {
$this->_gd_getDirectoryData(false);
return $this->setError('GoogleDrive error: ' . $e->getMessage());
* @param string $path file path
* @author Dmitry (dio) Levashov
protected function _unlink($path)
$files = new \Google_Service_Drive_DriveFile();
$files->setTrashed(true);
list($pid, $itemId) = $this->_gd_splitPath($path);
$opts = ['removeParents' => $pid];
$this->service->files->update($itemId, $files, $opts);
return $this->setError('GoogleDrive error: ' . $e->getMessage());
* @param string $path dir path
* @author Dmitry (dio) Levashov
protected function _rmdir($path)
$res = $this->_unlink($path);
$res && $this->_gd_getDirectoryData(false);
* Create new file and write into it from file pointer.
* Return new file path or false on error.
* @param resource $fp file pointer
* @param string $name file name
* @param array $stat file stat (required by some virtual fs)
* @author Dmitry (dio) Levashov
protected function _save($fp, $path, $name, $stat)
$path .= '/' . str_replace('/', '\\/', $name);
list($parentId, $itemId, $parent) = $this->_gd_splitPath($path);
if (!$stat || empty($stat['iid'])) {
'q' => sprintf('trashed=false and "%s" in parents and name="%s"', $parentId, $name),
'fields' => self::FETCHFIELDS_LIST,
$srcFile = $this->_gd_query($opts);
$srcFile = empty($srcFile) ? null : $srcFile[0];
$srcFile = $this->_gd_getFile($path);
$mime = isset($stat['mime']) ? $stat['mime'] : '';
$file = new Google_Service_Drive_DriveFile();
$mime = $srcFile->getMimeType();
$mime = self::mimetypeInternalDetect($name);
if ($mime === 'unknown') {
$mime = 'application/octet-stream';
$file->setMimeType($mime);
if (isset($stat['size'])) {
if (!empty($fstat['size'])) {
// set chunk size (max: 100MB)
$chunkSizeBytes = 100 * 1024 * 1024;
$memory = elFinder::getIniBytes('memory_limit');
$chunkSizeBytes = max(262144, min([$chunkSizeBytes, (intval($memory / 4 / 256) * 256)]));
if ($size > $chunkSizeBytes) {
// Call the API with the media upload, defer so it doesn't immediately return.
if ($mode === 'insert') {
$request = $this->service->files->create($file, [
'fields' => self::FETCHFIELDS_GET,
$request = $this->service->files->update($srcFile->getId(), $file, [
'fields' => self::FETCHFIELDS_GET,