Closed rajasharma27 closed 8 years ago
lovesin83@naver.com λκ» λ³΄λ΄μ λ©μΌ <[elFinder] elFinder with GoogleDrive (#1275)> μ΄ λ€μκ³Ό κ°μ μ΄μ λ‘ μ μ‘ μ€ν¨νμ΅λλ€.
λ°λ μ¬λμ΄ νμλμ λ©μΌμ μμ μ°¨λ¨ νμμ΅λλ€.
Inspired by @rajasharma27 , it added a net mount driver for FlySystem + GoogleDrive adapter.
composer require
composer require barryvdh/elfinder-flysystem-driver
composer require nao-pon/flysystem-google-drive:~1.1 google/apiclient:~2.0@rc
connector.php
// Load composer autoloader
require 'vender/autoload.php';
// Enable Google Drive as Netmount driver
include_once __DIR__.DIRECTORY_SEPARATOR.'elFinderFlysystemGoogleDriveNetmount.php';
define('ELFINDER_GOOGLEDRIVE_CLIENTID', 'YOUR CLIENT ID');
define('ELFINDER_GOOGLEDRIVE_CLIENTSECRET', 'YOUR CLIENT SECRET');
Google API Manager Add "YOUR_CONNECTOR_URL(connector.php)?cmd=netmount&protocol=googledrive&host=1" to "Authorized redirect URIs" in "Credentials" on Google API Manager.
thanks sir, I am updating a google drive adapter class for mounting google drive with elFinder
sir, my "google-api-php-client" library not work "get with array"
$contents = $service->files->get($fileId,['alt' => 'media']);
$request = new Google_Http_Request($downloadUrl, 'GET', null, null);
these are not found in my google library
where is the right path for download library and also download full package of fly-system
@rajasharma27 Can you use composer
in your server?
composer require google/apiclient:~2.0@rc league/flysystem league/flysystem-cached-adapter
or Download google-api-php-client v2.0.0 from https://github.com/google/google-api-php-client/releases and flysystem and flysystem-cached-adapter.
currently use windows 10 IIS with php 4.7
php 4.7? php 5.4.7?
composer can also be used with Windows.
ref. https://getcomposer.org/doc/00-intro.md#installation-windows
thanks now working C:>composer -V Composer version 1.0-dev (f542b0f32d044a9cc958510303b299685f7e7cc1) 2016-03-26 09:49:28
lovesin83@naver.com λκ» λ³΄λ΄μ λ©μΌ <Re: [elFinder] elFinder with GoogleDrive (#1275)> μ΄ λ€μκ³Ό κ°μ μ΄μ λ‘ μ μ‘ μ€ν¨νμ΅λλ€.
λ°λ μ¬λμ΄ νμλμ λ©μΌμ μμ μ°¨λ¨ νμμ΅λλ€.
PHP Version 5.4.45
create a function for mounting with subfolder but I am missing something getRealpath($path) this function call in getDBdat($path) and cacheDir($path) getRealpath function return everything but missing something
<?php
elFinder::$netDrivers['googledrive'] = 'GoogleDrive';
/**
* Simple elFinder driver for GoogleDrive
*
* @author Dmitry (dio) Levashov
* @author Cem (discofever)
* @author Raja Sharma - updating for GoogleDrive
**/
class elFinderVolumeGoogleDrive extends elFinderVolumeDriver {
/**
* Driver id
* Must be started from letter and contains [a-z0-9]
* Used as part of volume id
*
* @var string
**/
protected $driverId = 'gd';
/**
* OAuth object
*
* @var oauth
**/
protected $oauth = null;
//protected $client = null;
/**
* GoogleDrive object
*
* @var googledrive
**/
protected $googledrive = null;
/**
* Fetch fields setting for list
*
* @var string
*/
const FETCHFIELDS_LIST = 'files(id,mimeType,modifiedTime,name,parents,permissions,size,webContentLink),nextPageToken';
/**
* Fetch fields setting for get
*
* @var string
*/
const FETCHFIELDS_GET = 'id,name,mimeType,modifiedTime,parents,permissions,size,webContentLink';
/**
* MIME tyoe of directory
*
* @var string
*/
const DIRMIME = 'application/vnd.google-apps.folder';
/**
* Google_Service_Drive instance
*
* @var Google_Service_Drive
*/
protected $service;
/**
* Default options
*
* @var array
*/
protected static $defaultOptions = [
'spaces' => 'drive',
'useHasDir' => false,
'publishPermission' => [
'type' => 'anyone',
'role' => 'reader',
'withLink' => true
]
];
/**
* A comma-separated list of spaces to query
* Supported values are 'drive', 'appDataFolder' and 'photos'
*
* @var string
*/
protected $spaces;
/**
* Permission array as published item
*
* @var array
*/
protected $publishPermission;
/**
* Cache of file objects
*
* @var array
*/
private $cacheFileObjects = [];
/**
* Cache of hasDir
*
* @var array
*/
private $cacheHasDirs = [];
/**
* Use hasDir function
*
* @var bool
*/
private $useHasDir = false;
/**
* Directory for meta data caches
* If not set driver not cache meta data
*
* @var string
**/
protected $metaCache = '';
/**
* Last API error message
*
* @var string
**/
protected $apiError = '';
/**
* Directory for tmp files
* If not set driver will try to use tmbDir as tmpDir
*
* @var string
**/
protected $tmp = '';
/**
* Net mount key
*
* @var string
**/
public $netMountKey = '';
/**
* drive.google.com uid
*
* @var string
**/
protected $googledriveUid = '';
/**
* Gdrive download host, replaces 'drive.google.com' of shares URL
*
* @var string
*/
private $googledrive_dlhost = 'drive.google.com';
private $googledrive_phpFound = false;
private $DB_TableName = '';
private $tmbPrefix = '';
/**
* Constructor
* Extend options with required fields
*
* @return void
* @author Dmitry (dio) Levashov
* @author Cem (DiscoFever)
**/
public function __construct() {
//ini_set('memory_limit', '128M');
@ include_once 'google-api-php-client/src/Google_Client.php';
@ include_once 'google-api-php-client/src/contrib/Google_DriveService.php';
@ include_once 'google-api-php-client/src/contrib/Google_Oauth2Service.php';
//$this->gdrive_phpFound = in_array('setClientId', 'setClientSecret', 'setRedirectUri');
$opts = array(
'clientId' => '',
'clientSecret' => '',
'redirecturi' => '',
'accessToken' => '',
'accessTokenSecret' => '',
'googledriveUid' => '',
'root' => 'GoogleDrive',
'path' => '/',
'separator' => '/',
'PDO_DSN' => '', // if empty use 'sqlite:(metaCachePath|tmbPath)/elFinder_dropbox_db_(hash:googledriveUid+consumerSecret)'
'PDO_User' => '',
'PDO_Pass' => '',
'PDO_Options' => array(),
'PDO_DBName' => 'googledrive',
'treeDeep' => 0,
'tmbPath' => '../files/.tmb',
'tmbURL' => dirname($_SERVER['PHP_SELF']) . '/../files/.tmb',
'tmpPath' => '../files/.tmp',
'getTmbSize' => 'large', // small: 32x32, medium or s: 64x64, large or m: 128x128, l: 640x480, xl: 1024x768
'metaCachePath' => '',
'metaCacheTime' => '600', // 10m
'acceptedName' => '#^[^/\\?*:|"<>]*[^./\\?*:|"<>]$#',
'rootCssClass' => 'elfinder-navbar-root-googledrive'
);
$this->options = array_merge($this->options, $opts);
$this->options['mimeDetect'] = 'internal';
}
/**
* Prepare
* Call from elFinder::netmout() before volume->mount()
*
* @return Array
* @author Naoki Sawada
* @author Raja Sharma updating for GoogleDrive
**/
public function netmountPrepare($options) {
if (empty($options['clientId']) && defined('ELFINDER_GDRIVE_CLIENTID')) $options['clientId'] = ELFINDER_GDRIVE_CLIENTID;
if (empty($options['clientSecret']) && defined('ELFINDER_GDRIVE_CLIENTSECRET')) $options['clientSecret'] = ELFINDER_GDRIVE_CLIENTSECRET;
if (empty($options['redirecturi']) && defined('ELFINDER_GDRIVE_REDIRECTURI')) $options['redirecturi'] = ELFINDER_GDRIVE_REDIRECTURI;
if ($options['callback']=='true' && isset($_GET['code'])) {
session_start();
include_once 'google-api-php-client/src/Google_Client.php';
include_once 'google-api-php-client/src/contrib/Google_DriveService.php';
include_once 'google-api-php-client/src/contrib/Google_Oauth2Service.php';
$client = new Google_Client();
$client->setClientId($options['clientId']);
$client->setClientSecret($options['clientSecret']);
$client->setRedirectUri($options['redirecturi']);
$client->setScopes(array('https://www.googleapis.com/auth/drive https://www.googleapis.com/auth/userinfo.profile'));
$oauth2 = new Google_Oauth2Service($client);
$accessToken = $client->authenticate($_GET['code']);
$tokens = base64_encode($client->getAccessToken());
$callback_url = $_SESSION['callback'];
$userinfo = $oauth2->userinfo->get();
unset($_SESSION['callback']);
$objurl= array();
foreach (explode('&', $callback_url) as $chunk) {
$param = explode("=", $chunk);
if ($param) {
$objurl[urldecode($param[0])]=urldecode($param[1]);
}
}
$callback_url = $options['redirecturi'].'?node='.$objurl['node'].'&protocol='.$objurl['protocol'].'&uid='.$userinfo['id'].'&cmd=netmount&host='.$objurl['host'].'&code='.$_GET['code'].'&oauth_token='.$tokens.'&user='.$objurl['user'].'&pass=return'.'&_='.$objurl['_'];
header("Location: ".$callback_url);
exit();
}
if ($options['user'] === 'init') {
if (empty($options['clientId']) || empty($options['clientSecret']) || empty($options['redirecturi'])) {
return array('exit' => true, 'body' => '{msg:errNetMountNoDriver}');
}
try{
$this->oauth = new Google_Client();
}catch (Exception $e){
return array('exit' => true, 'body' => '{msg:errNetMountNoDriver}');
}
if ($options['pass'] === 'init') {
$html = '';
if (isset($_SESSION['elFinderGoogledriveTokens'])) {
// token check
try {
list($options['googledriveUid'], $options['accessToken']) = $_SESSION['elFinderGoogledriveTokens'];
$this->oauth->setAccessToken($_SESSION['elFinderGoogleDriveAuthTokens']);
$oauth_token = $this->oauth->getAccessToken();
$oauth2 = new Google_Oauth2Service($this->oauth);
$userid = $oauth2->userinfo->get();
$script = '<script>
$("#'.$options['id'].'").elfinder("instance").trigger("netmount", {protocol: "googledrive", mode: "done"});
</script>';
$html = $script;
} catch (GoogleDrive_Exception $e) {
unset($_SESSION['elFinderGoogledriveTokens']);
unset($_SESSION['elFinderGoogleDriveAuthTokens']);
}
}
if (! $html && !isset($_SESSION['elFinderGoogledriveTokens'])) {
// get customdata
$cdata = '';
$innerKeys = array('cmd', 'host', 'options', 'pass', 'protocol', 'user');
$this->ARGS = $_SERVER['REQUEST_METHOD'] === 'POST'? $_POST : $_GET;
foreach($this->ARGS as $k => $v) {
if (! in_array($k, $innerKeys)) {
$cdata .= '&' . $k . '=' . rawurlencode($v);
}
}
if (strpos($options['url'], 'http') !== 0 ) {
$options['url'] = $this->getConnectorUrl();
}
$callback = $options['url']
. '?cmd=netmount&protocol=googledrive&host=googledrive.com&user=init&pass=return&node='.$options['id'].$cdata;
$_SESSION['callback'] = $callback;
try {
$client = new Google_Client();
// Get your credentials from the console
$client->setClientId($options['clientId']);
$client->setClientSecret($options['clientSecret']);
$client->setRedirectUri($options['redirecturi']);
$client->setScopes(array('https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/drive https://www.googleapis.com/auth/drive.file https://www.googleapis.com/auth/drive.metadata'));
$client->setAccessType('online');
$client->setApprovalPrompt('force');
$service = new Google_DriveService($client);
$this->oauth = $client->createAuthUrl();
$url = $this->oauth.='&oauth_callback=' . rawurlencode($callback);
} catch (GoogleDrive_Exception $e) {
return array('exit' => true, 'body' => '{msg:errAccess}');
}
$_SESSION['elFinderGoogleDriveAuthTokens'] = $tokens;
$html = '<input id="elf-volumedriver-googledrive-host-btn" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" value="{msg:btnApprove}" type="button" onclick="window.open(\''.$url.'\')">';
$html .= '<script>
$("#'.$options['id'].'").elfinder("instance").trigger("netmount", {protocol: "googledrive", mode: "makebtn"});
</script>';
}
return array('exit' => true, 'body' => $html);
} else {
if (isset($_GET['oauth_token'])) {
$_SESSION['elFinderGoogleDriveAuthTokens'] = base64_decode($_GET["oauth_token"]);
}
$client = new Google_Client();
$client->setAccessToken($_SESSION['elFinderGoogleDriveAuthTokens']);
//unset($_SESSION['elFinderGoogleDriveAuthTokens']);
$oauth_token = $client->getAccessToken();
$oauth2 = new Google_Oauth2Service($client);
$userid = $oauth2->userinfo->get();
$_SESSION['elFinderGoogledriveTokens'] = array($userid['id'], $oauth_token);
$out = array(
'node' => $_GET['node'],
'json' => '{"protocol": "googledrive", "mode": "done"}',
'bind' => 'netmount'
);
return array('exit' => 'callback', 'out' => $out);
}
}
if (isset($_SESSION['elFinderGoogledriveTokens'])) {
list($options['googledriveUid'], $options['accessToken']) = $_SESSION['elFinderGoogledriveTokens'];
}
unset($options['user'], $options['pass']);
return $options;
}
/**
* process of on netunmount
* Drop `googledrive` & rm thumbs
*
* @param array $options
* @return boolean
*/
public function netunmount($netVolumes, $key) {
$count = 0;
$googledriveUid = '';
if (isset($netVolumes[$key])) {
$googledriveUid = $netVolumes[$key]['googledriveUid'];
}
foreach($netVolumes as $volume) {
if (@$volume['host'] === 'googledrive' && @$volume['googledriveUid'] === $googledriveUid) {
$count++;
}
}
if ($count === 1) {
foreach(glob(rtrim($this->options['tmbPath'], '\\/').DIRECTORY_SEPARATOR.$this->tmbPrefix.'*.png') as $tmb) {
unlink($tmb);
}
}
return true;
}
/**
* Get script url
*
* @return string full URL
* @author Naoki Sawada
*/
private function getConnectorUrl() {
$url = ((isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'off')? 'https://' : 'http://')
. $_SERVER['SERVER_NAME'] // host
. ($_SERVER['SERVER_PORT'] == 80 ? '' : ':' . $_SERVER['SERVER_PORT']) // port
. $_SERVER['REQUEST_URI']; // path & query
list($url) = explode('?', $url);
return $url;
}
/*********************************************************************/
/* INIT AND CONFIGURE */
/*********************************************************************/
/**
* Prepare FTP connection
* Connect to remote server and check if credentials are correct, if so, store the connection id in $ftp_conn
*
* @return bool
* @author Dmitry (dio) Levashov
* @author Cem (DiscoFever)
**/
protected function init() {
if (!$this->options['googledriveUid']
|| !$this->options['accessToken']) {
return $this->setError('Required options undefined.');
}
// make net mount key
$this->netMountKey = md5(join('-', array('googledrive', $this->options['path'])));
if (! $this->oauth) {
$client = new Google_Client();
$client->setAccessToken($_SESSION['elFinderGoogleDriveAuthTokens']);
$this->oauth = new Google_DriveService($client);
}
if (! $this->oauth) {
return $this->setError('OAuth extension not loaded.');
}
// normalize root path
$this->root = $this->options['path'] = $this->_normpath($this->options['path']);
if (empty($this->options['alias'])) {
$this->options['alias'] = ($this->options['path'] === '/')? 'GoogleDrive.com' : 'GoogleDrive'.$this->options['path'];
}
$this->rootName = $this->options['alias'];
$this->googledriveUid = $this->options['googledriveUid'];
$this->tmbPrefix = 'googledrive'.base_convert($this->googledriveUid, 10, 32);
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 && is_writable($this->options['tmbPath'])) {
$this->tmp = $this->options['tmbPath'];
}
if (!$this->tmp && ($tmp = elFinder::getStaticVar('commonTempPath'))) {
$this->tmp = $tmp;
}
if (!empty($this->options['metaCachePath'])) {
if ((is_dir($this->options['metaCachePath']) || @mkdir($this->options['metaCachePath'])) && is_writable($this->options['metaCachePath'])) {
$this->metaCache = $this->options['metaCachePath'];
}
}
if (!$this->metaCache && $this->tmp) {
$this->metaCache = $this->tmp;
}
if (!$this->metaCache) {
return $this->setError('Cache dirctory (metaCachePath or tmp) is require.');
}
if (is_null($this->options['syncChkAsTs'])) {
$this->options['syncChkAsTs'] = true;
}
if ($this->options['syncChkAsTs']) {
// 'tsPlSleep' minmum 5 sec
$this->options['tsPlSleep'] = max(5, $this->options['tsPlSleep']);
} else {
// 'lsPlSleep' minmum 10 sec
$this->options['lsPlSleep'] = max(10, $this->options['lsPlSleep']);
}
return true;
}
/**
* Configure after successfull mount.
*
* @return void
* @author Dmitry (dio) Levashov
**/
protected function configure() {
parent::configure();
if (!$this->tmp) {
$this->disabled[] = 'archive';
$this->disabled[] = 'extract';
}
}
/**
* Drive query and fetchAll
*
* @param string $sql
* @return boolean|array
*/
private function query($sql,$path) {
$files = new Google_DriveFile();
$curlres =array();
$path == '/' ? $fpath = '/' : $fpath = $path.'/';
$file = $this->oauth->files->listFiles($sql);
$i=0;
$j=0;
if($fpath == '/'){
$curlres[$j] = ['path'=>'/','id'=>NULL, 'name'=>'', 'size'=>'', 'modifiedTime'=>NULL, 'mimeType'=>'application/vnd.google-apps.folder', 'parents'=>'', 'read'=>'1', 'write'=>'1', 'locked'=>'0', 'hidden'=>'0', 'width'=>'', 'height'=>'', 'url'=>'','tmbUrl'=>''];
$j++;
}
if($fpath !== '/'){
$child = $this->oauth->files->get(basename($path));
$curlres[$j] = ['path'=>$path,'id'=>$child['id'], 'name'=>$child['title'], 'size'=>$child['childSize'], 'modifiedTime'=>$child['modifiedDate'], 'mimeType'=>$child['mimeType'], 'childs'=>$child[0]['childs'][0]['id'], 'read'=>'1', 'write'=>'1', 'locked'=>$child['labels']['restricted'], 'hidden'=>$child['labels']['hidden'], 'width'=>$child['imageMediaMetadata']['width'], 'height'=>$child['imageMediaMetadata']['height'], 'url'=>$child['alternateLink'],'tmbUrl'=>$child['thumbnailLink']];
$j++;
}
while($file['items'][$i]['id']){
$curlres[$j] = ['path'=>$fpath.$file['items'][$i]['id'],'id'=>$file['items'][$i]['id'], 'name'=>$file['items'][$i]['title'], 'size'=>$file['items'][$i]['fileSize'], 'modifiedTime'=>$file['items'][$i]['modifiedDate'], 'mimeType'=>$file['items'][$i]['mimeType'], 'parents'=>$file['items'][0]['parents'][0]['id'], 'read'=>'1', 'write'=>'1', 'locked'=>$file['items'][$i]['labels']['restricted'], 'hidden'=>$file['items'][$i]['labels']['hidden'], 'width'=>$file['items'][$i]['imageMediaMetadata']['width'], 'height'=>$file['items'][$i]['imageMediaMetadata']['height'], 'url'=>$file['items'][$i]['alternateLink'],'tmbUrl'=>$file['items'][$i]['thumbnailLink']];
$i++;
$j++;
}
return $curlres;
}
/**
* Get token and auto refresh
*
* @param boolean $refresh force refresh
* @return true|string error message
*/
private function refreshGoogleDriveToken($refresh = true) {
try {
$client = new Google_Client();
$google_token = $_SESSION['elFinderGoogleDriveAuthTokens'];
//$client->refreshToken($google_token->refresh_token);
$client->setAccessToken($_SESSION['elFinderGoogleDriveAuthTokens']);
$_SESSION['elFinderGoogleDriveAuthTokens'] = $client->getAccessToken();
$this->oauth = new Google_DriveService($client);
} catch(GoogleDrive_Exception $e) {
return $e->getMessage();
}
return true;
}
/**
* Get directory/file id
*
* @return true|string error message
*/
private function getRealpath($path) {
if($path == '/'){
return $path;
}else{
$temppath = explode('/',$path);
$temppath[0] == '' ? $itemId= 'root' : $itemId= $temppath[0];
$path== '/' || $path=='root' || $temppath[0]== '' || $temppath[0]== '/'? $itemId= 'root' : $itemId = basename($path);
$j=0;
foreach($temppath as $tpath) {
$opts = [
'q' => sprintf('trashed=false and "%s" in parents and mimeType = "%s"', basename($itemId), self::DIRMIME)
];
$files = new Google_DriveFile();
$file = $this->oauth->files->listFiles($opts);
$i=0;
while($file['items'][$i]['id']){
if($file['items'][$i]['title'] == $tpath || $file['items'][$i]['id'] ==$tpath ){
$itemId = $itemId.'/'.$file['items'][$i]['id'];
break;
}
$i++;
}
$j++;
}
return substr($itemId,4);
}
}
/**
* Get dat(googledrive metadata) from GoogleDrive
*
* @param string $path
* @return array googledrive metadata
*/
private function getDBdat($path) {
$path = $this->getRealpath($path);
$path == '/' || $path =='root' ? $itemId= 'root' : $itemId= basename($path);
$opts = [
'q' => sprintf('trashed=false and "%s" in parents', $itemId)
];
if($res = $this->query($opts,$path)) {
return $res[0];
} else {
return array();
}
}
/**
* Update DB dat(dropbox metadata)
*
* @param string $path
* @param array $dat
* @return bool|array
*/
private function updateDBdat($path, $dat) {
return $this->query('update '.$this->DB_TableName.' set dat='.$this->DB->quote(serialize($dat))
. ', isdir=' . ($dat['is_dir']? 1 : 0)
. ' where path='.$this->DB->quote(strtolower($this->_dirname($path))).' and fname='.$this->DB->quote(strtolower(basename($path))));
}
/*********************************************************************/
/* FS API */
/*********************************************************************/
/**
* Close opened connection
*
* @return void
* @author Dmitry (dio) Levashov
**/
public function umount() {
}
/**
* Get delta data and DB update
*
* @param boolean $refresh force refresh
* @return true|string error message
*/
/**
* Parse line from googledrive metadata output and return file stat (array)
*
* @param string $raw line from ftp_rawlist() output
* @return array
* @author Dmitry Levashov
**/
protected function parseRaw($raw) {
$stat = array();
$stat['rev'] = isset($raw['id']) ? $raw['id'] : 'root';
$stat['name'] = basename($raw['name']);
$stat['mime'] = $raw['mimeType']== self::DIRMIME ? 'directory' : $raw['mimeType'];
$stat['size'] = $raw['mimeType']== self::DIRMIME ? 0 : (int)$raw['size'];
$stat['ts'] = isset($raw['modifiedTime']) ? strtotime($raw['modifiedTime']) : $_SERVER['REQUEST_TIME'];
$stat['tmbUrl'] = $raw['tmbUrl'];
$stat['dirs'] = $raw['mimeType']== self::DIRMIME ? 1 : 0;
if (!empty($raw['url'])) {
$stat['url'] = $raw['url'];
} else {
$stat['url'] = '1';
}
isset($raw['width']) ? $stat['width'] = $raw['width'] : $stat['width'] = 0;
isset($raw['height'])? $stat['height'] = $raw['height'] : $stat['height'] = 0;
return $stat;
}
/**
* Cache dir contents
*
* @param string $path dir path
* @return void
* @author Dmitry Levashov
**/
protected function cacheDir($path) {
$path = $this->getRealpath($path);
$path == '/' || $path =='root' ? $itemId= 'root' : $itemId = basename($path);
$opts = [
// 'pageSize' => $maxResults ? : 1000,
// 'q' => sprintf('trashed=false and "%s" in parents and mimeType = "%s"', $itemID, self::DIRMIME)
'q' => sprintf('trashed=false and "%s" in parents',$itemId)
];
$this->dirsCache[$path] = array();
$res = $this->query($opts,$path);
if ($res) {
foreach($res as $raw) {
if ($stat = $this->parseRaw($raw)) {
$stat = $this->updateCache($raw['path'], $stat);
if (empty($stat['hidden']) && $path !== $raw['path']) {
$this->dirsCache[$path][] = $raw['path'];
}
}
}
}
return $this->dirsCache[$path];
}
/**
* Recursive files search
*
* @param string $path dir path
* @param string $q search string
* @param array $mimes
* @return array
* @author Naoki Sawada
**/
protected function doSearch($path, $q, $mimes) {
$result = array();
$sth = $this->DB->prepare('select dat from '.$this->DB_TableName.' WHERE path LIKE ? AND fname LIKE ?');
$sth->execute(array((($path === '/')? '' : strtolower($path)).'%', '%'.strtolower($q).'%'));
$res = $sth->fetchAll(PDO::FETCH_COLUMN);
$timeout = $this->options['searchTimeout']? $this->searchStart + $this->options['searchTimeout'] : 0;
if ($res) {
foreach($res as $raw) {
if ($timeout && $timeout < time()) {
$this->setError(elFinder::ERROR_SEARCH_TIMEOUT, $this->path($this->encode($path)));
break;
}
$raw = unserialize($raw);
if ($stat = $this->parseRaw($raw)) {
if (!isset($this->cache[$raw['path']])) {
$stat = $this->updateCache($raw['path'], $stat);
}
if (!empty($stat['hidden']) || ($mimes && $stat['mime'] === 'directory') || !$this->mimeAccepted($stat['mime'], $mimes)) {
continue;
}
$stat = $this->stat($raw['path']);
$stat['path'] = $this->path($stat['hash']);
$result[] = $stat;
}
}
}
return $result;
}
/**
* 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)
* @return string|false
* @author Dmitry (dio) Levashov
* @author Naoki Sawada
**/
protected function copy($src, $dst, $name) {
$this->clearcache();
return $this->_copy($src, $dst, $name)
? $this->_joinPath($dst, $name)
: $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
* @return bool
* @author Dmitry (dio) Levashov
* @author Naoki Sawada
**/
protected function remove($path, $force = false, $recursive = false) {
$stat = $this->stat($path);
$stat['realpath'] = $path;
$this->rmTmb($stat);
$this->clearcache();
if (empty($stat)) {
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));
}
} else {
if (!$recursive && !$this->_unlink($path)) {
return $this->setError(elFinder::ERROR_RM, $this->_path($path));
}
}
$this->removed[] = $stat;
return true;
}
/**
* Create thumnbnail and return it's URL on success
*
* @param string $path file path
* @param string $mime file mime type
* @return string|false
* @author Dmitry (dio) Levashov
* @author Naoki Sawada
**/
protected function createTmb($path, $stat) {
if (!$stat || !$this->canCreateTmb($path, $stat)) {
return false;
}
$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->getThumbnail($path, $this->options['getTmbSize'])) {
return false;
}
if (! file_put_contents($tmb, $data)) {
return false;
}
$result = false;
$tmbSize = $this->tmbSize;
if (($s = getimagesize($tmb)) == false) {
return 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' );
} else {
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 (($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');
}
} else {
$result = $this->imgResize($tmb, $tmbSize, $tmbSize, true, true, 'png');
}
$result = $this->imgSquareFit($tmb, $tmbSize, $tmbSize, 'center', 'middle', $this->options['tmbBgColor'], 'png' );
}
if (!$result) {
unlink($tmb);
return false;
}
return $name;
}
/**
* Return thumbnail file name for required file
*
* @param array $stat file stat
* @return string
* @author Dmitry (dio) Levashov
**/
protected function tmbname($stat) {
return $this->tmbPrefix.$stat['rev'].'.png';
}
/**
* Get thumbnail from dropbox.com
* @param string $path
* @param string $size
* @return string | boolean
*/
protected function getThumbnail($path, $size = 'small') {
$opts = [
'q' => sprintf('trashed=false and "%s" in parents',basename($path))
];
try {
$res = $this->query($opts,$path);
$res = file_get_contents($res[0]['tmbUrl']);
return $res;
} catch (GoogleDrive_Exception $e) {
return false;
}
}
/**
* Return content URL
*
* @param string $hash file hash
* @param array $options options
* @return array
* @author Naoki Sawada
**/
public function getContentUrl($hash, $options = array()) {
if (($file = $this->file($hash)) == false || !$file['url'] || $file['url'] == 1) {
$path = $this->decode($hash);
$cache = $this->getDBdat($path);
$url = '';
if (isset($cache['share']) && strpos($cache['share'], $this->googledrive_dlhost) !== false) {
$res = $this->getHttpResponseHeader($cache['share']);
if (preg_match("/^HTTP\/[01\.]+ ([0-9]{3})/", $res, $match)) {
if ($match[1] < 400) {
$url = $cache['share'];
}
}
}
if (! $url) {
try {
$res = $this->googledrive->share($path, null, false);
$url = $res['url'];
if (strpos($url, 'www.drive.google.com') === false) {
$res = $this->getHttpResponseHeader($url);
if (preg_match('/^location:\s*(http[^\s]+)/im', $res, $match)) {
$url = $match[1];
}
}
list($url) = explode('?', $url);
$url = str_replace('www.drive.google.com', $this->googledrive_dlhost, $url);
if (! isset($cache['share']) || $cache['share'] !== $url) {
$cache['share'] = $url;
$this->updateDBdat($path, $cache);
}
} catch (GoogleDrive_Exception $e) {
return false;
}
}
return $url;
}
return $file['url'];
}
/**
* Get HTTP request response header string
*
* @param string $url target URL
* @return string
* @author Naoki Sawada
*/
private function getHttpResponseHeader($url) {
if (function_exists('curl_exec')) {
$c = curl_init();
curl_setopt( $c, CURLOPT_RETURNTRANSFER, true );
curl_setopt( $c, CURLOPT_CUSTOMREQUEST, 'HEAD' );
curl_setopt( $c, CURLOPT_HEADER, 1 );
curl_setopt( $c, CURLOPT_NOBODY, true );
curl_setopt( $c, CURLOPT_URL, $url );
$res = curl_exec( $c );
} else {
require_once 'HTTP/Request2.php';
try {
$request2 = new HTTP_Request2();
$request2->setConfig(array(
'ssl_verify_peer' => false,
'ssl_verify_host' => false
));
$request2->setUrl($url);
$request2->setMethod(HTTP_Request2::METHOD_HEAD);
$result = $request2->send();
$res = array();
$res[] = 'HTTP/'.$result->getVersion().' '.$result->getStatus().' '.$result->getReasonPhrase();
foreach($result->getHeader() as $key => $val) {
$res[] = $key . ': ' . $val;
}
$res = join("\r\n", $res);
} catch( HTTP_Request2_Exception $e ){
$res = '';
} catch (Exception $e){
$res = '';
}
}
return $res;
}
/*********************** paths/urls *************************/
/**
* Return parent directory path
*
* @param string $path file path
* @return string
* @author Dmitry (dio) Levashov
**/
protected function _dirname($path) {
return $this->_normpath(dirname($path));
}
/**
* Return file name
*
* @param string $path file path
* @return string
* @author Dmitry (dio) Levashov
**/
protected function _basename($path) {
return basename($path);
}
/**
* Join dir name and file name and retur full path
*
* @param string $dir
* @param string $name
* @return string
* @author Dmitry (dio) Levashov
**/
protected function _joinPath($dir, $name) {
return $this->_normpath($dir.'/'.$name);
}
/**
* Return normalized path, this works the same as os.path.normpath() in Python
*
* @param string $path path
* @return string
* @author Troex Nevelin
**/
protected function _normpath($path) {
if (DIRECTORY_SEPARATOR !== '/') {
$path = str_replace(DIRECTORY_SEPARATOR, '/', $path);
}
$path = '/' . ltrim($path, '/');
return $path;
}
/**
* Return file path related to root dir
*
* @param string $path file path
* @return string
* @author Dmitry (dio) Levashov
**/
protected function _relpath($path) {
return $path;
}
/**
* Convert path related to root dir into real path
*
* @param string $path file path
* @return string
* @author Dmitry (dio) Levashov
**/
protected function _abspath($path) {
return $path;
}
/**
* Return fake path started from root dir
*
* @param string $path file path
* @return string
* @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
* @return bool
* @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
* @return array|false
* @author Dmitry (dio) Levashov
**/
protected function _stat($path) {
if ($this->isMyReload()) {
$this->refreshGoogleDriveToken();
}
if ($raw = $this->getDBdat($path)) {
return $this->parseRaw($raw);;
}
return false;
}
/**
* Return true if path is dir and has at least one childs directory
*
* @param string $path dir path
* @return bool
* @author Dmitry (dio) Levashov
**/
protected function _subdirs($path) {
return ($stat = $this->stat($path)) && isset($stat['dirs']) ? $stat['dirs'] : false;
}
/**
* 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
* @return string
* @author Dmitry (dio) Levashov
**/
protected function _dimensions($path, $mime) {
if (strpos($mime, 'image') !== 0) return '';
$cache = $this->getDBdat($path);
if (isset($cache['width']) && isset($cache['height'])) {
return $cache['width'].'x'.$cache['height'];
}
$ret = '';
if ($work = $this->getWorkFile($path)) {
if ($size = @getimagesize($work)) {
$cache['width'] = $size[0];
$cache['height'] = $size[1];
$this->updateDBdat($path, $cache);
$ret = $size[0].'x'.$size[1];
}
}
is_file($work) && @unlink($work);
return $ret;
}
/******************** file/dir content *********************/
/**
* Return files list in directory.
*
* @param string $path dir path
* @return array
* @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
* @return resource|false
* @author Dmitry (dio) Levashov
**/
protected function _fopen($path, $mode='rb') {
if (($mode == 'rb' || $mode == 'r')) {
try {
$res = $this->dropbox->media($path);
$url = parse_url($res['url']);
$fp = stream_socket_client('ssl://'.$url['host'].':443');
fputs($fp, "GET {$url['path']} HTTP/1.0\r\n");
fputs($fp, "Host: {$url['host']}\r\n");
fputs($fp, "\r\n");
while(trim(fgets($fp)) !== ''){};
return $fp;
} catch (Dropbox_Exception $e) {
return false;
}
}
if ($this->tmp) {
$contents = $this->_getContents($path);
if ($contents === false) {
return false;
}
if ($local = $this->getTempFile($path)) {
if (file_put_contents($local, $contents, LOCK_EX) !== false) {
return @fopen($local, $mode);
}
}
}
return false;
}
/**
* Close opened file
*
* @param resource $fp file pointer
* @return bool
* @author Dmitry (dio) Levashov
**/
protected function _fclose($fp, $path='') {
@fclose($fp);
if ($path) {
@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
* @return string|bool
* @author Dmitry (dio) Levashov
**/
protected function _mkdir($path, $name) {
//$path = $this->_normpath($path.'/'.$name);
// try {
// $this->dropbox->createFolder($path);
// } catch (Dropbox_Exception $e) {
// $this->deltaCheck();
// if ($this->dir($this->encode($path))) {
// return $path;
// }
// return $this->setError('Dropbox error: '.$e->getMessage());
// }
// $this->deltaCheck();
return $path;
}
/**
* Create file and return it's path or false on failed
*
* @param string $path parent dir path
* @param string $name new file name
* @return string|bool
* @author Dmitry (dio) Levashov
**/
protected function _mkfile($path, $name) {
return $this->_filePutContents($path.'/'.$name, '');
}
/**
* Create symlink. FTP driver does not support symlinks.
*
* @param string $target link target
* @param string $path symlink path
* @return bool
* @author Dmitry (dio) Levashov
**/
protected function _symlink($target, $path, $name) {
return false;
}
/**
* Copy file into another file
*
* @param string $source source file path
* @param string $targetDir target directory path
* @param string $name new file name
* @return bool
* @author Dmitry (dio) Levashov
**/
protected function _copy($source, $targetDir, $name) {
$path = $this->_normpath($targetDir.'/'.$name);
try {
$this->dropbox->copy($source, $path);
} catch (Dropbox_Exception $e) {
return $this->setError('Dropbox error: '.$e->getMessage());
}
$this->deltaCheck();
return true;
}
/**
* 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
* @return string|bool
* @author Dmitry (dio) Levashov
**/
protected function _move($source, $targetDir, $name) {
$target = $this->_normpath($targetDir.'/'.$name);
try {
$this->dropbox->move($source, $target);
} catch (Dropbox_Exception $e) {
return $this->setError('Dropbox error: '.$e->getMessage());
}
$this->deltaCheck();
return $target;
}
/**
* Remove file
*
* @param string $path file path
* @return bool
* @author Dmitry (dio) Levashov
**/
protected function _unlink($path) {
try {
$files = new Google_DriveFile();
//$this->oauth->files->delete(basename($path));
$this->oauth->files->trash(basename($path));
} catch (GoogleDrive_Exception $e) {
return $this->setError('GoogleDrive error: '.$e->getMessage());
}
return true;
}
/**
* Remove dir
*
* @param string $path dir path
* @return bool
* @author Dmitry (dio) Levashov
**/
protected function _rmdir($path) {
return $this->_unlink($path);
}
/**
* 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 $dir target dir path
* @param string $name file name
* @param array $stat file stat (required by some virtual fs)
* @return bool|string
* @author Dmitry (dio) Levashov
**/
protected function _save($fp, $path, $name, $stat) {
if ($name) $path .= '/'.$name;
$path = $this->_normpath($path);
try {
$this->dropbox->putFile($path, $fp);
} catch (Dropbox_Exception $e) {
return $this->setError('Dropbox error: '.$e->getMessage());
}
$this->deltaCheck();
if (is_array($stat)) {
$raw = $this->getDBdat($path);
if (isset($stat['width'])) $raw['width'] = $stat['width'];
if (isset($stat['height'])) $raw['height'] = $stat['height'];
$this->updateDBdat($path, $raw);
}
return $path;
}
/**
* Get file contents
*
* @param string $path file path
* @return string|false
* @author Dmitry (dio) Levashov
**/
protected function _getContents($path) {
$contents = '';
try {
$contents = $this->dropbox->getFile($path);
} catch (Dropbox_Exception $e) {
return $this->setError('Dropbox error: '.$e->getMessage());
}
return $contents;
}
/**
* Write a string to a file
*
* @param string $path file path
* @param string $content new file content
* @return bool
* @author Dmitry (dio) Levashov
**/
protected function _filePutContents($path, $content) {
$res = false;
if ($local = $this->getTempFile($path)) {
if (@file_put_contents($local, $content, LOCK_EX) !== false
&& ($fp = @fopen($local, 'rb'))) {
clearstatcache();
$res = $this->_save($fp, $path, '', array());
@fclose($fp);
}
file_exists($local) && @unlink($local);
}
return $res;
}
/**
* Detect available archivers
*
* @return void
**/
protected function _checkArchivers() {
// die('Not yet implemented. (_checkArchivers)');
return array();
}
/**
* chmod implementation
*
* @return bool
**/
protected function _chmod($path, $mode) {
return false;
}
/**
* Unpack archive
*
* @param string $path archive path
* @param array $arc archiver command and arguments (same as in $this->archivers)
* @return true
* @return void
* @author Dmitry (dio) Levashov
* @author Alexey Sukhotin
**/
protected function _unpack($path, $arc) {
die('Not yet implemented. (_unpack)');
return false;
}
/**
* Recursive symlinks search
*
* @param string $path file/dir path
* @return bool
* @author Dmitry (dio) Levashov
**/
protected function _findSymlinks($path) {
die('Not yet implemented. (_findSymlinks)');
if (is_link($path)) {
return true;
}
if (is_dir($path)) {
foreach (scandir($path) as $name) {
if ($name != '.' && $name != '..') {
$p = $path.DIRECTORY_SEPARATOR.$name;
if (is_link($p)) {
return true;
}
if (is_dir($p) && $this->_findSymlinks($p)) {
return true;
} elseif (is_file($p)) {
$this->archiveSize += filesize($p);
}
}
}
} else {
$this->archiveSize += filesize($path);
}
return false;
}
/**
* Extract files from archive
*
* @param string $path archive path
* @param array $arc archiver command and arguments (same as in $this->archivers)
* @return true
* @author Dmitry (dio) Levashov,
* @author Alexey Sukhotin
**/
protected function _extract($path, $arc) {
die('Not yet implemented. (_extract)');
}
/**
* Create archive and return its path
*
* @param string $dir target dir
* @param array $files files names list
* @param string $name archive name
* @param array $arc archiver options
* @return string|bool
* @author Dmitry (dio) Levashov,
* @author Alexey Sukhotin
**/
protected function _archive($dir, $files, $name, $arc) {
die('Not yet implemented. (_archive)');
return false;
}
} // END class
now is working with mount root or child folder /foldername/foldername/folderrname like dropbox class
<?php
elFinder::$netDrivers['googledrive'] = 'GoogleDrive';
/**
* Simple elFinder driver for GoogleDrive
*
* @author Dmitry (dio) Levashov
* @author Cem (discofever)
* @author Raja Sharma - updating for GoogleDrive
**/
class elFinderVolumeGoogleDrive extends elFinderVolumeDriver {
/**
* Driver id
* Must be started from letter and contains [a-z0-9]
* Used as part of volume id
*
* @var string
**/
protected $driverId = 'gd';
/**
* OAuth object
*
* @var oauth
**/
protected $oauth = null;
//protected $client = null;
/**
* GoogleDrive object
*
* @var googledrive
**/
protected $googledrive = null;
/**
* Fetch fields setting for list
*
* @var string
*/
const FETCHFIELDS_LIST = 'files(id,mimeType,modifiedTime,name,parents,permissions,size,webContentLink),nextPageToken';
/**
* Fetch fields setting for get
*
* @var string
*/
const FETCHFIELDS_GET = 'id,name,mimeType,modifiedTime,parents,permissions,size,webContentLink';
/**
* MIME tyoe of directory
*
* @var string
*/
const DIRMIME = 'application/vnd.google-apps.folder';
/**
* Google_Service_Drive instance
*
* @var Google_Service_Drive
*/
protected $service;
/**
* Default options
*
* @var array
*/
protected static $defaultOptions = [
'spaces' => 'drive',
'useHasDir' => false,
'publishPermission' => [
'type' => 'anyone',
'role' => 'reader',
'withLink' => true
]
];
/**
* A comma-separated list of spaces to query
* Supported values are 'drive', 'appDataFolder' and 'photos'
*
* @var string
*/
protected $spaces;
/**
* Permission array as published item
*
* @var array
*/
protected $publishPermission;
/**
* Cache of file objects
*
* @var array
*/
private $cacheFileObjects = [];
/**
* Cache of hasDir
*
* @var array
*/
private $cacheHasDirs = [];
/**
* Use hasDir function
*
* @var bool
*/
private $useHasDir = false;
/**
* Directory for meta data caches
* If not set driver not cache meta data
*
* @var string
**/
protected $metaCache = '';
/**
* Last API error message
*
* @var string
**/
protected $apiError = '';
/**
* Directory for tmp files
* If not set driver will try to use tmbDir as tmpDir
*
* @var string
**/
protected $tmp = '';
/**
* Net mount key
*
* @var string
**/
public $netMountKey = '';
/**
* drive.google.com uid
*
* @var string
**/
protected $googledriveUid = '';
/**
* Gdrive download host, replaces 'drive.google.com' of shares URL
*
* @var string
*/
private $googledrive_dlhost = 'drive.google.com';
private $googledrive_phpFound = false;
private $DB_TableName = '';
private $tmbPrefix = '';
/**
* Constructor
* Extend options with required fields
*
* @return void
* @author Dmitry (dio) Levashov
* @author Cem (DiscoFever)
**/
public function __construct() {
//ini_set('memory_limit', '128M');
@ include_once 'google-api-php-client/src/Google_Client.php';
@ include_once 'google-api-php-client/src/contrib/Google_DriveService.php';
@ include_once 'google-api-php-client/src/contrib/Google_Oauth2Service.php';
//$this->gdrive_phpFound = in_array('setClientId', 'setClientSecret', 'setRedirectUri');
$opts = array(
'clientId' => '',
'clientSecret' => '',
'redirecturi' => '',
'accessToken' => '',
'accessTokenSecret' => '',
'googledriveUid' => '',
'root' => 'GoogleDrive',
'path' => '/',
'childpath' => '',
'separator' => '/',
'PDO_DSN' => '', // if empty use 'sqlite:(metaCachePath|tmbPath)/elFinder_dropbox_db_(hash:googledriveUid+consumerSecret)'
'PDO_User' => '',
'PDO_Pass' => '',
'PDO_Options' => array(),
'PDO_DBName' => 'googledrive',
'treeDeep' => 0,
'tmbPath' => '../files/.tmb',
'tmbURL' => dirname($_SERVER['PHP_SELF']) . '/../files/.tmb',
'tmpPath' => '../files/.tmp',
'getTmbSize' => 'large', // small: 32x32, medium or s: 64x64, large or m: 128x128, l: 640x480, xl: 1024x768
'metaCachePath' => '',
'metaCacheTime' => '600', // 10m
'acceptedName' => '#^[^/\\?*:|"<>]*[^./\\?*:|"<>]$#',
'rootCssClass' => 'elfinder-navbar-root-googledrive'
);
$this->options = array_merge($this->options, $opts);
$this->options['mimeDetect'] = 'internal';
}
/**
* Prepare
* Call from elFinder::netmout() before volume->mount()
*
* @return Array
* @author Naoki Sawada
* @author Raja Sharma updating for GoogleDrive
**/
public function netmountPrepare($options) {
if (empty($options['clientId']) && defined('ELFINDER_GDRIVE_CLIENTID')) $options['clientId'] = ELFINDER_GDRIVE_CLIENTID;
if (empty($options['clientSecret']) && defined('ELFINDER_GDRIVE_CLIENTSECRET')) $options['clientSecret'] = ELFINDER_GDRIVE_CLIENTSECRET;
if (empty($options['redirecturi']) && defined('ELFINDER_GDRIVE_REDIRECTURI')) $options['redirecturi'] = ELFINDER_GDRIVE_REDIRECTURI;
if ($options['callback']=='true' && isset($_GET['code'])) {
session_start();
include_once 'google-api-php-client/src/Google_Client.php';
include_once 'google-api-php-client/src/contrib/Google_DriveService.php';
include_once 'google-api-php-client/src/contrib/Google_Oauth2Service.php';
$client = new Google_Client();
$client->setClientId($options['clientId']);
$client->setClientSecret($options['clientSecret']);
$client->setRedirectUri($options['redirecturi']);
$client->setScopes(array('https://www.googleapis.com/auth/drive https://www.googleapis.com/auth/userinfo.profile'));
$oauth2 = new Google_Oauth2Service($client);
$accessToken = $client->authenticate($_GET['code']);
$tokens = base64_encode($client->getAccessToken());
$callback_url = $_SESSION['callback'];
$userinfo = $oauth2->userinfo->get();
unset($_SESSION['callback']);
$objurl= array();
foreach (explode('&', $callback_url) as $chunk) {
$param = explode("=", $chunk);
if ($param) {
$objurl[urldecode($param[0])]=urldecode($param[1]);
}
}
$callback_url = $options['redirecturi'].'?node='.$objurl['node'].'&protocol='.$objurl['protocol'].'&uid='.$userinfo['id'].'&cmd=netmount&host='.$objurl['host'].'&code='.$_GET['code'].'&oauth_token='.$tokens.'&user='.$objurl['user'].'&pass=return'.'&_='.$objurl['_'];
header("Location: ".$callback_url);
exit();
}
if ($options['user'] === 'init') {
if (empty($options['clientId']) || empty($options['clientSecret']) || empty($options['redirecturi'])) {
return array('exit' => true, 'body' => '{msg:errNetMountNoDriver}');
}
try{
$this->oauth = new Google_Client();
}catch (Exception $e){
return array('exit' => true, 'body' => '{msg:errNetMountNoDriver}');
}
if ($options['pass'] === 'init') {
$html = '';
if (isset($_SESSION['elFinderGoogledriveTokens'])) {
// token check
try {
list($options['googledriveUid'], $options['accessToken']) = $_SESSION['elFinderGoogledriveTokens'];
$this->oauth->setAccessToken($_SESSION['elFinderGoogleDriveAuthTokens']);
$oauth_token = $this->oauth->getAccessToken();
$oauth2 = new Google_Oauth2Service($this->oauth);
$userid = $oauth2->userinfo->get();
$script = '<script>
$("#'.$options['id'].'").elfinder("instance").trigger("netmount", {protocol: "googledrive", mode: "done"});
</script>';
$html = $script;
} catch (GoogleDrive_Exception $e) {
unset($_SESSION['elFinderGoogledriveTokens']);
unset($_SESSION['elFinderGoogleDriveAuthTokens']);
}
}
if (! $html && !isset($_SESSION['elFinderGoogledriveTokens'])) {
// get customdata
$cdata = '';
$innerKeys = array('cmd', 'host', 'options', 'pass', 'protocol', 'user');
$this->ARGS = $_SERVER['REQUEST_METHOD'] === 'POST'? $_POST : $_GET;
foreach($this->ARGS as $k => $v) {
if (! in_array($k, $innerKeys)) {
$cdata .= '&' . $k . '=' . rawurlencode($v);
}
}
if (strpos($options['url'], 'http') !== 0 ) {
$options['url'] = $this->getConnectorUrl();
}
$callback = $options['url']
. '?cmd=netmount&protocol=googledrive&host=googledrive.com&user=init&pass=return&node='.$options['id'].$cdata;
$_SESSION['callback'] = $callback;
try {
$client = new Google_Client();
// Get your credentials from the console
$client->setClientId($options['clientId']);
$client->setClientSecret($options['clientSecret']);
$client->setRedirectUri($options['redirecturi']);
$client->setScopes(array('https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/drive https://www.googleapis.com/auth/drive.file https://www.googleapis.com/auth/drive.metadata'));
$client->setAccessType('online');
$client->setApprovalPrompt('force');
$service = new Google_DriveService($client);
$this->oauth = $client->createAuthUrl();
$url = $this->oauth.='&oauth_callback=' . rawurlencode($callback);
} catch (GoogleDrive_Exception $e) {
return array('exit' => true, 'body' => '{msg:errAccess}');
}
$_SESSION['elFinderGoogleDriveAuthTokens'] = $tokens;
$html = '<input id="elf-volumedriver-googledrive-host-btn" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" value="{msg:btnApprove}" type="button" onclick="window.open(\''.$url.'\')">';
$html .= '<script>
$("#'.$options['id'].'").elfinder("instance").trigger("netmount", {protocol: "googledrive", mode: "makebtn"});
</script>';
}
return array('exit' => true, 'body' => $html);
} else {
if (isset($_GET['oauth_token'])) {
$_SESSION['elFinderGoogleDriveAuthTokens'] = base64_decode($_GET["oauth_token"]);
}
$client = new Google_Client();
$client->setAccessToken($_SESSION['elFinderGoogleDriveAuthTokens']);
//unset($_SESSION['elFinderGoogleDriveAuthTokens']);
$oauth_token = $client->getAccessToken();
$oauth2 = new Google_Oauth2Service($client);
$userid = $oauth2->userinfo->get();
$_SESSION['elFinderGoogledriveTokens'] = array($userid['id'], $oauth_token);
$out = array(
'node' => $_GET['node'],
'json' => '{"protocol": "googledrive", "mode": "done"}',
'bind' => 'netmount'
);
return array('exit' => 'callback', 'out' => $out);
}
}
if (isset($_SESSION['elFinderGoogledriveTokens'])) {
list($options['googledriveUid'], $options['accessToken']) = $_SESSION['elFinderGoogledriveTokens'];
}
unset($options['user'], $options['pass']);
return $options;
}
/**
* process of on netunmount
* Drop `googledrive` & rm thumbs
*
* @param array $options
* @return boolean
*/
public function netunmount($netVolumes, $key) {
$count = 0;
$googledriveUid = '';
if (isset($netVolumes[$key])) {
$googledriveUid = $netVolumes[$key]['googledriveUid'];
}
foreach($netVolumes as $volume) {
if (@$volume['host'] === 'googledrive' && @$volume['googledriveUid'] === $googledriveUid) {
$count++;
}
}
if ($count === 1) {
foreach(glob(rtrim($this->options['tmbPath'], '\\/').DIRECTORY_SEPARATOR.$this->tmbPrefix.'*.png') as $tmb) {
unlink($tmb);
}
}
return true;
}
/**
* Get script url
*
* @return string full URL
* @author Naoki Sawada
*/
private function getConnectorUrl() {
$url = ((isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'off')? 'https://' : 'http://')
. $_SERVER['SERVER_NAME'] // host
. ($_SERVER['SERVER_PORT'] == 80 ? '' : ':' . $_SERVER['SERVER_PORT']) // port
. $_SERVER['REQUEST_URI']; // path & query
list($url) = explode('?', $url);
return $url;
}
/*********************************************************************/
/* INIT AND CONFIGURE */
/*********************************************************************/
/**
* Prepare FTP connection
* Connect to remote server and check if credentials are correct, if so, store the connection id in $ftp_conn
*
* @return bool
* @author Dmitry (dio) Levashov
* @author Cem (DiscoFever)
**/
protected function init() {
if (!$this->options['googledriveUid']
|| !$this->options['accessToken']) {
return $this->setError('Required options undefined.');
}
// make net mount key
$this->netMountKey = md5(join('-', array('googledrive', $this->options['path'])));
if (! $this->oauth) {
$client = new Google_Client();
$client->setAccessToken($_SESSION['elFinderGoogleDriveAuthTokens']);
$this->oauth = new Google_DriveService($client);
}
if (! $this->oauth) {
return $this->setError('OAuth extension not loaded.');
}
// normalize root path
if($this->_normpath($this->options['path']) == '/'){
$this->root = $this->options['path'] = $this->_normpath($this->options['path']);
}else{
$this->options['childpath'] = $this->options['path'];
$this->options['path'] = $this->getRealpath($this->options['path']);
$this->root = $this->options['path'] = $this->_normpath($this->options['path']);
}
if (empty($this->options['alias'])) {
$this->options['alias'] = ($this->options['path'] === '/')? 'GoogleDrive.com' : 'GoogleDrive'.$this->options['childpath'];
}
$this->rootName = $this->options['alias'];
$this->googledriveUid = $this->options['googledriveUid'];
$this->tmbPrefix = 'googledrive'.base_convert($this->googledriveUid, 10, 32);
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 && is_writable($this->options['tmbPath'])) {
$this->tmp = $this->options['tmbPath'];
}
if (!$this->tmp && ($tmp = elFinder::getStaticVar('commonTempPath'))) {
$this->tmp = $tmp;
}
if (!empty($this->options['metaCachePath'])) {
if ((is_dir($this->options['metaCachePath']) || @mkdir($this->options['metaCachePath'])) && is_writable($this->options['metaCachePath'])) {
$this->metaCache = $this->options['metaCachePath'];
}
}
if (!$this->metaCache && $this->tmp) {
$this->metaCache = $this->tmp;
}
if (!$this->metaCache) {
return $this->setError('Cache dirctory (metaCachePath or tmp) is require.');
}
if (is_null($this->options['syncChkAsTs'])) {
$this->options['syncChkAsTs'] = true;
}
if ($this->options['syncChkAsTs']) {
// 'tsPlSleep' minmum 5 sec
$this->options['tsPlSleep'] = max(5, $this->options['tsPlSleep']);
} else {
// 'lsPlSleep' minmum 10 sec
$this->options['lsPlSleep'] = max(10, $this->options['lsPlSleep']);
}
return true;
}
/**
* Configure after successfull mount.
*
* @return void
* @author Dmitry (dio) Levashov
**/
protected function configure() {
parent::configure();
if (!$this->tmp) {
$this->disabled[] = 'archive';
$this->disabled[] = 'extract';
}
}
/**
* Drive query and fetchAll
*
* @param string $sql
* @return boolean|array
*/
private function query($sql,$path) {
$files = new Google_DriveFile();
$curlres =array();
$path == '/' ? $fpath = '/' : $fpath = $path.'/';
$file = $this->oauth->files->listFiles($sql);
$i=0;
$j=0;
if($fpath == '/'){
$curlres[$j] = ['path'=>'/','id'=>NULL, 'name'=>'', 'size'=>'', 'modifiedTime'=>NULL, 'mimeType'=>'application/vnd.google-apps.folder', 'parents'=>'', 'read'=>'1', 'write'=>'1', 'locked'=>'0', 'hidden'=>'0', 'width'=>'', 'height'=>'', 'url'=>'','tmbUrl'=>''];
$j++;
}
if($fpath !== '/'){
$child = $this->oauth->files->get(basename($path));
$curlres[$j] = ['path'=>$path,'id'=>$child['id'], 'name'=>$child['title'], 'size'=>$child['childSize'], 'modifiedTime'=>$child['modifiedDate'], 'mimeType'=>$child['mimeType'], 'childs'=>$child[0]['childs'][0]['id'], 'read'=>'1', 'write'=>'1', 'locked'=>$child['labels']['restricted'], 'hidden'=>$child['labels']['hidden'], 'width'=>$child['imageMediaMetadata']['width'], 'height'=>$child['imageMediaMetadata']['height'], 'url'=>$child['alternateLink'],'tmbUrl'=>$child['thumbnailLink']];
$j++;
}
while($file['items'][$i]['id']){
$curlres[$j] = ['path'=>$fpath.$file['items'][$i]['id'],'id'=>$file['items'][$i]['id'], 'name'=>$file['items'][$i]['title'], 'size'=>$file['items'][$i]['fileSize'], 'modifiedTime'=>$file['items'][$i]['modifiedDate'], 'mimeType'=>$file['items'][$i]['mimeType'], 'parents'=>$file['items'][0]['parents'][0]['id'], 'read'=>'1', 'write'=>'1', 'locked'=>$file['items'][$i]['labels']['restricted'], 'hidden'=>$file['items'][$i]['labels']['hidden'], 'width'=>$file['items'][$i]['imageMediaMetadata']['width'], 'height'=>$file['items'][$i]['imageMediaMetadata']['height'], 'url'=>$file['items'][$i]['alternateLink'],'tmbUrl'=>$file['items'][$i]['thumbnailLink']];
$i++;
$j++;
}
return $curlres;
}
/**
* Get token and auto refresh
*
* @param boolean $refresh force refresh
* @return true|string error message
*/
private function refreshGoogleDriveToken($refresh = true) {
try {
$client = new Google_Client();
$google_token = $_SESSION['elFinderGoogleDriveAuthTokens'];
//$client->refreshToken($google_token->refresh_token);
$client->setAccessToken($_SESSION['elFinderGoogleDriveAuthTokens']);
$_SESSION['elFinderGoogleDriveAuthTokens'] = $client->getAccessToken();
$this->oauth = new Google_DriveService($client);
} catch(GoogleDrive_Exception $e) {
return $e->getMessage();
}
return true;
}
/**
* Get child directory real path with mount
*
* @return realpath|string error message
*/
private function getRealpath($path) {
$temppath = explode('/',$path);
$temppath[0] == '' ? $itemId= 'root' : $itemId= $temppath[0];
$path== '/' || $path=='root' || $temppath[0]== '' || $temppath[0]== '/'? $itemId= 'root' : $itemId = basename($path);
foreach($temppath as $tpath) {
$opts = [
'q' => sprintf('trashed=false and "%s" in parents and mimeType = "%s"', basename($itemId), self::DIRMIME)
];
$this->refreshGoogleDriveToken();
$files = new Google_DriveFile();
$file = $this->oauth->files->listFiles($opts);
$i=0;
while($file['items'][$i]['id']){
if($file['items'][$i]['title'] == $tpath || $file['items'][$i]['id'] ==$tpath ){
$itemId = $itemId.'/'.$file['items'][$i]['id'];
break;
}
$i++;
}
}
return substr($itemId,4);
}
/**
* Get dat(googledrive metadata) from GoogleDrive
*
* @param string $path
* @return array googledrive metadata
*/
private function getDBdat($path) {
$path == '/' || $path =='root' ? $itemId= 'root' : $itemId= basename($path);
$opts = [
'q' => sprintf('trashed=false and "%s" in parents', $itemId)
];
if($res = $this->query($opts,$path)) {
return $res[0];
} else {
return array();
}
}
/**
* Update DB dat(dropbox metadata)
*
* @param string $path
* @param array $dat
* @return bool|array
*/
private function updateDBdat($path, $dat) {
return $this->query('update '.$this->DB_TableName.' set dat='.$this->DB->quote(serialize($dat))
. ', isdir=' . ($dat['is_dir']? 1 : 0)
. ' where path='.$this->DB->quote(strtolower($this->_dirname($path))).' and fname='.$this->DB->quote(strtolower(basename($path))));
}
/*********************************************************************/
/* FS API */
/*********************************************************************/
/**
* Close opened connection
*
* @return void
* @author Dmitry (dio) Levashov
**/
public function umount() {
}
/**
* Get delta data and DB update
*
* @param boolean $refresh force refresh
* @return true|string error message
*/
/**
* Parse line from googledrive metadata output and return file stat (array)
*
* @param string $raw line from ftp_rawlist() output
* @return array
* @author Dmitry Levashov
**/
protected function parseRaw($raw) {
$stat = array();
$stat['rev'] = isset($raw['id']) ? $raw['id'] : 'root';
$stat['name'] = basename($raw['name']);
$stat['mime'] = $raw['mimeType']== self::DIRMIME ? 'directory' : $raw['mimeType'];
$stat['size'] = $raw['mimeType']== self::DIRMIME ? 0 : (int)$raw['size'];
$stat['ts'] = isset($raw['modifiedTime']) ? strtotime($raw['modifiedTime']) : $_SERVER['REQUEST_TIME'];
$stat['tmbUrl'] = $raw['tmbUrl'];
$stat['dirs'] = $raw['mimeType']== self::DIRMIME ? 1 : 0;
if (!empty($raw['url'])) {
$stat['url'] = $raw['url'];
} else {
$stat['url'] = '1';
}
isset($raw['width']) ? $stat['width'] = $raw['width'] : $stat['width'] = 0;
isset($raw['height'])? $stat['height'] = $raw['height'] : $stat['height'] = 0;
return $stat;
}
/**
* Cache dir contents
*
* @param string $path dir path
* @return void
* @author Dmitry Levashov
**/
protected function cacheDir($path) {
$path == '/' || $path =='root' ? $itemId= 'root' : $itemId = basename($path);
$opts = [
// 'pageSize' => $maxResults ? : 1000,
// 'q' => sprintf('trashed=false and "%s" in parents and mimeType = "%s"', $itemID, self::DIRMIME)
'q' => sprintf('trashed=false and "%s" in parents',$itemId)
];
$this->dirsCache[$path] = array();
$res = $this->query($opts,$path);
if ($res) {
foreach($res as $raw) {
if ($stat = $this->parseRaw($raw)) {
$stat = $this->updateCache($raw['path'], $stat);
if (empty($stat['hidden']) && $path !== $raw['path']) {
$this->dirsCache[$path][] = $raw['path'];
}
}
}
}
return $this->dirsCache[$path];
}
/**
* Recursive files search
*
* @param string $path dir path
* @param string $q search string
* @param array $mimes
* @return array
* @author Naoki Sawada
**/
protected function doSearch($path, $q, $mimes) {
$result = array();
$sth = $this->DB->prepare('select dat from '.$this->DB_TableName.' WHERE path LIKE ? AND fname LIKE ?');
$sth->execute(array((($path === '/')? '' : strtolower($path)).'%', '%'.strtolower($q).'%'));
$res = $sth->fetchAll(PDO::FETCH_COLUMN);
$timeout = $this->options['searchTimeout']? $this->searchStart + $this->options['searchTimeout'] : 0;
if ($res) {
foreach($res as $raw) {
if ($timeout && $timeout < time()) {
$this->setError(elFinder::ERROR_SEARCH_TIMEOUT, $this->path($this->encode($path)));
break;
}
$raw = unserialize($raw);
if ($stat = $this->parseRaw($raw)) {
if (!isset($this->cache[$raw['path']])) {
$stat = $this->updateCache($raw['path'], $stat);
}
if (!empty($stat['hidden']) || ($mimes && $stat['mime'] === 'directory') || !$this->mimeAccepted($stat['mime'], $mimes)) {
continue;
}
$stat = $this->stat($raw['path']);
$stat['path'] = $this->path($stat['hash']);
$result[] = $stat;
}
}
}
return $result;
}
/**
* 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)
* @return string|false
* @author Dmitry (dio) Levashov
* @author Naoki Sawada
**/
protected function copy($src, $dst, $name) {
$this->clearcache();
return $this->_copy($src, $dst, $name)
? $this->_joinPath($dst, $name)
: $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
* @return bool
* @author Dmitry (dio) Levashov
* @author Naoki Sawada
**/
protected function remove($path, $force = false, $recursive = false) {
$stat = $this->stat($path);
$stat['realpath'] = $path;
$this->rmTmb($stat);
$this->clearcache();
if (empty($stat)) {
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));
}
} else {
if (!$recursive && !$this->_unlink($path)) {
return $this->setError(elFinder::ERROR_RM, $this->_path($path));
}
}
$this->removed[] = $stat;
return true;
}
/**
* Create thumnbnail and return it's URL on success
*
* @param string $path file path
* @param string $mime file mime type
* @return string|false
* @author Dmitry (dio) Levashov
* @author Naoki Sawada
**/
protected function createTmb($path, $stat) {
if (!$stat || !$this->canCreateTmb($path, $stat)) {
return false;
}
$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->getThumbnail($path, $this->options['getTmbSize'])) {
return false;
}
if (! file_put_contents($tmb, $data)) {
return false;
}
$result = false;
$tmbSize = $this->tmbSize;
if (($s = getimagesize($tmb)) == false) {
return 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' );
} else {
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 (($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');
}
} else {
$result = $this->imgResize($tmb, $tmbSize, $tmbSize, true, true, 'png');
}
$result = $this->imgSquareFit($tmb, $tmbSize, $tmbSize, 'center', 'middle', $this->options['tmbBgColor'], 'png' );
}
if (!$result) {
unlink($tmb);
return false;
}
return $name;
}
/**
* Return thumbnail file name for required file
*
* @param array $stat file stat
* @return string
* @author Dmitry (dio) Levashov
**/
protected function tmbname($stat) {
return $this->tmbPrefix.$stat['rev'].'.png';
}
/**
* Get thumbnail from dropbox.com
* @param string $path
* @param string $size
* @return string | boolean
*/
protected function getThumbnail($path, $size = 'small') {
$opts = [
'q' => sprintf('trashed=false and "%s" in parents',basename($path))
];
try {
$res = $this->query($opts,$path);
$res = file_get_contents($res[0]['tmbUrl']);
return $res;
} catch (GoogleDrive_Exception $e) {
return false;
}
}
/**
* Return content URL
*
* @param string $hash file hash
* @param array $options options
* @return array
* @author Naoki Sawada
**/
public function getContentUrl($hash, $options = array()) {
if (($file = $this->file($hash)) == false || !$file['url'] || $file['url'] == 1) {
$path = $this->decode($hash);
$cache = $this->getDBdat($path);
$url = '';
if (isset($cache['share']) && strpos($cache['share'], $this->googledrive_dlhost) !== false) {
$res = $this->getHttpResponseHeader($cache['share']);
if (preg_match("/^HTTP\/[01\.]+ ([0-9]{3})/", $res, $match)) {
if ($match[1] < 400) {
$url = $cache['share'];
}
}
}
if (! $url) {
try {
$res = $this->googledrive->share($path, null, false);
$url = $res['url'];
if (strpos($url, 'www.drive.google.com') === false) {
$res = $this->getHttpResponseHeader($url);
if (preg_match('/^location:\s*(http[^\s]+)/im', $res, $match)) {
$url = $match[1];
}
}
list($url) = explode('?', $url);
$url = str_replace('www.drive.google.com', $this->googledrive_dlhost, $url);
if (! isset($cache['share']) || $cache['share'] !== $url) {
$cache['share'] = $url;
$this->updateDBdat($path, $cache);
}
} catch (GoogleDrive_Exception $e) {
return false;
}
}
return $url;
}
return $file['url'];
}
/**
* Get HTTP request response header string
*
* @param string $url target URL
* @return string
* @author Naoki Sawada
*/
private function getHttpResponseHeader($url) {
if (function_exists('curl_exec')) {
$c = curl_init();
curl_setopt( $c, CURLOPT_RETURNTRANSFER, true );
curl_setopt( $c, CURLOPT_CUSTOMREQUEST, 'HEAD' );
curl_setopt( $c, CURLOPT_HEADER, 1 );
curl_setopt( $c, CURLOPT_NOBODY, true );
curl_setopt( $c, CURLOPT_URL, $url );
$res = curl_exec( $c );
} else {
require_once 'HTTP/Request2.php';
try {
$request2 = new HTTP_Request2();
$request2->setConfig(array(
'ssl_verify_peer' => false,
'ssl_verify_host' => false
));
$request2->setUrl($url);
$request2->setMethod(HTTP_Request2::METHOD_HEAD);
$result = $request2->send();
$res = array();
$res[] = 'HTTP/'.$result->getVersion().' '.$result->getStatus().' '.$result->getReasonPhrase();
foreach($result->getHeader() as $key => $val) {
$res[] = $key . ': ' . $val;
}
$res = join("\r\n", $res);
} catch( HTTP_Request2_Exception $e ){
$res = '';
} catch (Exception $e){
$res = '';
}
}
return $res;
}
/*********************** paths/urls *************************/
/**
* Return parent directory path
*
* @param string $path file path
* @return string
* @author Dmitry (dio) Levashov
**/
protected function _dirname($path) {
return $this->_normpath(dirname($path));
}
/**
* Return file name
*
* @param string $path file path
* @return string
* @author Dmitry (dio) Levashov
**/
protected function _basename($path) {
return basename($path);
}
/**
* Join dir name and file name and retur full path
*
* @param string $dir
* @param string $name
* @return string
* @author Dmitry (dio) Levashov
**/
protected function _joinPath($dir, $name) {
return $this->_normpath($dir.'/'.$name);
}
/**
* Return normalized path, this works the same as os.path.normpath() in Python
*
* @param string $path path
* @return string
* @author Troex Nevelin
**/
protected function _normpath($path) {
if (DIRECTORY_SEPARATOR !== '/') {
$path = str_replace(DIRECTORY_SEPARATOR, '/', $path);
}
$path = '/' . ltrim($path, '/');
return $path;
}
/**
* Return file path related to root dir
*
* @param string $path file path
* @return string
* @author Dmitry (dio) Levashov
**/
protected function _relpath($path) {
return $path;
}
/**
* Convert path related to root dir into real path
*
* @param string $path file path
* @return string
* @author Dmitry (dio) Levashov
**/
protected function _abspath($path) {
return $path;
}
/**
* Return fake path started from root dir
*
* @param string $path file path
* @return string
* @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
* @return bool
* @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
* @return array|false
* @author Dmitry (dio) Levashov
**/
protected function _stat($path) {
if ($this->isMyReload()) {
$this->refreshGoogleDriveToken();
}
if ($raw = $this->getDBdat($path)) {
return $this->parseRaw($raw);;
}
return false;
}
/**
* Return true if path is dir and has at least one childs directory
*
* @param string $path dir path
* @return bool
* @author Dmitry (dio) Levashov
**/
protected function _subdirs($path) {
return ($stat = $this->stat($path)) && isset($stat['dirs']) ? $stat['dirs'] : false;
}
/**
* 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
* @return string
* @author Dmitry (dio) Levashov
**/
protected function _dimensions($path, $mime) {
if (strpos($mime, 'image') !== 0) return '';
$cache = $this->getDBdat($path);
if (isset($cache['width']) && isset($cache['height'])) {
return $cache['width'].'x'.$cache['height'];
}
$ret = '';
if ($work = $this->getWorkFile($path)) {
if ($size = @getimagesize($work)) {
$cache['width'] = $size[0];
$cache['height'] = $size[1];
$this->updateDBdat($path, $cache);
$ret = $size[0].'x'.$size[1];
}
}
is_file($work) && @unlink($work);
return $ret;
}
/******************** file/dir content *********************/
/**
* Return files list in directory.
*
* @param string $path dir path
* @return array
* @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
* @return resource|false
* @author Dmitry (dio) Levashov
**/
protected function _fopen($path, $mode='rb') {
if (($mode == 'rb' || $mode == 'r')) {
try {
$res = $this->dropbox->media($path);
$url = parse_url($res['url']);
$fp = stream_socket_client('ssl://'.$url['host'].':443');
fputs($fp, "GET {$url['path']} HTTP/1.0\r\n");
fputs($fp, "Host: {$url['host']}\r\n");
fputs($fp, "\r\n");
while(trim(fgets($fp)) !== ''){};
return $fp;
} catch (Dropbox_Exception $e) {
return false;
}
}
if ($this->tmp) {
$contents = $this->_getContents($path);
if ($contents === false) {
return false;
}
if ($local = $this->getTempFile($path)) {
if (file_put_contents($local, $contents, LOCK_EX) !== false) {
return @fopen($local, $mode);
}
}
}
return false;
}
/**
* Close opened file
*
* @param resource $fp file pointer
* @return bool
* @author Dmitry (dio) Levashov
**/
protected function _fclose($fp, $path='') {
@fclose($fp);
if ($path) {
@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
* @return string|bool
* @author Dmitry (dio) Levashov
**/
protected function _mkdir($path, $name) {
//$path = $this->_normpath($path.'/'.$name);
// try {
// $this->dropbox->createFolder($path);
// } catch (Dropbox_Exception $e) {
// $this->deltaCheck();
// if ($this->dir($this->encode($path))) {
// return $path;
// }
// return $this->setError('Dropbox error: '.$e->getMessage());
// }
// $this->deltaCheck();
return $path;
}
/**
* Create file and return it's path or false on failed
*
* @param string $path parent dir path
* @param string $name new file name
* @return string|bool
* @author Dmitry (dio) Levashov
**/
protected function _mkfile($path, $name) {
return $this->_filePutContents($path.'/'.$name, '');
}
/**
* Create symlink. FTP driver does not support symlinks.
*
* @param string $target link target
* @param string $path symlink path
* @return bool
* @author Dmitry (dio) Levashov
**/
protected function _symlink($target, $path, $name) {
return false;
}
/**
* Copy file into another file
*
* @param string $source source file path
* @param string $targetDir target directory path
* @param string $name new file name
* @return bool
* @author Dmitry (dio) Levashov
**/
protected function _copy($source, $targetDir, $name) {
$path = $this->_normpath($targetDir.'/'.$name);
try {
$this->dropbox->copy($source, $path);
} catch (Dropbox_Exception $e) {
return $this->setError('Dropbox error: '.$e->getMessage());
}
$this->deltaCheck();
return true;
}
/**
* 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
* @return string|bool
* @author Dmitry (dio) Levashov
**/
protected function _move($source, $targetDir, $name) {
$target = $this->_normpath($targetDir.'/'.$name);
try {
$this->dropbox->move($source, $target);
} catch (Dropbox_Exception $e) {
return $this->setError('Dropbox error: '.$e->getMessage());
}
$this->deltaCheck();
return $target;
}
/**
* Remove file
*
* @param string $path file path
* @return bool
* @author Dmitry (dio) Levashov
**/
protected function _unlink($path) {
try {
$files = new Google_DriveFile();
//$this->oauth->files->delete(basename($path));
$this->oauth->files->trash(basename($path));
} catch (GoogleDrive_Exception $e) {
return $this->setError('GoogleDrive error: '.$e->getMessage());
}
return true;
}
/**
* Remove dir
*
* @param string $path dir path
* @return bool
* @author Dmitry (dio) Levashov
**/
protected function _rmdir($path) {
return $this->_unlink($path);
}
/**
* 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 $dir target dir path
* @param string $name file name
* @param array $stat file stat (required by some virtual fs)
* @return bool|string
* @author Dmitry (dio) Levashov
**/
protected function _save($fp, $path, $name, $stat) {
if ($name) $path .= '/'.$name;
$path = $this->_normpath($path);
try {
$this->dropbox->putFile($path, $fp);
} catch (Dropbox_Exception $e) {
return $this->setError('Dropbox error: '.$e->getMessage());
}
$this->deltaCheck();
if (is_array($stat)) {
$raw = $this->getDBdat($path);
if (isset($stat['width'])) $raw['width'] = $stat['width'];
if (isset($stat['height'])) $raw['height'] = $stat['height'];
$this->updateDBdat($path, $raw);
}
return $path;
}
/**
* Get file contents
*
* @param string $path file path
* @return string|false
* @author Dmitry (dio) Levashov
**/
protected function _getContents($path) {
$contents = '';
try {
$contents = $this->dropbox->getFile($path);
} catch (Dropbox_Exception $e) {
return $this->setError('Dropbox error: '.$e->getMessage());
}
return $contents;
}
/**
* Write a string to a file
*
* @param string $path file path
* @param string $content new file content
* @return bool
* @author Dmitry (dio) Levashov
**/
protected function _filePutContents($path, $content) {
$res = false;
if ($local = $this->getTempFile($path)) {
if (@file_put_contents($local, $content, LOCK_EX) !== false
&& ($fp = @fopen($local, 'rb'))) {
clearstatcache();
$res = $this->_save($fp, $path, '', array());
@fclose($fp);
}
file_exists($local) && @unlink($local);
}
return $res;
}
/**
* Detect available archivers
*
* @return void
**/
protected function _checkArchivers() {
// die('Not yet implemented. (_checkArchivers)');
return array();
}
/**
* chmod implementation
*
* @return bool
**/
protected function _chmod($path, $mode) {
return false;
}
/**
* Unpack archive
*
* @param string $path archive path
* @param array $arc archiver command and arguments (same as in $this->archivers)
* @return true
* @return void
* @author Dmitry (dio) Levashov
* @author Alexey Sukhotin
**/
protected function _unpack($path, $arc) {
die('Not yet implemented. (_unpack)');
return false;
}
/**
* Recursive symlinks search
*
* @param string $path file/dir path
* @return bool
* @author Dmitry (dio) Levashov
**/
protected function _findSymlinks($path) {
die('Not yet implemented. (_findSymlinks)');
if (is_link($path)) {
return true;
}
if (is_dir($path)) {
foreach (scandir($path) as $name) {
if ($name != '.' && $name != '..') {
$p = $path.DIRECTORY_SEPARATOR.$name;
if (is_link($p)) {
return true;
}
if (is_dir($p) && $this->_findSymlinks($p)) {
return true;
} elseif (is_file($p)) {
$this->archiveSize += filesize($p);
}
}
}
} else {
$this->archiveSize += filesize($path);
}
return false;
}
/**
* Extract files from archive
*
* @param string $path archive path
* @param array $arc archiver command and arguments (same as in $this->archivers)
* @return true
* @author Dmitry (dio) Levashov,
* @author Alexey Sukhotin
**/
protected function _extract($path, $arc) {
die('Not yet implemented. (_extract)');
}
/**
* Create archive and return its path
*
* @param string $dir target dir
* @param array $files files names list
* @param string $name archive name
* @param array $arc archiver options
* @return string|bool
* @author Dmitry (dio) Levashov,
* @author Alexey Sukhotin
**/
protected function _archive($dir, $files, $name, $arc) {
die('Not yet implemented. (_archive)');
return false;
}
} // END class
Just wanted to ask, how are you finding the speeds when navigating the Drive folders, and doing stuff like opening files, copying, moving etc?
What would the benefit of Drive be over Google Cloud Storage?
Sir, how to view or read file contents in php google-api-php-client
https://code.google.com/archive/p/google-api-php-client/downloads
google-api-php-client-0.6.7.
Well that's not what I asked. Never mind.
I am using curl result with loop nothing special pattern is same like elFinder dropbox class
@rajasharma27 Why are you using google-api-php-client-0.6.7? stable version is 1.1.7. And 2.0.0-RC7 was released.
Other matters, you must use session handler class instead to $_SESSION like elFinderFlysystemGoogleDriveNetmount
Digress the topic, I think elFinderFlysystemGoogleDriveNetmount + flysystem-google-drive is enough speed for me. Did you try this one?
thanks sir now working everything with google-api-php-client 2.0.0-RC7
lovesin83@naver.com λκ» λ³΄λ΄μ λ©μΌ <Re: [Studio-42/elFinder] elFinder with GoogleDrive (#1275)> μ΄ λ€μκ³Ό κ°μ μ΄μ λ‘ μ μ‘ μ€ν¨νμ΅λλ€.
λ°λ μ¬λμ΄ νμλμ λ©μΌμ μμ μ°¨λ¨ νμμ΅λλ€.
thanks
Sir, I am updating a class for mounting google drive like dropbox. but some problem facing this is my web url for testing http://www.onlinewebplace.com/controlpanel/filemanager/index.html
this is my class code
https://github.com/nao-pon/elFinder-nightly/issues/35