Elfinder update - preliminary
preliminary
This commit is contained in:
parent
45359b8192
commit
f87d9830c6
27 changed files with 6194 additions and 2286 deletions
7
include/thirdparty/elFinder/connector.php
vendored
7
include/thirdparty/elFinder/connector.php
vendored
|
@ -180,4 +180,9 @@ $opts = array(
|
|||
|
||||
// run elFinder
|
||||
$connector = new elFinderConnector(new elFinder($opts));
|
||||
$connector->run();
|
||||
|
||||
try {
|
||||
$connector->run();
|
||||
} catch (Exception $e) {
|
||||
}
|
||||
|
||||
|
|
3981
include/thirdparty/elFinder/js/elfinder.full.js
vendored
3981
include/thirdparty/elFinder/js/elfinder.full.js
vendored
File diff suppressed because one or more lines are too long
26
include/thirdparty/elFinder/js/elfinder.min.js
vendored
26
include/thirdparty/elFinder/js/elfinder.min.js
vendored
File diff suppressed because one or more lines are too long
32
include/thirdparty/elFinder/php/MySQLStorage.sql
vendored
32
include/thirdparty/elFinder/php/MySQLStorage.sql
vendored
|
@ -2,7 +2,7 @@ DROP TABLE IF EXISTS `elfinder_file`;
|
|||
CREATE TABLE IF NOT EXISTS `elfinder_file` (
|
||||
`id` int(7) unsigned NOT NULL auto_increment,
|
||||
`parent_id` int(7) unsigned NOT NULL,
|
||||
`name` varchar(256) NOT NULL,
|
||||
`name` varchar(255) NOT NULL,
|
||||
`content` longblob NOT NULL,
|
||||
`size` int(10) unsigned NOT NULL default '0',
|
||||
`mtime` int(10) unsigned NOT NULL default '0',
|
||||
|
@ -16,8 +16,32 @@ CREATE TABLE IF NOT EXISTS `elfinder_file` (
|
|||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `parent_name` (`parent_id`, `name`),
|
||||
KEY `parent_id` (`parent_id`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
|
||||
|
||||
INSERT INTO `elfinder_file`
|
||||
(`id`, `parent_id`, `name`, `content`, `size`, `mtime`, `mime`, `read`, `write`, `locked`, `hidden`, `width`, `height`) VALUES
|
||||
('1', '0', 'DATABASE', '', '0', '0', 'directory', '1', '1', '0', '0', '0', '0');
|
||||
(`id`, `parent_id`, `name`, `content`, `size`, `mtime`, `mime`, `read`, `write`, `locked`, `hidden`, `width`, `height`) VALUES
|
||||
('1' , '0', 'DATABASE', '', '0', '0','directory', '1', '1', '0', '0', '0', '0');
|
||||
|
||||
DROP TABLE IF EXISTS `elfinder_trash`;
|
||||
CREATE TABLE IF NOT EXISTS `elfinder_trash` (
|
||||
`id` int(7) unsigned NOT NULL auto_increment,
|
||||
`parent_id` int(7) unsigned NOT NULL,
|
||||
`name` varchar(255) NOT NULL,
|
||||
`content` longblob NOT NULL,
|
||||
`size` int(10) unsigned NOT NULL default '0',
|
||||
`mtime` int(10) unsigned NOT NULL default '0',
|
||||
`mime` varchar(256) NOT NULL default 'unknown',
|
||||
`read` enum('1', '0') NOT NULL default '1',
|
||||
`write` enum('1', '0') NOT NULL default '1',
|
||||
`locked` enum('1', '0') NOT NULL default '0',
|
||||
`hidden` enum('1', '0') NOT NULL default '0',
|
||||
`width` int(5) NOT NULL default '0',
|
||||
`height` int(5) NOT NULL default '0',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `parent_name` (`parent_id`, `name`),
|
||||
KEY `parent_id` (`parent_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
|
||||
|
||||
INSERT INTO `elfinder_trash`
|
||||
(`id`, `parent_id`, `name`, `content`, `size`, `mtime`, `mime`, `read`, `write`, `locked`, `hidden`, `width`, `height`) VALUES
|
||||
('1' , '0', 'DB Trash', '', '0', '0','directory', '1', '1', '0', '0', '0', '0');
|
||||
|
|
1
include/thirdparty/elFinder/php/autoload.php
vendored
1
include/thirdparty/elFinder/php/autoload.php
vendored
|
@ -26,6 +26,7 @@ function elFinderAutoloader($name)
|
|||
'elFinderVolumeGroup' => 'elFinderVolumeGroup.class.php',
|
||||
'elFinderVolumeLocalFileSystem' => 'elFinderVolumeLocalFileSystem.class.php',
|
||||
'elFinderVolumeMySQL' => 'elFinderVolumeMySQL.class.php',
|
||||
'elFinderVolumeSFTPphpseclib' => 'elFinderVolumeSFTPphpseclib.class.php',
|
||||
'elFinderVolumeTrash' => 'elFinderVolumeTrash.class.php',
|
||||
);
|
||||
if (isset($map[$name])) {
|
||||
|
|
448
include/thirdparty/elFinder/php/connector.maximal.php-dist
vendored
Normal file
448
include/thirdparty/elFinder/php/connector.maximal.php-dist
vendored
Normal file
|
@ -0,0 +1,448 @@
|
|||
<?php
|
||||
|
||||
error_reporting(0); // Set E_ALL for debuging
|
||||
|
||||
// // Optional exec path settings (Default is called with command name only)
|
||||
// define('ELFINDER_TAR_PATH', '/PATH/TO/tar');
|
||||
// define('ELFINDER_GZIP_PATH', '/PATH/TO/gzip');
|
||||
// define('ELFINDER_BZIP2_PATH', '/PATH/TO/bzip2');
|
||||
// define('ELFINDER_XZ_PATH', '/PATH/TO/xz');
|
||||
// define('ELFINDER_ZIP_PATH', '/PATH/TO/zip');
|
||||
// define('ELFINDER_UNZIP_PATH', '/PATH/TO/unzip');
|
||||
// define('ELFINDER_RAR_PATH', '/PATH/TO/rar');
|
||||
// define('ELFINDER_UNRAR_PATH', '/PATH/TO/unrar');
|
||||
// define('ELFINDER_7Z_PATH', '/PATH/TO/7za');
|
||||
// define('ELFINDER_CONVERT_PATH', '/PATH/TO/convert');
|
||||
// define('ELFINDER_IDENTIFY_PATH', '/PATH/TO/identify');
|
||||
// define('ELFINDER_EXIFTRAN_PATH', '/PATH/TO/exiftran');
|
||||
// define('ELFINDER_JPEGTRAN_PATH', '/PATH/TO/jpegtran');
|
||||
// define('ELFINDER_FFMPEG_PATH', '/PATH/TO/ffmpeg');
|
||||
|
||||
// define('ELFINDER_CONNECTOR_URL', 'URL to this connector script'); // see elFinder::getConnectorUrl()
|
||||
|
||||
// define('ELFINDER_DEBUG_ERRORLEVEL', -1); // Error reporting level of debug mode
|
||||
|
||||
// // To Enable(true) handling of PostScript files by ImageMagick
|
||||
// // It is disabled by default as a countermeasure
|
||||
// // of Ghostscript multiple -dSAFER sandbox bypass vulnerabilities
|
||||
// // see https://www.kb.cert.org/vuls/id/332928
|
||||
// define('ELFINDER_IMAGEMAGICK_PS', true);
|
||||
// ===============================================
|
||||
|
||||
// // load composer autoload before load elFinder autoload If you need composer
|
||||
// // You need to run the composer command in the php directory.
|
||||
is_readable('./vendor/autoload.php') && require './vendor/autoload.php';
|
||||
|
||||
// // elFinder autoload
|
||||
require './autoload.php';
|
||||
// ===============================================
|
||||
|
||||
// // Enable FTP connector netmount
|
||||
elFinder::$netDrivers['ftp'] = 'FTP';
|
||||
// ===============================================
|
||||
|
||||
// // Required for Dropbox network mount
|
||||
// // Installation by composer
|
||||
// // `composer require kunalvarma05/dropbox-php-sdk` on php directory
|
||||
// // Enable network mount
|
||||
// elFinder::$netDrivers['dropbox2'] = 'Dropbox2';
|
||||
// // Dropbox2 Netmount driver need next two settings. You can get at https://www.dropbox.com/developers/apps
|
||||
// // AND require register redirect url to "YOUR_CONNECTOR_URL?cmd=netmount&protocol=dropbox2&host=1"
|
||||
// define('ELFINDER_DROPBOX_APPKEY', '');
|
||||
// define('ELFINDER_DROPBOX_APPSECRET', '');
|
||||
// ===============================================
|
||||
|
||||
// // Required for Google Drive network mount
|
||||
// // Installation by composer
|
||||
// // `composer require google/apiclient:^2.0` on php directory
|
||||
// // Enable network mount
|
||||
// elFinder::$netDrivers['googledrive'] = 'GoogleDrive';
|
||||
// // GoogleDrive Netmount driver need next two settings. You can get at https://console.developers.google.com
|
||||
// // AND require register redirect url to "YOUR_CONNECTOR_URL?cmd=netmount&protocol=googledrive&host=1"
|
||||
// define('ELFINDER_GOOGLEDRIVE_CLIENTID', '');
|
||||
// define('ELFINDER_GOOGLEDRIVE_CLIENTSECRET', '');
|
||||
// // Required case when Google API is NOT added via composer
|
||||
// define('ELFINDER_GOOGLEDRIVE_GOOGLEAPICLIENT', '/path/to/google-api-php-client/vendor/autoload.php');
|
||||
// ===============================================
|
||||
|
||||
// // Required for Google Drive network mount with Flysystem
|
||||
// // Installation by composer
|
||||
// // `composer require nao-pon/flysystem-google-drive:~1.1 nao-pon/elfinder-flysystem-driver-ext` on php directory
|
||||
// // Enable network mount
|
||||
// elFinder::$netDrivers['googledrive'] = 'FlysystemGoogleDriveNetmount';
|
||||
// // GoogleDrive Netmount driver need next two settings. You can get at https://console.developers.google.com
|
||||
// // AND require register redirect url to "YOUR_CONNECTOR_URL?cmd=netmount&protocol=googledrive&host=1"
|
||||
// define('ELFINDER_GOOGLEDRIVE_CLIENTID', '');
|
||||
// define('ELFINDER_GOOGLEDRIVE_CLIENTSECRET', '');
|
||||
// // And "php/.tmp" directory must exist and be writable by PHP.
|
||||
// ===============================================
|
||||
|
||||
// // Required for One Drive network mount
|
||||
// // * cURL PHP extension required
|
||||
// // * HTTP server PATH_INFO supports required
|
||||
// // Enable network mount
|
||||
// elFinder::$netDrivers['onedrive'] = 'OneDrive';
|
||||
// // GoogleDrive Netmount driver need next two settings. You can get at https://dev.onedrive.com
|
||||
// // AND require register redirect url to "YOUR_CONNECTOR_URL/netmount/onedrive/1"
|
||||
// define('ELFINDER_ONEDRIVE_CLIENTID', '');
|
||||
// define('ELFINDER_ONEDRIVE_CLIENTSECRET', '');
|
||||
// ===============================================
|
||||
|
||||
// // Required for Box network mount
|
||||
// // * cURL PHP extension required
|
||||
// // Enable network mount
|
||||
// elFinder::$netDrivers['box'] = 'Box';
|
||||
// // Box Netmount driver need next two settings. You can get at https://developer.box.com
|
||||
// // AND require register redirect url to "YOUR_CONNECTOR_URL?cmd=netmount&protocol=box&host=1"
|
||||
// define('ELFINDER_BOX_CLIENTID', '');
|
||||
// define('ELFINDER_BOX_CLIENTSECRET', '');
|
||||
// ===============================================
|
||||
|
||||
|
||||
// // Zoho Office Editor APIKey
|
||||
// // https://www.zoho.com/docs/help/office-apis.html
|
||||
// define('ELFINDER_ZOHO_OFFICE_APIKEY', '');
|
||||
// ===============================================
|
||||
|
||||
// // Online converter (online-convert.com) APIKey
|
||||
// // https://apiv2.online-convert.com/docs/getting_started/api_key.html
|
||||
// define('ELFINDER_ONLINE_CONVERT_APIKEY', '');
|
||||
// ===============================================
|
||||
|
||||
// // Zip Archive editor
|
||||
// // Installation by composer
|
||||
// // `composer require nao-pon/elfinder-flysystem-ziparchive-netmount` on php directory
|
||||
// define('ELFINDER_DISABLE_ZIPEDITOR', false); // set `true` to disable zip editor
|
||||
// ===============================================
|
||||
|
||||
/**
|
||||
* Simple function to demonstrate how to control file access using "accessControl" callback.
|
||||
* This method will disable accessing files/folders starting from '.' (dot)
|
||||
*
|
||||
* @param string $attr attribute name (read|write|locked|hidden)
|
||||
* @param string $path absolute file path
|
||||
* @param string $data value of volume option `accessControlData`
|
||||
* @param object $volume elFinder volume driver object
|
||||
* @param bool|null $isDir path is directory (true: directory, false: file, null: unknown)
|
||||
* @param string $relpath file path relative to volume root directory started with directory separator
|
||||
* @return bool|null
|
||||
**/
|
||||
function access($attr, $path, $data, $volume, $isDir, $relpath) {
|
||||
$basename = basename($path);
|
||||
return $basename[0] === '.' // if file/folder begins with '.' (dot)
|
||||
&& strlen($relpath) !== 1 // but with out volume root
|
||||
? !($attr == 'read' || $attr == 'write') // set read+write to false, other (locked+hidden) set to true
|
||||
: null; // else elFinder decide it itself
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple debug function
|
||||
* Usage: debug($anyVal[, $anyVal2 ...]);
|
||||
*/
|
||||
function debug() {
|
||||
$arg = func_get_args();
|
||||
ob_start();
|
||||
foreach($arg as $v) {
|
||||
var_dump($v);
|
||||
}
|
||||
$o = ob_get_contents();
|
||||
ob_end_clean();
|
||||
file_put_contents('.debug.txt', $o, FILE_APPEND);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple logger function.
|
||||
* Demonstrate how to work with elFinder event api.
|
||||
*
|
||||
* @package elFinder
|
||||
* @author Dmitry (dio) Levashov
|
||||
**/
|
||||
class elFinderSimpleLogger {
|
||||
|
||||
/**
|
||||
* Log file path
|
||||
*
|
||||
* @var string
|
||||
**/
|
||||
protected $file = '';
|
||||
|
||||
/**
|
||||
* constructor
|
||||
*
|
||||
* @return void
|
||||
* @author Dmitry (dio) Levashov
|
||||
**/
|
||||
public function __construct($path)
|
||||
{
|
||||
$this->file = $path;
|
||||
$dir = dirname($path);
|
||||
if (!is_dir($dir)) {
|
||||
mkdir($dir);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create log record
|
||||
*
|
||||
* @param string $cmd command name
|
||||
* @param array $result command result
|
||||
* @param array $args command arguments from client
|
||||
* @param elFinder $elfinder elFinder instance
|
||||
* @param elFinderVolumeDriver $volume current volume driver instance
|
||||
* @return void|true
|
||||
* @author Dmitry (dio) Levashov
|
||||
**/
|
||||
public function log($cmd, $result, $args, $elfinder, $volume)
|
||||
{
|
||||
$log = $cmd.' ['.date('d.m H:s')."]\n";
|
||||
|
||||
if (!empty($result['error'])) {
|
||||
$log .= "\tERROR: ".implode(' ', $result['error'])."\n";
|
||||
}
|
||||
|
||||
if (!empty($result['warning'])) {
|
||||
$log .= "\tWARNING: ".implode(' ', $result['warning'])."\n";
|
||||
}
|
||||
|
||||
if (!empty($result['removed'])) {
|
||||
foreach ($result['removed'] as $file) {
|
||||
// removed file contain additional field "realpath"
|
||||
$log .= "\tREMOVED: ".$file['realpath']."\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($result['added'])) {
|
||||
foreach ($result['added'] as $file) {
|
||||
$log .= "\tADDED: ".$elfinder->realpath($file['hash'])."\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($result['changed'])) {
|
||||
foreach ($result['changed'] as $file) {
|
||||
$log .= "\tCHANGED: ".$elfinder->realpath($file['hash'])."\n";
|
||||
}
|
||||
}
|
||||
|
||||
$this->write($log);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write log into file
|
||||
*
|
||||
* @param string $log log record
|
||||
* @return void
|
||||
* @author Dmitry (dio) Levashov
|
||||
**/
|
||||
protected function write($log)
|
||||
{
|
||||
|
||||
if (($fp = @fopen($this->file, 'a'))) {
|
||||
fwrite($fp, $log."\n");
|
||||
fclose($fp);
|
||||
}
|
||||
}
|
||||
|
||||
} // END class
|
||||
// Make logger instance
|
||||
$logger = new elFinderSimpleLogger('.log.txt');
|
||||
|
||||
// Documentation for connector options:
|
||||
// https://github.com/Studio-42/elFinder/wiki/Connector-configuration-options
|
||||
$opts = array(
|
||||
'debug' => true, // enable debug mode
|
||||
'roots' => array(
|
||||
// Items volume
|
||||
array(
|
||||
'driver' => 'LocalFileSystem', // driver for accessing file system (REQUIRED)
|
||||
'path' => '../files/', // path to files (REQUIRED)
|
||||
'URL' => dirname($_SERVER['PHP_SELF']) . '/../files/', // URL to files (REQUIRED)
|
||||
'trashHash' => 't1_Lw', // elFinder's hash of trash folder
|
||||
'winHashFix' => DIRECTORY_SEPARATOR !== '/', // to make hash same to Linux one on windows too
|
||||
'uploadDeny' => array('all'), // All Mimetypes not allowed to upload
|
||||
'uploadAllow' => array('image/x-ms-bmp', 'image/gif', 'image/jpeg', 'image/png', 'image/x-icon', 'text/plain'), // Mimetype `image` and `text/plain` allowed to upload
|
||||
'uploadOrder' => array('deny', 'allow'), // allowed Mimetype `image` and `text/plain` only
|
||||
'accessControl' => 'access', // disable and hide dot starting files (OPTIONAL)
|
||||
'attributes' => array( // additional thumbnail directories
|
||||
'pattern' => '~^/\.tmb(?:Cloud|Netmount)$~',
|
||||
'read' => false,
|
||||
'write' => false,
|
||||
'locked' => true,
|
||||
'hidden' => true ),
|
||||
),
|
||||
// Trash volume
|
||||
array(
|
||||
'id' => '1',
|
||||
'driver' => 'Trash',
|
||||
'path' => '../files/.trash/',
|
||||
'tmbURL' => dirname($_SERVER['PHP_SELF']) . '/../files/.trash/.tmb/',
|
||||
'winHashFix' => DIRECTORY_SEPARATOR !== '/', // to make hash same to Linux one on windows too
|
||||
'uploadDeny' => array('all'), // Recomend the same settings as the original volume that uses the trash
|
||||
'uploadAllow' => array('image/x-ms-bmp', 'image/gif', 'image/jpeg', 'image/png', 'image/x-icon', 'text/plain'), // Same as above
|
||||
'uploadOrder' => array('deny', 'allow'), // Same as above
|
||||
'accessControl' => 'access', // Same as above
|
||||
),
|
||||
),
|
||||
// some bind functions
|
||||
'bind' => array(
|
||||
// enable logger
|
||||
// '*' => array($logger, 'log'),
|
||||
'mkdir mkfile rename duplicate upload rm paste' => array($logger, 'log'),
|
||||
// enable plugins
|
||||
'archive.pre ls.pre mkdir.pre mkfile.pre rename.pre upload.pre' => array(
|
||||
'Plugin.Normalizer.cmdPreprocess',
|
||||
'Plugin.Sanitizer.cmdPreprocess'
|
||||
),
|
||||
'upload.presave' => array(
|
||||
'Plugin.AutoRotate.onUpLoadPreSave',
|
||||
'Plugin.AutoResize.onUpLoadPreSave',
|
||||
'Plugin.Watermark.onUpLoadPreSave',
|
||||
'Plugin.Normalizer.onUpLoadPreSave',
|
||||
'Plugin.Sanitizer.onUpLoadPreSave',
|
||||
),
|
||||
),
|
||||
// volume options of netmount volumes
|
||||
'optionsNetVolumes' => array(
|
||||
'*' => array( // "*" is all of netmount volumes
|
||||
'tmbURL' => dirname($_SERVER['PHP_SELF']) . '/../files/.tmbNetmount/',
|
||||
'tmbPath' => '../files/.tmbNetmount',
|
||||
'tmbGcMaxlifeHour' => 1, // 1 hour
|
||||
'tmbGcPercentage' => 10, // 10 execute / 100 tmb querys
|
||||
'plugin' => array(
|
||||
'AutoResize' => array(
|
||||
'enable' => false
|
||||
),
|
||||
'Watermark' => array(
|
||||
'enable' => false
|
||||
),
|
||||
'Normalizer' => array(
|
||||
'enable' => false
|
||||
),
|
||||
'Sanitizer' => array(
|
||||
'enable' => false
|
||||
)
|
||||
),
|
||||
)
|
||||
),
|
||||
);
|
||||
|
||||
// Extended other volume types
|
||||
// To get an access token or refresh token, see the elFinder wiki.
|
||||
// https://github.com/Studio-42/elFinder/wiki/How-to-get-OAuth-token
|
||||
|
||||
// Thumbnail settings for cloud volumes
|
||||
$tmbConfig = array(
|
||||
'tmbPath' => '../files/.tmbCloud',
|
||||
'tmbURL' => dirname($_SERVER['PHP_SELF']) . '/../files/.tmbCloud/',
|
||||
'tmbGcMaxlifeHour' => 2160, // 90 days
|
||||
'tmbGcPercentage' => 5, // 5 execute / 100 tmb querys
|
||||
);
|
||||
|
||||
// MySQL config
|
||||
$mySqlConfig = array(
|
||||
'path' => 1,
|
||||
'host' => '127.0.0.1',
|
||||
'user' => '', // @String DB user name
|
||||
'pass' => '', // @String DB user password
|
||||
'db' => '', // @String Database name
|
||||
'uploadMaxSize' => '10M', // It should be less than "max_allowed_packet" value of MySQL setting
|
||||
);
|
||||
// MySQL volume
|
||||
$opts['roots'][] = array_merge($tmbConfig, $mySqlConfig, array(
|
||||
'driver' => 'MySQL',
|
||||
'trashHash' => 'tm1_MQ', // set trash to MySQL trash (tm1_) 1 (MQ)
|
||||
'files_table' => 'elfinder_file',
|
||||
));
|
||||
// MySQL trash volume
|
||||
$opts['roots'][] = array_merge($tmbConfig, $mySqlConfig, array(
|
||||
'id' => '1', // volume id became "tm1_"
|
||||
'alias' => 'DB Trash',
|
||||
'driver' => 'TrashMySQL',
|
||||
'files_table' => 'elfinder_trash',
|
||||
));
|
||||
|
||||
// Volume group
|
||||
$opts['roots'][] = array(
|
||||
'id' => '1', // volume id became "g1_"
|
||||
'alias' => 'CloudVolumes',
|
||||
'driver' => 'Group',
|
||||
'rootCssClass' => 'elfinder-navbar-root-network' // set volume icon
|
||||
);
|
||||
|
||||
// FTP volume
|
||||
$opts['roots'][] = array_merge($tmbConfig, array(
|
||||
'phash' => 'g1_Lw', // set parent to Volume group (g1_) root "/" (Lw)
|
||||
'driver' => 'FTP',
|
||||
'host' => 'ftp.jaist.ac.jp',
|
||||
'user' => 'anonymous',
|
||||
'path' => '/',
|
||||
'owner' => false,
|
||||
));
|
||||
|
||||
// To enable the following cloud volumes, first complete the steps
|
||||
// for enabling each network-mounted volume described earlier in this file.
|
||||
|
||||
// Box volume
|
||||
// Require constant "ELFINDER_BOX_CLIENTID" and "ELFINDER_BOX_CLIENTSECRET"
|
||||
$opts['roots'][] = array_merge($tmbConfig, array(
|
||||
'phash' => 'g1_Lw', // set parent to Volume group (g1_) root "/" (Lw)
|
||||
'driver' => 'Box',
|
||||
'path' => '/', // or folder id as root
|
||||
'accessToken' => '', // @JSON String access token including refresh token
|
||||
));
|
||||
|
||||
// Dropbox volume
|
||||
// Require constant "ELFINDER_DROPBOX_APPKEY" and "ELFINDER_DROPBOX_APPSECRET"
|
||||
$opts['roots'][] = array_merge($tmbConfig, array(
|
||||
'phash' => 'g1_Lw', // set parent to Volume group (g1_) root "/" (Lw)
|
||||
'driver' => 'Dropbox2',
|
||||
'path' => '/', // or folder path as root
|
||||
'access_token' => '', // @String your access token
|
||||
));
|
||||
|
||||
// GoogleDrive volume with refresh token
|
||||
// Require constant "ELFINDER_GOOGLEDRIVE_CLIENTID" and "ELFINDER_GOOGLEDRIVE_CLIENTSECRET"
|
||||
$opts['roots'][] = array_merge($tmbConfig, array(
|
||||
'phash' => 'g1_Lw', // set parent to Volume group (g1_) root "/" (Lw)
|
||||
'driver' => 'GoogleDrive',
|
||||
'path' => '/', // or folder id as root
|
||||
'refresh_token' => '', // @String your refresh token
|
||||
));
|
||||
|
||||
// GoogleDrive volume with service account
|
||||
// Require constant "ELFINDER_GOOGLEDRIVE_CLIENTID" and "ELFINDER_GOOGLEDRIVE_CLIENTSECRET"
|
||||
$opts['roots'][] = array_merge($tmbConfig, array(
|
||||
'phash' => 'g1_Lw', // set parent to Volume group (g1_) root "/" (Lw)
|
||||
'driver' => 'GoogleDrive',
|
||||
'path' => '/', // or folder id as root
|
||||
'serviceAccountConfigFile' => '', // @String path to config json file
|
||||
));
|
||||
|
||||
// OneDrive volume
|
||||
// Require constant "ELFINDER_ONEDRIVE_CLIENTID" and "ELFINDER_ONEDRIVE_CLIENTSECRET"
|
||||
$opts['roots'][] = array_merge($tmbConfig, array(
|
||||
'phash' => 'g1_Lw', // set parent to Volume group (g1_) root "/" (Lw)
|
||||
'driver' => 'OneDrive',
|
||||
'path' => '/', // or folder id as root
|
||||
'accessToken' => '', // @JSON String access token including refresh token
|
||||
));
|
||||
|
||||
// SFTP volume
|
||||
// Require phpseclib 1 installed (http://phpseclib.sourceforge.net)
|
||||
// pear install example:
|
||||
//sudo pear channel-discover phpseclib.sourceforge.net
|
||||
//sudo pear remote-list -c phpseclib
|
||||
//sudo pear install phpseclib/Net_SFTP
|
||||
/*$opts['roots'][] = array_merge($tmbConfig, array(
|
||||
'phash' => 'g1_Lw', // set parent to Volume group (g1_) root "/" (Lw)
|
||||
'driver' => 'SFTPphpseclib',
|
||||
'host' => '127.0.0.1',
|
||||
'path' => '/tmp', // or folder id as root
|
||||
'user' => 'test', // @JSON String access token including refresh token
|
||||
'pass' => 'test',
|
||||
));*/
|
||||
|
||||
|
||||
// run elFinder
|
||||
$connector = new elFinderConnector(new elFinder($opts));
|
||||
$connector->run();
|
||||
|
|
@ -2,6 +2,26 @@
|
|||
|
||||
error_reporting(0); // Set E_ALL for debuging
|
||||
|
||||
// // Optional exec path settings (Default is called with command name only)
|
||||
// define('ELFINDER_TAR_PATH', '/PATH/TO/tar');
|
||||
// define('ELFINDER_GZIP_PATH', '/PATH/TO/gzip');
|
||||
// define('ELFINDER_BZIP2_PATH', '/PATH/TO/bzip2');
|
||||
// define('ELFINDER_XZ_PATH', '/PATH/TO/xz');
|
||||
// define('ELFINDER_ZIP_PATH', '/PATH/TO/zip');
|
||||
// define('ELFINDER_UNZIP_PATH', '/PATH/TO/unzip');
|
||||
// define('ELFINDER_RAR_PATH', '/PATH/TO/rar');
|
||||
// define('ELFINDER_UNRAR_PATH', '/PATH/TO/unrar');
|
||||
// define('ELFINDER_7Z_PATH', '/PATH/TO/7za');
|
||||
// define('ELFINDER_CONVERT_PATH', '/PATH/TO/convert');
|
||||
// define('ELFINDER_IDENTIFY_PATH', '/PATH/TO/identify');
|
||||
// define('ELFINDER_EXIFTRAN_PATH', '/PATH/TO/exiftran');
|
||||
// define('ELFINDER_JPEGTRAN_PATH', '/PATH/TO/jpegtran');
|
||||
// define('ELFINDER_FFMPEG_PATH', '/PATH/TO/ffmpeg');
|
||||
|
||||
// define('ELFINDER_CONNECTOR_URL', 'URL to this connector script'); // see elFinder::getConnectorUrl()
|
||||
|
||||
// define('ELFINDER_DEBUG_ERRORLEVEL', -1); // Error reporting level of debug mode
|
||||
|
||||
// // To Enable(true) handling of PostScript files by ImageMagick
|
||||
// // It is disabled by default as a countermeasure
|
||||
// // of Ghostscript multiple -dSAFER sandbox bypass vulnerabilities
|
||||
|
@ -9,50 +29,55 @@ error_reporting(0); // Set E_ALL for debuging
|
|||
// define('ELFINDER_IMAGEMAGICK_PS', true);
|
||||
// ===============================================
|
||||
|
||||
// load composer autoload before load elFinder autoload If you need composer
|
||||
//require './vendor/autoload.php';
|
||||
// // load composer autoload before load elFinder autoload If you need composer
|
||||
// // You need to run the composer command in the php directory.
|
||||
is_readable('./vendor/autoload.php') && require './vendor/autoload.php';
|
||||
|
||||
// elFinder autoload
|
||||
// // elFinder autoload
|
||||
require './autoload.php';
|
||||
// ===============================================
|
||||
|
||||
// Enable FTP connector netmount
|
||||
// // Enable FTP connector netmount
|
||||
elFinder::$netDrivers['ftp'] = 'FTP';
|
||||
// ===============================================
|
||||
|
||||
// // Required for Dropbox network mount
|
||||
// // Installation by composer
|
||||
// // `composer require kunalvarma05/dropbox-php-sdk`
|
||||
// // `composer require kunalvarma05/dropbox-php-sdk` on php directory
|
||||
// // Enable network mount
|
||||
// elFinder::$netDrivers['dropbox2'] = 'Dropbox2';
|
||||
// // Dropbox2 Netmount driver need next two settings. You can get at https://www.dropbox.com/developers/apps
|
||||
// // AND reuire regist redirect url to "YOUR_CONNECTOR_URL?cmd=netmount&protocol=dropbox2&host=1"
|
||||
// // AND require register redirect url to "YOUR_CONNECTOR_URL?cmd=netmount&protocol=dropbox2&host=1"
|
||||
// // If the elFinder HTML element ID is not "elfinder", you need to change "host=1" to "host=ElementID"
|
||||
// define('ELFINDER_DROPBOX_APPKEY', '');
|
||||
// define('ELFINDER_DROPBOX_APPSECRET', '');
|
||||
// ===============================================
|
||||
|
||||
// // Required for Google Drive network mount
|
||||
// // Installation by composer
|
||||
// // `composer require google/apiclient:^2.0`
|
||||
// // `composer require google/apiclient:^2.0` on php directory
|
||||
// // Enable network mount
|
||||
// elFinder::$netDrivers['googledrive'] = 'GoogleDrive';
|
||||
// // GoogleDrive Netmount driver need next two settings. You can get at https://console.developers.google.com
|
||||
// // AND reuire regist redirect url to "YOUR_CONNECTOR_URL?cmd=netmount&protocol=googledrive&host=1"
|
||||
// // AND require register redirect url to "YOUR_CONNECTOR_URL?cmd=netmount&protocol=googledrive&host=1"
|
||||
// // If the elFinder HTML element ID is not "elfinder", you need to change "host=1" to "host=ElementID"
|
||||
// define('ELFINDER_GOOGLEDRIVE_CLIENTID', '');
|
||||
// define('ELFINDER_GOOGLEDRIVE_CLIENTSECRET', '');
|
||||
// // Required case of without composer
|
||||
// // Required case when Google API is NOT added via composer
|
||||
// define('ELFINDER_GOOGLEDRIVE_GOOGLEAPICLIENT', '/path/to/google-api-php-client/vendor/autoload.php');
|
||||
// ===============================================
|
||||
|
||||
// // Required for Google Drive network mount with Flysystem
|
||||
// // Installation by composer
|
||||
// // `composer require nao-pon/flysystem-google-drive:~1.1 nao-pon/elfinder-flysystem-driver-ext`
|
||||
// // `composer require nao-pon/flysystem-google-drive:~1.1 nao-pon/elfinder-flysystem-driver-ext` on php directory
|
||||
// // Enable network mount
|
||||
// elFinder::$netDrivers['googledrive'] = 'FlysystemGoogleDriveNetmount';
|
||||
// // GoogleDrive Netmount driver need next two settings. You can get at https://console.developers.google.com
|
||||
// // AND reuire regist redirect url to "YOUR_CONNECTOR_URL?cmd=netmount&protocol=googledrive&host=1"
|
||||
// // AND require register redirect url to "YOUR_CONNECTOR_URL?cmd=netmount&protocol=googledrive&host=1"
|
||||
// // If the elFinder HTML element ID is not "elfinder", you need to change "host=1" to "host=ElementID"
|
||||
// define('ELFINDER_GOOGLEDRIVE_CLIENTID', '');
|
||||
// define('ELFINDER_GOOGLEDRIVE_CLIENTSECRET', '');
|
||||
// // And "php/.tmp" directory must exist and be writable by PHP.
|
||||
// ===============================================
|
||||
|
||||
// // Required for One Drive network mount
|
||||
|
@ -61,7 +86,8 @@ elFinder::$netDrivers['ftp'] = 'FTP';
|
|||
// // Enable network mount
|
||||
// elFinder::$netDrivers['onedrive'] = 'OneDrive';
|
||||
// // GoogleDrive Netmount driver need next two settings. You can get at https://dev.onedrive.com
|
||||
// // AND reuire regist redirect url to "YOUR_CONNECTOR_URL/netmount/onedrive/1"
|
||||
// // AND require register redirect url to "YOUR_CONNECTOR_URL/netmount/onedrive/1"
|
||||
// // If the elFinder HTML element ID is not "elfinder", you need to change "/1" to "/ElementID"
|
||||
// define('ELFINDER_ONEDRIVE_CLIENTID', '');
|
||||
// define('ELFINDER_ONEDRIVE_CLIENTSECRET', '');
|
||||
// ===============================================
|
||||
|
@ -71,7 +97,8 @@ elFinder::$netDrivers['ftp'] = 'FTP';
|
|||
// // Enable network mount
|
||||
// elFinder::$netDrivers['box'] = 'Box';
|
||||
// // Box Netmount driver need next two settings. You can get at https://developer.box.com
|
||||
// // AND reuire regist redirect url to "YOUR_CONNECTOR_URL"
|
||||
// // AND require register redirect url to "YOUR_CONNECTOR_URL?cmd=netmount&protocol=box&host=1"
|
||||
// // If the elFinder HTML element ID is not "elfinder", you need to change "host=1" to "host=ElementID"
|
||||
// define('ELFINDER_BOX_CLIENTID', '');
|
||||
// define('ELFINDER_BOX_CLIENTSECRET', '');
|
||||
// ===============================================
|
||||
|
@ -89,7 +116,7 @@ elFinder::$netDrivers['ftp'] = 'FTP';
|
|||
|
||||
// // Zip Archive editor
|
||||
// // Installation by composer
|
||||
// // `composer require nao-pon/elfinder-flysystem-ziparchive-netmount`
|
||||
// // `composer require nao-pon/elfinder-flysystem-ziparchive-netmount` on php directory
|
||||
// define('ELFINDER_DISABLE_ZIPEDITOR', false); // set `true` to disable zip editor
|
||||
// ===============================================
|
||||
|
||||
|
@ -142,7 +169,7 @@ $opts = array(
|
|||
'uploadAllow' => array('image/x-ms-bmp', 'image/gif', 'image/jpeg', 'image/png', 'image/x-icon', 'text/plain'), // Same as above
|
||||
'uploadOrder' => array('deny', 'allow'), // Same as above
|
||||
'accessControl' => 'access', // Same as above
|
||||
)
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ class elFinderEditorOnlineConvert extends elFinderEditor
|
|||
|
||||
public function enabled()
|
||||
{
|
||||
return !defined('ELFINDER_DISABLE_ONLINE_CONVERT') || !ELFINDER_DISABLE_ONLINE_CONVERT;
|
||||
return defined('ELFINDER_ONLINE_CONVERT_APIKEY') && ELFINDER_ONLINE_CONVERT_APIKEY && (!defined('ELFINDER_DISABLE_ONLINE_CONVERT') || !ELFINDER_DISABLE_ONLINE_CONVERT);
|
||||
}
|
||||
|
||||
public function init()
|
||||
|
|
|
@ -6,10 +6,21 @@ class elFinderEditorZohoOffice extends elFinderEditor
|
|||
|
||||
protected $allowed = array('init', 'save', 'chk');
|
||||
|
||||
protected $editor_settings = array(
|
||||
'writer' => array(
|
||||
'unit' => 'mm',
|
||||
'view' => 'pageview'
|
||||
),
|
||||
'sheet' => array(
|
||||
'country' => 'US'
|
||||
),
|
||||
'show' => array()
|
||||
);
|
||||
|
||||
private $urls = array(
|
||||
'writer' => 'https://writer.zoho.com/writer/remotedoc.im',
|
||||
'sheet' => 'https://sheet.zoho.com/sheet/remotedoc.im',
|
||||
'show' => 'https://show.zoho.com/show/remotedoc.im',
|
||||
'writer' => 'https://writer.zoho.com/writer/officeapi/v1/document',
|
||||
'sheet' => 'https://sheet.zoho.com/sheet/officeapi/v1/spreadsheet',
|
||||
'show' => 'https://show.zoho.com/show/officeapi/v1/presentation',
|
||||
);
|
||||
|
||||
private $srvs = array(
|
||||
|
@ -32,6 +43,14 @@ class elFinderEditorZohoOffice extends elFinderEditor
|
|||
'application/vnd.sun.xml.impress' => 'show',
|
||||
);
|
||||
|
||||
private $myName = '';
|
||||
|
||||
public function __construct($elfinder, $args)
|
||||
{
|
||||
parent::__construct($elfinder, $args);
|
||||
$this->myName = preg_replace('/^elFinderEditor/i', '', get_class($this));
|
||||
}
|
||||
|
||||
public function enabled()
|
||||
{
|
||||
return defined('ELFINDER_ZOHO_OFFICE_APIKEY') && ELFINDER_ZOHO_OFFICE_APIKEY && function_exists('curl_init');
|
||||
|
@ -51,7 +70,8 @@ class elFinderEditorZohoOffice extends elFinderEditor
|
|||
$cookie = $this->elfinder->getFetchCookieFile();
|
||||
$save = false;
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, elFinder::getConnectorUrl() . '?cmd=editor&name=ZohoOffice&method=chk&args[target]=' . rawurlencode($hash) . $cdata);
|
||||
$conUrl = elFinder::getConnectorUrl();
|
||||
curl_setopt($ch, CURLOPT_URL, $conUrl . (strpos($conUrl, '?') !== false? '&' : '?') . 'cmd=editor&name=' . $this->myName . '&method=chk&args[target]=' . rawurlencode($hash) . $cdata);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
if ($cookie) {
|
||||
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie);
|
||||
|
@ -94,18 +114,29 @@ class elFinderEditorZohoOffice extends elFinderEditor
|
|||
$srvsName = $this->srvs[$file['mime']];
|
||||
$data = array(
|
||||
'apikey' => ELFINDER_ZOHO_OFFICE_APIKEY,
|
||||
'output' => 'url',
|
||||
'mode' => 'normaledit',
|
||||
'filename' => $file['name'],
|
||||
'id' => $hash,
|
||||
'format' => $format,
|
||||
'lang' => $lang
|
||||
'callback_settings' => array(
|
||||
'save_format' => $format,
|
||||
'context_info' => array(
|
||||
'hash' => $hash
|
||||
)
|
||||
),
|
||||
'editor_settings' => $this->editor_settings[$srvsName],
|
||||
'document_info' => array(
|
||||
'document_name' => substr($file['name'], 0, strlen($file['name']) - strlen($format)- 1)
|
||||
)
|
||||
);
|
||||
$data['editor_settings']['language'] = $lang;
|
||||
if ($save) {
|
||||
$data['saveurl'] = elFinder::getConnectorUrl() . '?cmd=editor&name=ZohoOffice&method=save' . $cdata;
|
||||
$conUrl = elFinder::getConnectorUrl();
|
||||
$data['callback_settings']['save_url'] = $conUrl . (strpos($conUrl, '?') !== false? '&' : '?') . 'cmd=editor&name=' . $this->myName . '&method=save' . $cdata;
|
||||
}
|
||||
foreach($data as $_k => $_v) {
|
||||
if (is_array($_v)){
|
||||
$data[$_k] = json_encode($_v);
|
||||
}
|
||||
}
|
||||
if ($cfile) {
|
||||
$data['content'] = $cfile;
|
||||
$data['document'] = $cfile;
|
||||
}
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $this->urls[$srvsName]);
|
||||
|
@ -120,16 +151,12 @@ class elFinderEditorZohoOffice extends elFinderEditor
|
|||
|
||||
$fp && fclose($fp);
|
||||
|
||||
if ($res) {
|
||||
if (strpos($res, 'RESULT=TRUE') !== false) {
|
||||
list(, $url) = explode('URL=', $res);
|
||||
preg_match('/URL=([^\s]+)/', $res, $m);
|
||||
|
||||
$ret = array('zohourl' => $m[1]);
|
||||
if ($res && $res = @json_decode($res, true)) {
|
||||
if (!empty($res['document_url'])) {
|
||||
$ret = array('zohourl' => $res['document_url']);
|
||||
if (!$save) {
|
||||
$ret['warning'] = 'exportToSave';
|
||||
}
|
||||
|
||||
return $ret;
|
||||
} else {
|
||||
$error = $res;
|
||||
|
@ -137,23 +164,27 @@ class elFinderEditorZohoOffice extends elFinderEditor
|
|||
}
|
||||
|
||||
if ($error) {
|
||||
return array('error' => preg_split('/[\r\n]+/', $error));
|
||||
return array('error' => is_string($error)? preg_split('/[\r\n]+/', $error) : 'Error code: ' . $error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return array('error' => array('errCmdParams', 'editor.ZohoOffice.init'));
|
||||
return array('error' => array('errCmdParams', 'editor.' . $this->myName . '.init'));
|
||||
}
|
||||
|
||||
public function save()
|
||||
{
|
||||
if (isset($_POST) && !empty($_POST['id'])) {
|
||||
$hash = $_POST['id'];
|
||||
/** @var elFinderVolumeDriver $volume */
|
||||
if ($volume = $this->elfinder->getVolume($hash)) {
|
||||
$content = file_get_contents($_FILES['content']['tmp_name']);
|
||||
if ($volume->putContents($hash, $content)) {
|
||||
return array('raw' => true, 'error' => '', 'header' => 'HTTP/1.1 200 OK');
|
||||
if (!empty($_POST) && !empty($_POST['id']) && !empty($_FILES) && !empty($_FILES['content'])) {
|
||||
$data = @json_decode(str_replace('"', '"', $_POST['id']), true);
|
||||
if (!empty($data['hash'])) {
|
||||
$hash = $data['hash'];
|
||||
/** @var elFinderVolumeDriver $volume */
|
||||
if ($volume = $this->elfinder->getVolume($hash)) {
|
||||
if ($content = file_get_contents($_FILES['content']['tmp_name'])) {
|
||||
if ($volume->putContents($hash, $content)) {
|
||||
return array('raw' => true, 'error' => '', 'header' => 'HTTP/1.1 200 OK');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
843
include/thirdparty/elFinder/php/elFinder.class.php
vendored
843
include/thirdparty/elFinder/php/elFinder.class.php
vendored
File diff suppressed because it is too large
Load diff
|
@ -171,6 +171,16 @@ class elFinderConnector
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the header.
|
||||
*
|
||||
* @param array|string $value HTTP header(s)
|
||||
*/
|
||||
public function setHeader($value)
|
||||
{
|
||||
$this->header = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Output json
|
||||
*
|
||||
|
@ -209,7 +219,7 @@ class elFinderConnector
|
|||
$sendData = !($this->reqMethod === 'HEAD' || !empty($data['info']['xsendfile']));
|
||||
$psize = null;
|
||||
if (($this->reqMethod === 'GET' || !$sendData)
|
||||
&& elFinder::isSeekableStream($fp)
|
||||
&& (elFinder::isSeekableStream($fp) || elFinder::isSeekableUrl($fp))
|
||||
&& (array_search('Accept-Ranges: none', headers_list()) === false)) {
|
||||
header('Accept-Ranges: bytes');
|
||||
if (!empty($_SERVER['HTTP_RANGE'])) {
|
||||
|
@ -248,7 +258,7 @@ class elFinderConnector
|
|||
}
|
||||
}
|
||||
|
||||
$sendData && fseek($fp, $start);
|
||||
$sendData && !elFinder::isSeekableUrl($fp) && fseek($fp, $start);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -267,7 +277,7 @@ class elFinderConnector
|
|||
}
|
||||
|
||||
if ($sendData) {
|
||||
if ($toEnd) {
|
||||
if ($toEnd || elFinder::isSeekableUrl($fp)) {
|
||||
// PHP < 5.6 has a bug of fpassthru
|
||||
// see https://bugs.php.net/bug.php?id=66736
|
||||
if (version_compare(PHP_VERSION, '5.6', '<')) {
|
||||
|
@ -283,7 +293,9 @@ class elFinderConnector
|
|||
}
|
||||
|
||||
if (!empty($data['volume'])) {
|
||||
$data['volume']->close($data['pointer'], $data['info']['hash']);
|
||||
$data['volume']->close($fp, $data['info']['hash']);
|
||||
} else {
|
||||
fclose($fp);
|
||||
}
|
||||
exit();
|
||||
} else {
|
||||
|
@ -349,8 +361,8 @@ class elFinderConnector
|
|||
if (!empty($data['raw']) && isset($data['error'])) {
|
||||
$out = $data['error'];
|
||||
} else {
|
||||
if (isset($data['debug']) && isset($data['debug']['phpErrors'])) {
|
||||
$data['debug']['phpErrors'] = array_merge($data['debug']['phpErrors'], elFinder::$phpErrors);
|
||||
if (isset($data['debug']) && isset($data['debug']['backendErrors'])) {
|
||||
$data['debug']['backendErrors'] = array_merge($data['debug']['backendErrors'], elFinder::$phpErrors);
|
||||
}
|
||||
$out = json_encode($data);
|
||||
}
|
||||
|
|
|
@ -126,16 +126,19 @@ class elFinderVolumeFlysystemGoogleDriveNetmount extends ExtDriver
|
|||
|
||||
}
|
||||
|
||||
if ($options['user'] === 'init') {
|
||||
$itpCare = isset($options['code']);
|
||||
$code = $itpCare? $options['code'] : (isset($_GET['code'])? $_GET['code'] : '');
|
||||
if ($code || $options['user'] === 'init') {
|
||||
if (empty($options['url'])) {
|
||||
$options['url'] = elFinder::getConnectorUrl();
|
||||
}
|
||||
|
||||
$callback = $options['url']
|
||||
. '?cmd=netmount&protocol=googledrive&host=1';
|
||||
$client->setRedirectUri($callback);
|
||||
if (isset($options['id'])) {
|
||||
$callback = $options['url'] . (strpos($options['url'], '?') !== false? '&' : '?') . 'cmd=netmount&protocol=googledrive&host=' . ($options['id'] === 'elfinder'? '1' : $options['id']);
|
||||
$client->setRedirectUri($callback);
|
||||
}
|
||||
|
||||
if (!$aToken && empty($_GET['code'])) {
|
||||
if (!$aToken && empty($code)) {
|
||||
$client->setScopes([Google_Service_Drive::DRIVE]);
|
||||
if (!empty($options['offline'])) {
|
||||
$client->setApprovalPrompt('force');
|
||||
|
@ -143,9 +146,9 @@ class elFinderVolumeFlysystemGoogleDriveNetmount extends ExtDriver
|
|||
}
|
||||
$url = $client->createAuthUrl();
|
||||
|
||||
$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 = '<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">';
|
||||
$html .= '<script>
|
||||
$("#' . $options['id'] . '").elfinder("instance").trigger("netmount", {protocol: "googledrive", mode: "makebtn"});
|
||||
$("#' . $options['id'] . '").elfinder("instance").trigger("netmount", {protocol: "googledrive", mode: "makebtn", url: "' . $url . '"});
|
||||
</script>';
|
||||
if (empty($options['pass']) && $options['host'] !== '1') {
|
||||
$options['pass'] = 'return';
|
||||
|
@ -160,16 +163,38 @@ class elFinderVolumeFlysystemGoogleDriveNetmount extends ExtDriver
|
|||
return array('exit' => 'callback', 'out' => $out);
|
||||
}
|
||||
} else {
|
||||
if (!empty($_GET['code'])) {
|
||||
$aToken = $client->fetchAccessTokenWithAuthCode($_GET['code']);
|
||||
$options['access_token'] = $aToken;
|
||||
$this->session->set('GoogleDriveTokens', $aToken)->set('GoogleDriveAuthParams', $options);
|
||||
$out = array(
|
||||
'node' => $options['id'],
|
||||
'json' => '{"protocol": "googledrive", "mode": "done", "reset": 1}',
|
||||
'bind' => 'netmount'
|
||||
);
|
||||
return array('exit' => 'callback', 'out' => $out);
|
||||
if ($code) {
|
||||
if (!empty($options['id'])) {
|
||||
$aToken = $client->fetchAccessTokenWithAuthCode($code);
|
||||
$options['access_token'] = $aToken;
|
||||
unset($options['code']);
|
||||
$this->session->set('GoogleDriveTokens', $aToken)->set('GoogleDriveAuthParams', $options);
|
||||
$out = array(
|
||||
'node' => $options['id'],
|
||||
'json' => '{"protocol": "googledrive", "mode": "done", "reset": 1}',
|
||||
'bind' => 'netmount'
|
||||
);
|
||||
} else {
|
||||
$nodeid = ($_GET['host'] === '1')? 'elfinder' : $_GET['host'];
|
||||
$out = array(
|
||||
'node' => $nodeid,
|
||||
'json' => json_encode(array(
|
||||
'protocol' => 'googledrive',
|
||||
'host' => $nodeid,
|
||||
'mode' => 'redirect',
|
||||
'options' => array(
|
||||
'id' => $nodeid,
|
||||
'code'=> $code
|
||||
)
|
||||
)),
|
||||
'bind' => 'netmount'
|
||||
);
|
||||
}
|
||||
if (!$itpCare) {
|
||||
return array('exit' => 'callback', 'out' => $out);
|
||||
} else {
|
||||
return array('exit' => true, 'body' => $out['json']);
|
||||
}
|
||||
}
|
||||
$folders = [];
|
||||
foreach ($service->files->listFiles([
|
||||
|
@ -211,6 +236,9 @@ class elFinderVolumeFlysystemGoogleDriveNetmount extends ExtDriver
|
|||
try {
|
||||
$file = $service->files->get($options['path']);
|
||||
$options['alias'] = sprintf($this->options['gdAlias'], $file->getName());
|
||||
if (!empty($this->options['netkey'])) {
|
||||
elFinder::$instance->updateNetVolumeOption($this->options['netkey'], 'alias', $this->options['alias']);
|
||||
}
|
||||
} catch (Google_Service_Exception $e) {
|
||||
$err = json_decode($e->getMessage(), true);
|
||||
if (isset($err['error']) && $err['error']['code'] == 404) {
|
||||
|
@ -277,7 +305,7 @@ class elFinderVolumeFlysystemGoogleDriveNetmount extends ExtDriver
|
|||
if (!empty($opts['access_token'])) {
|
||||
$client->setAccessToken($opts['access_token']);
|
||||
}
|
||||
if ($client->isAccessTokenExpired()) {
|
||||
if ($this->needOnline && $client->isAccessTokenExpired()) {
|
||||
try {
|
||||
$creds = $client->fetchAccessTokenWithRefreshToken();
|
||||
} catch (LogicException $e) {
|
||||
|
@ -335,4 +363,18 @@ class elFinderVolumeFlysystemGoogleDriveNetmount extends ExtDriver
|
|||
return $this->netMountKey . substr(substr($stat['hash'], strlen($this->id)), -38) . $stat['ts'] . '.png';
|
||||
}
|
||||
|
||||
/**
|
||||
* Return debug info for client.
|
||||
*
|
||||
* @return array
|
||||
**/
|
||||
public function debug()
|
||||
{
|
||||
$res = parent::debug();
|
||||
if (!empty($this->options['netkey']) && empty($this->options['refresh_token']) && $this->options['access_token'] && isset($this->options['access_token']['refresh_token'])) {
|
||||
$res['refresh_token'] = $this->options['access_token']['refresh_token'];
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,7 +49,8 @@ class elFinderSession implements elFinderSessionInterface
|
|||
'keys' => array(
|
||||
'default' => 'elFinderCaches',
|
||||
'netvolume' => 'elFinderNetVolumes'
|
||||
)
|
||||
),
|
||||
'cookieParams' => array()
|
||||
);
|
||||
|
||||
/**
|
||||
|
@ -64,11 +65,9 @@ class elFinderSession implements elFinderSessionInterface
|
|||
$this->opts = array_merge($this->opts, $opts);
|
||||
$this->base64encode = !empty($this->opts['base64encode']);
|
||||
$this->keys = $this->opts['keys'];
|
||||
if (function_exists('apache_get_version')) {
|
||||
if (function_exists('apache_get_version') || $this->opts['cookieParams']) {
|
||||
$this->fixCookieRegist = true;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -123,23 +122,30 @@ class elFinderSession implements elFinderSessionInterface
|
|||
*/
|
||||
public function start()
|
||||
{
|
||||
set_error_handler(array($this, 'session_start_error'), E_NOTICE | E_WARNING);
|
||||
|
||||
// apache2 SAPI has a bug of session cookie register
|
||||
// see https://bugs.php.net/bug.php?id=75554
|
||||
// see https://github.com/php/php-src/pull/3231
|
||||
if ($this->fixCookieRegist === true) {
|
||||
// apache2 SAPI has a bug of session cookie register
|
||||
// see https://bugs.php.net/bug.php?id=75554
|
||||
// see https://github.com/php/php-src/pull/3231
|
||||
ini_set('session.use_cookies', 0);
|
||||
if ((int)ini_get('session.use_cookies') === 1) {
|
||||
if (ini_set('session.use_cookies', 0) === false) {
|
||||
$this->fixCookieRegist = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (version_compare(PHP_VERSION, '5.4.0', '>=')) {
|
||||
if (session_status() !== PHP_SESSION_ACTIVE) {
|
||||
session_start();
|
||||
}
|
||||
} else {
|
||||
set_error_handler(array($this, 'session_start_error'), E_NOTICE);
|
||||
session_start();
|
||||
restore_error_handler();
|
||||
}
|
||||
$this->started = session_id() ? true : false;
|
||||
|
||||
restore_error_handler();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -217,7 +223,20 @@ class elFinderSession implements elFinderSessionInterface
|
|||
if ($this->fixCookieRegist === true) {
|
||||
// regist cookie only once for apache2 SAPI
|
||||
$cParm = session_get_cookie_params();
|
||||
setcookie(session_name(), session_id(), 0, $cParm['path'], $cParm['domain'], $cParm['secure'], $cParm['httponly']);
|
||||
if ($this->opts['cookieParams'] && is_array($this->opts['cookieParams'])) {
|
||||
$cParm = array_merge($cParm, $this->opts['cookieParams']);
|
||||
}
|
||||
if (version_compare(PHP_VERSION, '7.3', '<')) {
|
||||
setcookie(session_name(), session_id(), 0, $cParm['path'] . (!empty($cParm['SameSite'])? '; SameSite=' . $cParm['SameSite'] : ''), $cParm['domain'], $cParm['secure'], $cParm['httponly']);
|
||||
} else {
|
||||
$allows = array('expires' => true, 'path' => true, 'domain' => true, 'secure' => true, 'httponly' => true, 'samesite' => true);
|
||||
foreach(array_keys($cParm) as $_k) {
|
||||
if (!isset($allows[$_k])) {
|
||||
unset($cParm[$_k]);
|
||||
}
|
||||
}
|
||||
setcookie(session_name(), session_id(), $cParm);
|
||||
}
|
||||
$this->fixCookieRegist = false;
|
||||
}
|
||||
session_write_close();
|
||||
|
|
|
@ -26,12 +26,12 @@ class elFinderVolumeBox extends elFinderVolumeDriver
|
|||
/**
|
||||
* @var string The base URL for authorization requests
|
||||
*/
|
||||
const AUTH_URL = 'https://www.box.com/api/oauth2/authorize';
|
||||
const AUTH_URL = 'https://account.box.com/api/oauth2/authorize';
|
||||
|
||||
/**
|
||||
* @var string The base URL for token requests
|
||||
*/
|
||||
const TOKEN_URL = 'https://www.box.com/api/oauth2/token';
|
||||
const TOKEN_URL = 'https://api.box.com/oauth2/token';
|
||||
|
||||
/**
|
||||
* @var string The base URL for upload requests
|
||||
|
@ -74,6 +74,13 @@ class elFinderVolumeBox extends elFinderVolumeDriver
|
|||
**/
|
||||
private $tmbPrefix = '';
|
||||
|
||||
/**
|
||||
* Path to access token file for permanent mount
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $aTokenFile = '';
|
||||
|
||||
/**
|
||||
* hasCache by folders.
|
||||
*
|
||||
|
@ -100,7 +107,7 @@ class elFinderVolumeBox extends elFinderVolumeDriver
|
|||
'tmbPath' => '',
|
||||
'tmbURL' => '',
|
||||
'tmpPath' => '',
|
||||
'acceptedName' => '#^[^/\\?*:|"<>]*[^./\\?*:|"<>]$#',
|
||||
'acceptedName' => '#^[^\\\/]+$#',
|
||||
'rootCssClass' => 'elfinder-navbar-root-box',
|
||||
);
|
||||
$this->options = array_merge($this->options, $opts);
|
||||
|
@ -191,10 +198,15 @@ class elFinderVolumeBox extends elFinderVolumeDriver
|
|||
|
||||
$decoded = $this->_bd_curlExec($curl, true, array('Content-Length: ' . strlen($fields)));
|
||||
|
||||
return (object)array(
|
||||
$res = (object)array(
|
||||
'expires' => time() + $decoded->expires_in - 30,
|
||||
'data' => $decoded,
|
||||
'initialToken' => '',
|
||||
'data' => $decoded
|
||||
);
|
||||
if (!empty($decoded->refresh_token)) {
|
||||
$res->initialToken = md5($client_id . $decoded->refresh_token);
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -206,14 +218,6 @@ class elFinderVolumeBox extends elFinderVolumeDriver
|
|||
protected function _bd_refreshToken()
|
||||
{
|
||||
if (!property_exists($this->token, 'expires') || $this->token->expires < time()) {
|
||||
if (!$token = $this->session->get('BoxTokens')) {
|
||||
$token = $this->token;
|
||||
}
|
||||
if (empty($token->data->refresh_token)) {
|
||||
$this->session->remove('BoxTokens');
|
||||
throw new \Exception(elFinder::ERROR_REAUTH_REQUIRE);
|
||||
}
|
||||
|
||||
if (!$this->options['client_id']) {
|
||||
$this->options['client_id'] = ELFINDER_BOX_CLIENTID;
|
||||
}
|
||||
|
@ -222,6 +226,32 @@ class elFinderVolumeBox extends elFinderVolumeDriver
|
|||
$this->options['client_secret'] = ELFINDER_BOX_CLIENTSECRET;
|
||||
}
|
||||
|
||||
if (empty($this->token->data->refresh_token)) {
|
||||
throw new \Exception(elFinder::ERROR_REAUTH_REQUIRE);
|
||||
} else {
|
||||
$refresh_token = $this->token->data->refresh_token;
|
||||
$initialToken = $this->_bd_getInitialToken();
|
||||
}
|
||||
|
||||
$lock = '';
|
||||
$aTokenFile = $this->aTokenFile? $this->aTokenFile : $this->_bd_getATokenFile();
|
||||
if ($aTokenFile && is_file($aTokenFile)) {
|
||||
$lock = $aTokenFile . '.lock';
|
||||
if (file_exists($lock)) {
|
||||
// Probably updating on other instance
|
||||
return true;
|
||||
}
|
||||
touch($lock);
|
||||
$GLOBALS['elFinderTempFiles'][$lock] = true;
|
||||
}
|
||||
|
||||
$postData = array(
|
||||
'client_id' => $this->options['client_id'],
|
||||
'client_secret' => $this->options['client_secret'],
|
||||
'grant_type' => 'refresh_token',
|
||||
'refresh_token' => $refresh_token
|
||||
);
|
||||
|
||||
$url = self::TOKEN_URL;
|
||||
|
||||
$curl = curl_init();
|
||||
|
@ -230,32 +260,67 @@ class elFinderVolumeBox extends elFinderVolumeDriver
|
|||
// General options.
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_POST => true, // i am sending post data
|
||||
CURLOPT_POSTFIELDS => 'client_id=' . urlencode($this->options['client_id'])
|
||||
. '&client_secret=' . urlencode($this->options['client_secret'])
|
||||
. '&grant_type=refresh_token'
|
||||
. '&refresh_token=' . urlencode($token->data->refresh_token),
|
||||
|
||||
CURLOPT_POSTFIELDS => http_build_query($postData),
|
||||
CURLOPT_URL => $url,
|
||||
));
|
||||
|
||||
$decoded = $this->_bd_curlExec($curl);
|
||||
$decoded = $error = '';
|
||||
try {
|
||||
$decoded = $this->_bd_curlExec($curl, true, array(), $postData);
|
||||
} catch (Exception $e) {
|
||||
$error = $e->getMessage();
|
||||
}
|
||||
if (!$decoded && !$error) {
|
||||
$error = 'Tried to renew the access token, but did not get a response from the Box server.';
|
||||
}
|
||||
if ($error) {
|
||||
$lock && unlink($lock);
|
||||
throw new \Exception('Box access token update failed. ('.$error.') If this message appears repeatedly, please notify the administrator.');
|
||||
}
|
||||
|
||||
if (empty($decoded->access_token)) {
|
||||
throw new \Exception(elFinder::ERROR_REAUTH_REQUIRE);
|
||||
if ($aTokenFile) {
|
||||
if (is_file($aTokenFile)) {
|
||||
unlink($aTokenFile);
|
||||
}
|
||||
}
|
||||
$err = property_exists($decoded, 'error')? ' ' . $decoded->error : '';
|
||||
$err .= property_exists($decoded, 'error_description')? ' ' . $decoded->error_description : '';
|
||||
throw new \Exception($err? $err : elFinder::ERROR_REAUTH_REQUIRE);
|
||||
}
|
||||
|
||||
$token = (object)array(
|
||||
'expires' => time() + $decoded->expires_in - 30,
|
||||
'expires' => time() + $decoded->expires_in - 300,
|
||||
'initialToken' => $initialToken,
|
||||
'data' => $decoded,
|
||||
);
|
||||
|
||||
$this->session->set('BoxTokens', $token);
|
||||
$this->options['accessToken'] = json_encode($token);
|
||||
$this->token = $token;
|
||||
$json = json_encode($token);
|
||||
|
||||
if (!empty($this->options['netkey'])) {
|
||||
elFinder::$instance->updateNetVolumeOption($this->options['netkey'], 'accessToken', $this->options['accessToken']);
|
||||
if (!empty($decoded->refresh_token)) {
|
||||
if (empty($this->options['netkey']) && $aTokenFile) {
|
||||
file_put_contents($aTokenFile, json_encode($token), LOCK_EX);
|
||||
$this->options['accessToken'] = $json;
|
||||
} else if (!empty($this->options['netkey'])) {
|
||||
// OAuth2 refresh token can be used only once,
|
||||
// so update it if it is the same as the token file
|
||||
if ($aTokenFile && is_file($aTokenFile)) {
|
||||
if ($_token = json_decode(file_get_contents($aTokenFile))) {
|
||||
if ($_token->data->refresh_token === $refresh_token) {
|
||||
file_put_contents($aTokenFile, $json, LOCK_EX);
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->options['accessToken'] = $json;
|
||||
// update session value
|
||||
elFinder::$instance->updateNetVolumeOption($this->options['netkey'], 'accessToken', $json);
|
||||
$this->session->set('BoxTokens', $token);
|
||||
} else {
|
||||
throw new \Exception(ERROR_CREATING_TEMP_DIR);
|
||||
}
|
||||
}
|
||||
$lock && unlink($lock);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -341,13 +406,15 @@ class elFinderVolumeBox extends elFinderVolumeDriver
|
|||
* @throws \Exception
|
||||
* @return mixed
|
||||
*/
|
||||
protected function _bd_curlExec($curl, $decodeOrParent = true, $headers = array())
|
||||
protected function _bd_curlExec($curl, $decodeOrParent = true, $headers = array(), $postData = array())
|
||||
{
|
||||
$headers = array_merge(array(
|
||||
'Authorization: Bearer ' . $this->token->data->access_token,
|
||||
), $headers);
|
||||
if ($this->token) {
|
||||
$headers = array_merge(array(
|
||||
'Authorization: Bearer ' . $this->token->data->access_token,
|
||||
), $headers);
|
||||
}
|
||||
|
||||
$result = elFinder::curlExec($curl, array(), $headers);
|
||||
$result = elFinder::curlExec($curl, array(), $headers, $postData);
|
||||
|
||||
if (!$decodeOrParent) {
|
||||
return $result;
|
||||
|
@ -355,12 +422,18 @@ class elFinderVolumeBox extends elFinderVolumeDriver
|
|||
|
||||
$decoded = json_decode($result);
|
||||
|
||||
if (!empty($decoded->error_code)) {
|
||||
if ($error = !empty($decoded->error_code)) {
|
||||
$errmsg = $decoded->error_code;
|
||||
if (!empty($decoded->message)) {
|
||||
$errmsg .= ': ' . $decoded->message;
|
||||
}
|
||||
throw new \Exception($errmsg);
|
||||
} else if ($error = !empty($decoded->error)) {
|
||||
$errmsg = $decoded->error;
|
||||
if (!empty($decoded->error_description)) {
|
||||
$errmsg .= ': ' . $decoded->error_description;
|
||||
}
|
||||
throw new \Exception($errmsg);
|
||||
}
|
||||
|
||||
// make catch
|
||||
|
@ -546,6 +619,39 @@ class elFinderVolumeBox extends elFinderVolumeDriver
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get AccessToken file path
|
||||
*
|
||||
* @return string ( description_of_the_return_value )
|
||||
*/
|
||||
protected function _bd_getATokenFile()
|
||||
{
|
||||
$tmp = $aTokenFile = '';
|
||||
if (!empty($this->token->data->refresh_token)) {
|
||||
if (!$this->tmp) {
|
||||
$tmp = elFinder::getStaticVar('commonTempPath');
|
||||
if (!$tmp) {
|
||||
$tmp = $this->getTempPath();
|
||||
}
|
||||
$this->tmp = $tmp;
|
||||
}
|
||||
if ($tmp) {
|
||||
$aTokenFile = $tmp . DIRECTORY_SEPARATOR . $this->_bd_getInitialToken() . '.btoken';
|
||||
}
|
||||
}
|
||||
return $aTokenFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Initial Token (MD5 hash)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function _bd_getInitialToken()
|
||||
{
|
||||
return (empty($this->token->initialToken)? md5($this->options['client_id'] . (!empty($this->token->data->refresh_token)? $this->token->data->refresh_token : $this->token->data->access_token)) : $this->token->initialToken);
|
||||
}
|
||||
|
||||
/*********************************************************************/
|
||||
/* OVERRIDE FUNCTIONS */
|
||||
/*********************************************************************/
|
||||
|
@ -575,30 +681,57 @@ class elFinderVolumeBox extends elFinderVolumeDriver
|
|||
|
||||
if (isset($options['id'])) {
|
||||
$this->session->set('nodeId', $options['id']);
|
||||
} elseif ($_id = $this->session->get('nodeId')) {
|
||||
} else if ($_id = $this->session->get('nodeId')) {
|
||||
$options['id'] = $_id;
|
||||
$this->session->set('nodeId', $_id);
|
||||
}
|
||||
|
||||
if (!empty($options['tmpPath'])) {
|
||||
if ((is_dir($options['tmpPath']) || mkdir($this->options['tmpPath'])) && is_writable($options['tmpPath'])) {
|
||||
$this->tmp = $options['tmpPath'];
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
if (empty($options['client_id']) || empty($options['client_secret'])) {
|
||||
return array('exit' => true, 'body' => '{msg:errNetMountNoDriver}');
|
||||
}
|
||||
|
||||
if (isset($_GET['code'])) {
|
||||
$itpCare = isset($options['code']);
|
||||
$code = $itpCare? $options['code'] : (isset($_GET['code'])? $_GET['code'] : '');
|
||||
if ($code) {
|
||||
try {
|
||||
// Obtain the token using the code received by the Box.com API
|
||||
$this->session->set('BoxTokens',
|
||||
$this->_bd_obtainAccessToken($options['client_id'], $options['client_secret'], $_GET['code']));
|
||||
if (!empty($options['id'])) {
|
||||
// Obtain the token using the code received by the Box.com API
|
||||
$this->session->set('BoxTokens',
|
||||
$this->_bd_obtainAccessToken($options['client_id'], $options['client_secret'], $code));
|
||||
|
||||
$out = array(
|
||||
'node' => $options['id'],
|
||||
'json' => '{"protocol": "box", "mode": "done", "reset": 1}',
|
||||
'bind' => 'netmount',
|
||||
|
||||
);
|
||||
|
||||
return array('exit' => 'callback', 'out' => $out);
|
||||
$out = array(
|
||||
'node' => $options['id'],
|
||||
'json' => '{"protocol": "box", "mode": "done", "reset": 1}',
|
||||
'bind' => 'netmount'
|
||||
);
|
||||
} else {
|
||||
$nodeid = ($_GET['host'] === '1')? 'elfinder' : $_GET['host'];
|
||||
$out = array(
|
||||
'node' => $nodeid,
|
||||
'json' => json_encode(array(
|
||||
'protocol' => 'box',
|
||||
'host' => $nodeid,
|
||||
'mode' => 'redirect',
|
||||
'options' => array(
|
||||
'id' => $nodeid,
|
||||
'code'=> $code
|
||||
)
|
||||
)),
|
||||
'bind' => 'netmount'
|
||||
);
|
||||
}
|
||||
if (!$itpCare) {
|
||||
return array('exit' => 'callback', 'out' => $out);
|
||||
} else {
|
||||
return array('exit' => true, 'body' => $out['json']);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
$out = array(
|
||||
'node' => $options['id'],
|
||||
|
@ -640,34 +773,20 @@ class elFinderVolumeBox extends elFinderVolumeDriver
|
|||
}
|
||||
|
||||
if ($result === false) {
|
||||
$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 (empty($options['url'])) {
|
||||
$options['url'] = elFinder::getConnectorUrl();
|
||||
}
|
||||
$callback = $options['url']
|
||||
. '?cmd=netmount&protocol=box&host=box.com&user=init&pass=return&node=' . $options['id'] . $cdata;
|
||||
$redirect = elFinder::getConnectorUrl();
|
||||
$redirect .= (strpos($redirect, '?') !== false? '&' : '?') . 'cmd=netmount&protocol=box&host=' . ($options['id'] === 'elfinder'? '1' : $options['id']);
|
||||
|
||||
try {
|
||||
$this->session->set('BoxTokens', (object)array('token' => null));
|
||||
|
||||
$url = self::AUTH_URL . '?' . http_build_query(array('response_type' => 'code', 'client_id' => $options['client_id'], 'redirect_uri' => elFinder::getConnectorUrl() . '?cmd=netmount&protocol=box&host=1'));
|
||||
|
||||
$url .= '&oauth_callback=' . rawurlencode($callback);
|
||||
$url = self::AUTH_URL . '?' . http_build_query(array('response_type' => 'code', 'client_id' => $options['client_id'], 'redirect_uri' => $redirect));
|
||||
} catch (Exception $e) {
|
||||
return array('exit' => true, 'body' => '{msg:errAccess}');
|
||||
}
|
||||
|
||||
$html = '<input id="elf-volumedriver-box-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 = '<input id="elf-volumedriver-box-host-btn" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" value="{msg:btnApprove}" type="button">';
|
||||
$html .= '<script>
|
||||
$("#' . $options['id'] . '").elfinder("instance").trigger("netmount", {protocol: "box", mode: "makebtn"});
|
||||
</script>';
|
||||
$("#' . $options['id'] . '").elfinder("instance").trigger("netmount", {protocol: "box", mode: "makebtn", url: "' . $url . '"});
|
||||
</script>';
|
||||
|
||||
return array('exit' => true, 'body' => $html);
|
||||
} else {
|
||||
|
@ -690,11 +809,12 @@ class elFinderVolumeBox extends elFinderVolumeDriver
|
|||
$folders = json_encode($folders);
|
||||
|
||||
$expires = empty($this->token->data->refresh_token) ? (int)$this->token->expires : 0;
|
||||
$json = '{"protocol": "box", "mode": "done", "folders": ' . $folders . ', "expires": ' . $expires . '}';
|
||||
$mnt2res = empty($this->token->data->refresh_token) ? '' : ', "mnt2res": 1';
|
||||
$json = '{"protocol": "box", "mode": "done", "folders": ' . $folders . ', "expires": ' . $expires . $mnt2res . '}';
|
||||
$html = 'Box.com';
|
||||
$html .= '<script>
|
||||
$("#' . $options['id'] . '").elfinder("instance").trigger("netmount", ' . $json . ');
|
||||
</script>';
|
||||
$("#' . $options['id'] . '").elfinder("instance").trigger("netmount", ' . $json . ');
|
||||
</script>';
|
||||
|
||||
return array('exit' => true, 'body' => $html);
|
||||
}
|
||||
|
@ -705,7 +825,11 @@ class elFinderVolumeBox extends elFinderVolumeDriver
|
|||
|
||||
if ($_aToken = $this->session->get('BoxTokens')) {
|
||||
$options['accessToken'] = json_encode($_aToken);
|
||||
if ($this->options['path'] === 'root' || !$this->options['path']) {
|
||||
$this->options['path'] = '/';
|
||||
}
|
||||
} else {
|
||||
$this->session->remove('BoxTokens');
|
||||
$this->setError(elFinder::ERROR_NETMOUNT, $options['host'], implode(' ', $this->error()));
|
||||
|
||||
return array('exit' => true, 'error' => $this->error());
|
||||
|
@ -745,7 +869,7 @@ class elFinderVolumeBox extends elFinderVolumeDriver
|
|||
public function debug()
|
||||
{
|
||||
$res = parent::debug();
|
||||
if (!empty($this->options['accessToken'])) {
|
||||
if (!empty($this->options['netkey']) && !empty($this->options['accessToken'])) {
|
||||
$res['accessToken'] = $this->options['accessToken'];
|
||||
}
|
||||
|
||||
|
@ -771,22 +895,62 @@ class elFinderVolumeBox extends elFinderVolumeDriver
|
|||
return $this->setError('Required option `accessToken` is undefined.');
|
||||
}
|
||||
|
||||
try {
|
||||
$this->token = json_decode($this->options['accessToken']);
|
||||
$this->_bd_refreshToken();
|
||||
} catch (Exception $e) {
|
||||
$this->token = null;
|
||||
$this->session->remove('BoxTokens');
|
||||
|
||||
return $this->setError($e->getMessage());
|
||||
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 (empty($options['netkey'])) {
|
||||
$error = false;
|
||||
try {
|
||||
$this->token = json_decode($this->options['accessToken']);
|
||||
if (!is_object($this->token)) {
|
||||
throw new Exception('Required option `accessToken` is invalid JSON.');
|
||||
}
|
||||
|
||||
// make net mount key
|
||||
$_tokenKey = isset($this->token->data->refresh_token) ? $this->token->data->refresh_token : $this->token->data->access_token;
|
||||
$this->netMountKey = md5(implode('-', array('box', $this->options['path'], $_tokenKey)));
|
||||
} else {
|
||||
$this->netMountKey = $options['netkey'];
|
||||
if (empty($this->options['netkey'])) {
|
||||
$this->netMountKey = $this->_bd_getInitialToken();
|
||||
} else {
|
||||
$this->netMountKey = $this->options['netkey'];
|
||||
}
|
||||
|
||||
if ($this->aTokenFile = $this->_bd_getATokenFile()) {
|
||||
if (empty($this->options['netkey'])) {
|
||||
if ($this->aTokenFile) {
|
||||
if (is_file($this->aTokenFile)) {
|
||||
$this->token = json_decode(file_get_contents($this->aTokenFile));
|
||||
if (!is_object($this->token)) {
|
||||
unlink($this->aTokenFile);
|
||||
throw new Exception('Required option `accessToken` is invalid JSON.');
|
||||
}
|
||||
} else {
|
||||
file_put_contents($this->aTokenFile, json_encode($this->token), LOCK_EX);
|
||||
}
|
||||
}
|
||||
} else if (is_file($this->aTokenFile)) {
|
||||
// If the refresh token is the same as the permanent volume
|
||||
$this->token = json_decode(file_get_contents($this->aTokenFile));
|
||||
}
|
||||
}
|
||||
|
||||
$this->needOnline && $this->_bd_refreshToken();
|
||||
} catch (Exception $e) {
|
||||
$this->token = null;
|
||||
$error = true;
|
||||
$this->setError($e->getMessage());
|
||||
}
|
||||
|
||||
if ($this->netMountKey) {
|
||||
$this->tmbPrefix = 'box' . base_convert($this->netMountKey, 16, 32);
|
||||
}
|
||||
|
||||
if ($error) {
|
||||
if (empty($this->options['netkey']) && $this->tmbPrefix) {
|
||||
// for delete thumbnail
|
||||
$this->netunmount(null, null);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// normalize root path
|
||||
|
@ -796,27 +960,22 @@ class elFinderVolumeBox extends elFinderVolumeDriver
|
|||
|
||||
$this->root = $this->options['path'] = $this->_normpath($this->options['path']);
|
||||
|
||||
$this->options['root'] == '' ? $this->options['root'] = 'Box.com' : $this->options['root'];
|
||||
$this->options['root'] = ($this->options['root'] == '')? 'Box.com' : $this->options['root'];
|
||||
|
||||
if (empty($this->options['alias'])) {
|
||||
list(, $itemId) = $this->_bd_splitPath($this->options['path']);
|
||||
$this->options['alias'] = ($this->options['path'] === '/') ? $this->options['root'] :
|
||||
$this->_bd_query($itemId, $fetch_self = true)->name . '@Box.com';
|
||||
}
|
||||
|
||||
$this->rootName = $this->options['alias'];
|
||||
|
||||
$this->tmbPrefix = 'box' . base_convert($this->netMountKey, 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->needOnline) {
|
||||
list(, $itemId) = $this->_bd_splitPath($this->options['path']);
|
||||
$this->options['alias'] = ($this->options['path'] === '/') ? $this->options['root'] :
|
||||
$this->_bd_query($itemId, $fetch_self = true)->name . '@Box';
|
||||
if (!empty($this->options['netkey'])) {
|
||||
elFinder::$instance->updateNetVolumeOption($this->options['netkey'], 'alias', $this->options['alias']);
|
||||
}
|
||||
} else {
|
||||
$this->options['alias'] = $this->options['root'];
|
||||
}
|
||||
}
|
||||
|
||||
if (!$this->tmp && ($tmp = elFinder::getStaticVar('commonTempPath'))) {
|
||||
$this->tmp = $tmp;
|
||||
}
|
||||
$this->rootName = $this->options['alias'];
|
||||
|
||||
// This driver dose not support `syncChkAsTs`
|
||||
$this->options['syncChkAsTs'] = false;
|
||||
|
@ -896,7 +1055,16 @@ class elFinderVolumeBox extends elFinderVolumeDriver
|
|||
$this->options['searchExDirReg'] = $searchExDirReg;
|
||||
|
||||
if ($search) {
|
||||
return $search[0];
|
||||
$f = false;
|
||||
foreach($search as $f) {
|
||||
if ($f['name'] !== $name) {
|
||||
$f = false;
|
||||
}
|
||||
if ($f) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $f;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -1106,27 +1274,8 @@ class elFinderVolumeBox extends elFinderVolumeDriver
|
|||
**/
|
||||
protected function getSharedWebContentLink($raw)
|
||||
{
|
||||
$fExtension = pathinfo($raw->name, PATHINFO_EXTENSION);
|
||||
list($fType) = explode('/', self::mimetypeInternalDetect($raw->name));
|
||||
|
||||
if ($raw->shared_link->url && ($fType == 'image' || $fType == 'video' || $fType == 'audio')) {
|
||||
if ($fExtension == 'jpg' && $fType == 'image') {
|
||||
$url = 'https://app.box.com/representation/file_version_' . $raw->file_version->id . '/image_2048_' . $fExtension . '/1.' . $fExtension . '?shared_name=' . basename($raw->shared_link->url);
|
||||
|
||||
return $url;
|
||||
} elseif ($fExtension !== 'jpg' && $fType == 'image') {
|
||||
$url = 'https://app.box.com/representation/file_version_' . $raw->file_version->id . '/image_2048/1.' . $fExtension . '?shared_name=' . basename($raw->shared_link->url);
|
||||
|
||||
return $url;
|
||||
} elseif ($fType == 'video') {
|
||||
$url = 'https://app.box.com/representation/file_version_' . $raw->file_version->id . '/video_480.' . $fExtension . '?shared_name=' . basename($raw->shared_link->url);
|
||||
|
||||
return $url;
|
||||
} elseif ($fType == 'audio') {
|
||||
$url = 'https://app.box.com/index.php?rm=preview_stream&&file_version_' . $raw->file_version->id . '/audio/mpeg:' . $raw->name . '&shared_name=' . basename($raw->shared_link->url);
|
||||
|
||||
return $url;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
@ -1384,7 +1533,8 @@ class elFinderVolumeBox extends elFinderVolumeDriver
|
|||
$cache['height'] = $size[1];
|
||||
$ret = array('dim' => $size[0] . 'x' . $size[1]);
|
||||
$srcfp = fopen($work, 'rb');
|
||||
if ($subImgLink = $this->getSubstituteImgLink(elFinder::$currentArgs['target'], $size, $srcfp)) {
|
||||
$target = isset(elFinder::$currentArgs['target'])? elFinder::$currentArgs['target'] : '';
|
||||
if ($subImgLink = $this->getSubstituteImgLink($target, $size, $srcfp)) {
|
||||
$ret['url'] = $subImgLink;
|
||||
}
|
||||
}
|
||||
|
@ -1431,6 +1581,16 @@ class elFinderVolumeBox extends elFinderVolumeDriver
|
|||
'headers' => array('Authorization: Bearer ' . $this->token->data->access_token),
|
||||
);
|
||||
|
||||
// to support range request
|
||||
if (func_num_args() > 2) {
|
||||
$opts = func_get_arg(2);
|
||||
} else {
|
||||
$opts = array();
|
||||
}
|
||||
if (!empty($opts['httpheaders'])) {
|
||||
$data['headers'] = array_merge($opts['httpheaders'], $data['headers']);
|
||||
}
|
||||
|
||||
return elFinder::getStreamByUrl($data);
|
||||
}
|
||||
|
||||
|
@ -1448,7 +1608,7 @@ class elFinderVolumeBox extends elFinderVolumeDriver
|
|||
*/
|
||||
protected function _fclose($fp, $path = '')
|
||||
{
|
||||
fclose($fp);
|
||||
is_resource($fp) && fclose($fp);
|
||||
if ($path) {
|
||||
unlink($this->getTempFile($path));
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -68,7 +68,7 @@ class elFinderVolumeDropbox2 extends elFinderVolumeDriver
|
|||
'aliasFormat' => '%s@Dropbox',
|
||||
'path' => '/',
|
||||
'separator' => '/',
|
||||
'acceptedName' => '#^[^/\\?*:|"<>]*[^./\\?*:|"<>]$#',
|
||||
'acceptedName' => '#^[^\\\/]+$#',
|
||||
'rootCssClass' => 'elfinder-navbar-root-dropbox',
|
||||
'publishPermission' => [
|
||||
'requested_visibility' => 'public',
|
||||
|
@ -287,7 +287,6 @@ class elFinderVolumeDropbox2 extends elFinderVolumeDriver
|
|||
}
|
||||
|
||||
try {
|
||||
$this->session->start();
|
||||
$app = new DropboxApp($options['app_key'], $options['app_secret']);
|
||||
$dropbox = new Dropbox($app);
|
||||
$authHelper = $dropbox->getAuthHelper();
|
||||
|
@ -326,20 +325,25 @@ class elFinderVolumeDropbox2 extends elFinderVolumeDriver
|
|||
}
|
||||
}
|
||||
|
||||
if ($options['user'] === 'init') {
|
||||
if ((isset($options['user']) && $options['user'] === 'init') || (isset($_GET['host']) && $_GET['host'] == '1')) {
|
||||
if (empty($options['url'])) {
|
||||
$options['url'] = elFinder::getConnectorUrl();
|
||||
}
|
||||
|
||||
$callback = $options['url']
|
||||
. '?cmd=netmount&protocol=dropbox2&host=1';
|
||||
if (!empty($options['id'])) {
|
||||
$callback = $options['url']
|
||||
. (strpos($options['url'], '?') !== false? '&' : '?') . 'cmd=netmount&protocol=dropbox2&host=' . ($options['id'] === 'elfinder'? '1' : $options['id']);
|
||||
}
|
||||
|
||||
if (!$aToken && empty($_GET['code'])) {
|
||||
$itpCare = isset($options['code']);
|
||||
$code = $itpCare? $options['code'] : (isset($_GET['code'])? $_GET['code'] : '');
|
||||
$state = $itpCare? $options['state'] : (isset($_GET['state'])? $_GET['state'] : '');
|
||||
if (!$aToken && empty($code)) {
|
||||
$url = $authHelper->getAuthUrl($callback);
|
||||
|
||||
$html = '<input id="elf-volumedriver-dropbox2-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 = '<input id="elf-volumedriver-dropbox2-host-btn" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" value="{msg:btnApprove}" type="button">';
|
||||
$html .= '<script>
|
||||
$("#' . $options['id'] . '").elfinder("instance").trigger("netmount", {protocol: "dropbox2", mode: "makebtn"});
|
||||
$("#' . $options['id'] . '").elfinder("instance").trigger("netmount", {protocol: "dropbox2", mode: "makebtn", url: "' . $url . '"});
|
||||
</script>';
|
||||
if (empty($options['pass']) && $options['host'] !== '1') {
|
||||
$options['pass'] = 'return';
|
||||
|
@ -356,20 +360,44 @@ class elFinderVolumeDropbox2 extends elFinderVolumeDriver
|
|||
return ['exit' => 'callback', 'out' => $out];
|
||||
}
|
||||
} else {
|
||||
if (!empty($_GET['code']) && isset($_GET['state'])) {
|
||||
$tokenObj = $authHelper->getAccessToken($_GET['code'], $_GET['state'], $callback);
|
||||
$options['tokens'] = [
|
||||
'access_token' => $tokenObj->getToken(),
|
||||
'uid' => $tokenObj->getUid(),
|
||||
];
|
||||
$this->session->set('Dropbox2Tokens', $options['tokens'])->set('Dropbox2AuthParams', $options);
|
||||
$out = [
|
||||
'node' => $options['id'],
|
||||
'json' => '{"protocol": "dropbox2", "mode": "done", "reset": 1}',
|
||||
'bind' => 'netmount',
|
||||
];
|
||||
|
||||
return ['exit' => 'callback', 'out' => $out];
|
||||
if ($code && $state) {
|
||||
if (!empty($options['id'])) {
|
||||
// see https://github.com/kunalvarma05/dropbox-php-sdk/issues/115
|
||||
$authHelper->getPersistentDataStore()->set('state', filter_var($state, FILTER_SANITIZE_STRING));
|
||||
$tokenObj = $authHelper->getAccessToken($code, $state, $callback);
|
||||
$options['tokens'] = [
|
||||
'access_token' => $tokenObj->getToken(),
|
||||
'uid' => $tokenObj->getUid(),
|
||||
];
|
||||
unset($options['code'], $options['state']);
|
||||
$this->session->set('Dropbox2Tokens', $options['tokens'])->set('Dropbox2AuthParams', $options);
|
||||
$out = [
|
||||
'node' => $options['id'],
|
||||
'json' => '{"protocol": "dropbox2", "mode": "done", "reset": 1}',
|
||||
'bind' => 'netmount',
|
||||
];
|
||||
} else {
|
||||
$nodeid = ($_GET['host'] === '1')? 'elfinder' : $_GET['host'];
|
||||
$out = [
|
||||
'node' => $nodeid,
|
||||
'json' => json_encode(array(
|
||||
'protocol' => 'dropbox2',
|
||||
'host' => $nodeid,
|
||||
'mode' => 'redirect',
|
||||
'options' => array(
|
||||
'id' => $nodeid,
|
||||
'code' => $code,
|
||||
'state' => $state
|
||||
)
|
||||
)),
|
||||
'bind' => 'netmount'
|
||||
];
|
||||
}
|
||||
if (!$itpCare) {
|
||||
return array('exit' => 'callback', 'out' => $out);
|
||||
} else {
|
||||
return array('exit' => true, 'body' => $out['json']);
|
||||
}
|
||||
}
|
||||
$path = $options['path'];
|
||||
$folders = [];
|
||||
|
@ -495,9 +523,11 @@ class elFinderVolumeDropbox2 extends elFinderVolumeDriver
|
|||
$this->netMountKey = md5($aToken . '-' . $this->options['path']);
|
||||
|
||||
$errors = [];
|
||||
if (!$this->service) {
|
||||
if ($this->needOnline && !$this->service) {
|
||||
$app = new DropboxApp($this->options['app_key'], $this->options['app_secret'], $aToken);
|
||||
$this->service = new Dropbox($app);
|
||||
// to check access_token
|
||||
$this->service->getCurrentAccount();
|
||||
}
|
||||
} catch (DropboxClientException $e) {
|
||||
$errors[] = 'Dropbox error: ' . $e->getMessage();
|
||||
|
@ -505,9 +535,11 @@ class elFinderVolumeDropbox2 extends elFinderVolumeDriver
|
|||
$errors[] = $e->getMessage();
|
||||
}
|
||||
|
||||
if (!$this->service) {
|
||||
if ($this->needOnline && !$this->service) {
|
||||
$errors[] = 'Dropbox Service could not be loaded.';
|
||||
}
|
||||
|
||||
if ($errors) {
|
||||
return $this->setError($errors);
|
||||
}
|
||||
|
||||
|
@ -519,7 +551,10 @@ class elFinderVolumeDropbox2 extends elFinderVolumeDriver
|
|||
$this->root = $this->options['path'] = $this->_normpath($this->options['path']);
|
||||
|
||||
if (empty($this->options['alias'])) {
|
||||
$this->options['alias'] = sprintf($this->options['aliasFormat'], ($this->options['path'] === '/') ? 'root' : $this->_basename($this->options['path']));
|
||||
$this->options['alias'] = sprintf($this->options['aliasFormat'], ($this->options['path'] === '/') ? 'Root' : $this->_basename($this->options['path']));
|
||||
if (!empty($this->options['netkey'])) {
|
||||
elFinder::$instance->updateNetVolumeOption($this->options['netkey'], 'alias', $this->options['alias']);
|
||||
}
|
||||
}
|
||||
|
||||
$this->rootName = $this->options['alias'];
|
||||
|
@ -890,7 +925,7 @@ class elFinderVolumeDropbox2 extends elFinderVolumeDriver
|
|||
public function debug()
|
||||
{
|
||||
$res = parent::debug();
|
||||
if (isset($this->options['tokens']) && !empty($this->options['tokens']['uid'])) {
|
||||
if (!empty($this->options['netkey']) && isset($this->options['tokens']) && !empty($this->options['tokens']['uid'])) {
|
||||
$res['Dropbox uid'] = $this->options['tokens']['uid'];
|
||||
$res['access_token'] = $this->options['tokens']['access_token'];
|
||||
}
|
||||
|
@ -1105,7 +1140,8 @@ class elFinderVolumeDropbox2 extends elFinderVolumeDriver
|
|||
if ($size) {
|
||||
$ret = array('dim' => $size[0] . 'x' . $size[1]);
|
||||
$srcfp = fopen($tmp, 'rb');
|
||||
if ($subImgLink = $this->getSubstituteImgLink(elFinder::$currentArgs['target'], $size, $srcfp)) {
|
||||
$target = isset(elFinder::$currentArgs['target'])? elFinder::$currentArgs['target'] : '';
|
||||
if ($subImgLink = $this->getSubstituteImgLink($target, $size, $srcfp)) {
|
||||
$ret['url'] = $subImgLink;
|
||||
}
|
||||
}
|
||||
|
@ -1151,6 +1187,16 @@ class elFinderVolumeDropbox2 extends elFinderVolumeDriver
|
|||
'headers' => array('Authorization: Bearer ' . $access_token),
|
||||
);
|
||||
|
||||
// to support range request
|
||||
if (func_num_args() > 2) {
|
||||
$opts = func_get_arg(2);
|
||||
} else {
|
||||
$opts = array();
|
||||
}
|
||||
if (!empty($opts['httpheaders'])) {
|
||||
$data['headers'] = array_merge($opts['httpheaders'], $data['headers']);
|
||||
}
|
||||
|
||||
return elFinder::getStreamByUrl($data);
|
||||
}
|
||||
}
|
||||
|
@ -1169,7 +1215,7 @@ class elFinderVolumeDropbox2 extends elFinderVolumeDriver
|
|||
**/
|
||||
protected function _fclose($fp, $path = '')
|
||||
{
|
||||
fclose($fp);
|
||||
is_resource($fp) && fclose($fp);
|
||||
}
|
||||
|
||||
/******************** file/dir manipulations *************************/
|
||||
|
|
|
@ -112,6 +112,7 @@ class elFinderVolumeFTP extends elFinderVolumeDriver
|
|||
'tmbPath' => '',
|
||||
'tmpPath' => '',
|
||||
'separator' => '/',
|
||||
'checkSubfolders' => -1,
|
||||
'dirMode' => 0755,
|
||||
'fileMode' => 0644,
|
||||
'rootCssClass' => 'elfinder-navbar-root-ftp',
|
||||
|
@ -194,8 +195,9 @@ class elFinderVolumeFTP extends elFinderVolumeDriver
|
|||
|
||||
if (empty($this->options['alias'])) {
|
||||
$this->options['alias'] = $this->options['user'] . '@' . $this->options['host'];
|
||||
// $num = elFinder::$volumesCnt-1;
|
||||
// $this->options['alias'] = $this->root == '/' || $this->root == '.' ? 'FTP folder '.$num : basename($this->root);
|
||||
if (!empty($this->options['netkey'])) {
|
||||
elFinder::$instance->updateNetVolumeOption($this->options['netkey'], 'alias', $this->options['alias']);
|
||||
}
|
||||
}
|
||||
|
||||
$this->rootName = $this->options['alias'];
|
||||
|
@ -209,7 +211,7 @@ class elFinderVolumeFTP extends elFinderVolumeDriver
|
|||
$this->ftpListOption = $this->options['ftpListOption'];
|
||||
}
|
||||
|
||||
return $this->connect();
|
||||
return $this->needOnline? $this->connect() : true;
|
||||
|
||||
}
|
||||
|
||||
|
@ -382,7 +384,10 @@ class elFinderVolumeFTP extends elFinderVolumeDriver
|
|||
$lastyear = date('Y') - 1;
|
||||
}
|
||||
|
||||
$info = preg_split("/\s+/", $raw, 9);
|
||||
$info = preg_split("/\s+/", $raw, 8);
|
||||
if (isset($info[7])) {
|
||||
list($info[7], $info[8]) = explode(' ', $info[7], 2);
|
||||
}
|
||||
$stat = array();
|
||||
|
||||
if (!isset($this->ftpOsUnix)) {
|
||||
|
@ -829,33 +834,47 @@ class elFinderVolumeFTP extends elFinderVolumeDriver
|
|||
$res = array(
|
||||
'name' => $this->root,
|
||||
'mime' => 'directory',
|
||||
'dirs' => $this->_subdirs($path)
|
||||
'dirs' => -1
|
||||
);
|
||||
if ($this->isMyReload()) {
|
||||
if ($this->needOnline && (($this->ARGS['cmd'] === 'open' && $this->ARGS['target'] === $this->encode($this->root)) || $this->isMyReload())) {
|
||||
$check = array(
|
||||
'ts' => true,
|
||||
'dirs' => true,
|
||||
);
|
||||
$ts = 0;
|
||||
foreach ($this->ftpRawList($path) as $str) {
|
||||
if (($stat = $this->parseRaw($str, $path))) {
|
||||
if (!empty($stat['ts'])) {
|
||||
$info = preg_split('/\s+/', $str, 9);
|
||||
if ($info[8] === '.') {
|
||||
$info[8] = 'root';
|
||||
if ($stat = $this->parseRaw(join(' ', $info), $path)) {
|
||||
unset($stat['name']);
|
||||
$res = array_merge($res, $stat);
|
||||
if ($res['ts']) {
|
||||
$ts = 0;
|
||||
unset($check['ts']);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($check && ($stat = $this->parseRaw($str, $path))) {
|
||||
if (isset($stat['ts']) && !empty($stat['ts'])) {
|
||||
$ts = max($ts, $stat['ts']);
|
||||
}
|
||||
if (isset($stat['dirs']) && $stat['mime'] === 'directory') {
|
||||
$res['dirs'] = 1;
|
||||
unset($stat['dirs']);
|
||||
}
|
||||
if (!$check) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($ts) {
|
||||
$res['ts'] = $ts;
|
||||
}
|
||||
$this->cache[$outPath] = $res;
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
// stat of system root
|
||||
if ($path === $this->separator) {
|
||||
$res = array(
|
||||
'name' => $this->separator,
|
||||
'mime' => 'directory',
|
||||
'dirs' => 1
|
||||
);
|
||||
$this->cache[$outPath] = $res;
|
||||
return $res;
|
||||
}
|
||||
|
||||
$pPath = $this->_dirname($path);
|
||||
if ($this->_inPath($pPath, $this->root)) {
|
||||
|
|
|
@ -118,7 +118,7 @@ class elFinderVolumeGoogleDrive extends elFinderVolumeDriver
|
|||
'tmbPath' => '',
|
||||
'separator' => '/',
|
||||
'useGoogleTmb' => true,
|
||||
'acceptedName' => '#^[^/\\?*:|"<>]*[^./\\?*:|"<>]$#',
|
||||
'acceptedName' => '#.#',
|
||||
'rootCssClass' => 'elfinder-navbar-root-googledrive',
|
||||
'publishPermission' => [
|
||||
'type' => 'anyone',
|
||||
|
@ -157,8 +157,10 @@ class elFinderVolumeGoogleDrive extends elFinderVolumeDriver
|
|||
$id = 'root';
|
||||
$parent = '';
|
||||
} else {
|
||||
$path = str_replace('\\/', chr(0), $path);
|
||||
$paths = explode('/', $path);
|
||||
$id = array_pop($paths);
|
||||
$id = str_replace(chr(0), '/', $id);
|
||||
if ($paths) {
|
||||
$parent = '/' . implode('/', $paths);
|
||||
$pid = array_pop($paths);
|
||||
|
@ -676,16 +678,20 @@ class elFinderVolumeGoogleDrive extends elFinderVolumeDriver
|
|||
}
|
||||
}
|
||||
|
||||
if (isset($options['user']) && $options['user'] === 'init') {
|
||||
$itpCare = isset($options['code']);
|
||||
$code = $itpCare? $options['code'] : (isset($_GET['code'])? $_GET['code'] : '');
|
||||
if ($code || (isset($options['user']) && $options['user'] === 'init')) {
|
||||
if (empty($options['url'])) {
|
||||
$options['url'] = elFinder::getConnectorUrl();
|
||||
}
|
||||
|
||||
$callback = $options['url']
|
||||
. '?cmd=netmount&protocol=googledrive&host=1';
|
||||
$client->setRedirectUri($callback);
|
||||
if (isset($options['id'])) {
|
||||
$callback = $options['url']
|
||||
. (strpos($options['url'], '?') !== false? '&' : '?') . 'cmd=netmount&protocol=googledrive&host=' . ($options['id'] === 'elfinder'? '1' : $options['id']);
|
||||
$client->setRedirectUri($callback);
|
||||
}
|
||||
|
||||
if (!$aToken && empty($_GET['code'])) {
|
||||
if (!$aToken && empty($code)) {
|
||||
$client->setScopes([Google_Service_Drive::DRIVE]);
|
||||
if (!empty($options['offline'])) {
|
||||
$client->setApprovalPrompt('force');
|
||||
|
@ -693,9 +699,9 @@ class elFinderVolumeGoogleDrive extends elFinderVolumeDriver
|
|||
}
|
||||
$url = $client->createAuthUrl();
|
||||
|
||||
$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 = '<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">';
|
||||
$html .= '<script>
|
||||
$("#' . $options['id'] . '").elfinder("instance").trigger("netmount", {protocol: "googledrive", mode: "makebtn"});
|
||||
$("#' . $options['id'] . '").elfinder("instance").trigger("netmount", {protocol: "googledrive", mode: "makebtn", url: "' . $url . '"});
|
||||
</script>';
|
||||
if (empty($options['pass']) && $options['host'] !== '1') {
|
||||
$options['pass'] = 'return';
|
||||
|
@ -712,17 +718,38 @@ class elFinderVolumeGoogleDrive extends elFinderVolumeDriver
|
|||
return ['exit' => 'callback', 'out' => $out];
|
||||
}
|
||||
} else {
|
||||
if (!empty($_GET['code'])) {
|
||||
$aToken = $client->fetchAccessTokenWithAuthCode($_GET['code']);
|
||||
$options['access_token'] = $aToken;
|
||||
$this->session->set('GoogleDriveTokens', $aToken)->set('GoogleDriveAuthParams', $options);
|
||||
$out = [
|
||||
'node' => $options['id'],
|
||||
'json' => '{"protocol": "googledrive", "mode": "done", "reset": 1}',
|
||||
'bind' => 'netmount',
|
||||
];
|
||||
|
||||
return ['exit' => 'callback', 'out' => $out];
|
||||
if ($code) {
|
||||
if (!empty($options['id'])) {
|
||||
$aToken = $client->fetchAccessTokenWithAuthCode($code);
|
||||
$options['access_token'] = $aToken;
|
||||
unset($options['code']);
|
||||
$this->session->set('GoogleDriveTokens', $aToken)->set('GoogleDriveAuthParams', $options);
|
||||
$out = [
|
||||
'node' => $options['id'],
|
||||
'json' => '{"protocol": "googledrive", "mode": "done", "reset": 1}',
|
||||
'bind' => 'netmount',
|
||||
];
|
||||
} else {
|
||||
$nodeid = ($_GET['host'] === '1')? 'elfinder' : $_GET['host'];
|
||||
$out = array(
|
||||
'node' => $nodeid,
|
||||
'json' => json_encode(array(
|
||||
'protocol' => 'googledrive',
|
||||
'host' => $nodeid,
|
||||
'mode' => 'redirect',
|
||||
'options' => array(
|
||||
'id' => $nodeid,
|
||||
'code'=> $code
|
||||
)
|
||||
)),
|
||||
'bind' => 'netmount'
|
||||
);
|
||||
}
|
||||
if (!$itpCare) {
|
||||
return array('exit' => 'callback', 'out' => $out);
|
||||
} else {
|
||||
return array('exit' => true, 'body' => $out['json']);
|
||||
}
|
||||
}
|
||||
$path = $options['path'];
|
||||
if ($path === '/') {
|
||||
|
@ -744,7 +771,8 @@ class elFinderVolumeGoogleDrive extends elFinderVolumeDriver
|
|||
$folders = ['root' => $rootObj->getName()] + $folders;
|
||||
$folders = json_encode($folders);
|
||||
$expires = empty($aToken['refresh_token']) ? $aToken['created'] + $aToken['expires_in'] - 30 : 0;
|
||||
$json = '{"protocol": "googledrive", "mode": "done", "folders": ' . $folders . ', "expires": ' . $expires . '}';
|
||||
$mnt2res = empty($aToken['refresh_token']) ? '' : ', "mnt2res": 1';
|
||||
$json = '{"protocol": "googledrive", "mode": "done", "folders": ' . $folders . ', "expires": ' . $expires . $mnt2res . '}';
|
||||
$options['pass'] = 'return';
|
||||
$html = 'Google.com';
|
||||
$html .= '<script>
|
||||
|
@ -907,7 +935,7 @@ class elFinderVolumeGoogleDrive extends elFinderVolumeDriver
|
|||
}
|
||||
|
||||
$errors = [];
|
||||
if (!$this->service) {
|
||||
if ($this->needOnline && !$this->service) {
|
||||
if (($this->options['googleApiClient'] || defined('ELFINDER_GOOGLEDRIVE_GOOGLEAPICLIENT')) && !class_exists('Google_Client')) {
|
||||
include_once $this->options['googleApiClient'] ? $this->options['googleApiClient'] : ELFINDER_GOOGLEDRIVE_GOOGLEAPICLIENT;
|
||||
}
|
||||
|
@ -948,17 +976,21 @@ class elFinderVolumeGoogleDrive extends elFinderVolumeDriver
|
|||
$this->service = new \Google_Service_Drive($client);
|
||||
}
|
||||
|
||||
$this->netMountKey = md5($aToken . '-' . $this->options['path']);
|
||||
if ($this->needOnline) {
|
||||
$this->netMountKey = md5($aToken . '-' . $this->options['path']);
|
||||
}
|
||||
} catch (InvalidArgumentException $e) {
|
||||
$errors[] = $e->getMessage();
|
||||
} catch (Google_Service_Exception $e) {
|
||||
$errors[] = $e->getMessage();
|
||||
}
|
||||
|
||||
if (!$this->service) {
|
||||
if ($this->needOnline && !$this->service) {
|
||||
$this->session->remove($this->id . $this->netMountKey);
|
||||
if ($aTokenFile) {
|
||||
unlink($aTokenFile);
|
||||
if (is_file($aTokenFile)) {
|
||||
unlink($aTokenFile);
|
||||
}
|
||||
}
|
||||
$errors[] = 'Google Drive Service could not be loaded.';
|
||||
|
||||
|
@ -971,13 +1003,20 @@ class elFinderVolumeGoogleDrive extends elFinderVolumeDriver
|
|||
}
|
||||
$this->root = $this->options['path'] = $this->_normpath($this->options['path']);
|
||||
|
||||
$this->options['root'] == '' ? $this->options['root'] = $this->_gd_getNameByPath('root') : $this->options['root'];
|
||||
|
||||
if (empty($this->options['alias'])) {
|
||||
$this->options['alias'] = ($this->options['path'] === '/') ? $this->options['root'] : sprintf($this->options['gdAlias'], $this->_gd_getNameByPath($this->options['path']));
|
||||
if ($this->needOnline) {
|
||||
$this->options['root'] = ($this->options['root'] === '')? $this->_gd_getNameByPath('root') : $this->options['root'];
|
||||
$this->options['alias'] = ($this->options['path'] === '/') ? $this->options['root'] : sprintf($this->options['gdAlias'], $this->_gd_getNameByPath($this->options['path']));
|
||||
if (!empty($this->options['netkey'])) {
|
||||
elFinder::$instance->updateNetVolumeOption($this->options['netkey'], 'alias', $this->options['alias']);
|
||||
}
|
||||
} else {
|
||||
$this->options['root'] = ($this->options['root'] === '')? 'GoogleDrive' : $this->options['root'];
|
||||
$this->options['alias'] = $this->options['root'];
|
||||
}
|
||||
}
|
||||
|
||||
$this->rootName = $this->options['alias'];
|
||||
$this->rootName = isset($this->options['alias'])? $this->options['alias'] : 'GoogleDrive';
|
||||
|
||||
if (!empty($this->options['tmpPath'])) {
|
||||
if ((is_dir($this->options['tmpPath']) || mkdir($this->options['tmpPath'])) && is_writable($this->options['tmpPath'])) {
|
||||
|
@ -1020,7 +1059,7 @@ class elFinderVolumeGoogleDrive extends elFinderVolumeDriver
|
|||
$this->tmp = $this->tmbPath;
|
||||
}
|
||||
|
||||
if ($this->isMyReload()) {
|
||||
if ($this->needOnline && $this->isMyReload()) {
|
||||
$this->_gd_getDirectoryData(false);
|
||||
}
|
||||
}
|
||||
|
@ -1375,7 +1414,7 @@ class elFinderVolumeGoogleDrive extends elFinderVolumeDriver
|
|||
public function debug()
|
||||
{
|
||||
$res = parent::debug();
|
||||
if (empty($this->options['refresh_token']) && $this->options['access_token'] && isset($this->options['access_token']['refresh_token'])) {
|
||||
if (!empty($this->options['netkey']) && empty($this->options['refresh_token']) && $this->options['access_token'] && isset($this->options['access_token']['refresh_token'])) {
|
||||
$res['refresh_token'] = $this->options['access_token']['refresh_token'];
|
||||
}
|
||||
|
||||
|
@ -1425,7 +1464,7 @@ class elFinderVolumeGoogleDrive extends elFinderVolumeDriver
|
|||
**/
|
||||
protected function _joinPath($dir, $name)
|
||||
{
|
||||
return $this->_normpath($dir . '/' . $name);
|
||||
return $this->_normpath($dir . '/' . str_replace('/', '\\/', $name));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1658,6 +1697,16 @@ class elFinderVolumeGoogleDrive extends elFinderVolumeDriver
|
|||
'headers' => array('Authorization: Bearer ' . $access_token),
|
||||
);
|
||||
|
||||
// to support range request
|
||||
if (func_num_args() > 2) {
|
||||
$opts = func_get_arg(2);
|
||||
} else {
|
||||
$opts = array();
|
||||
}
|
||||
if (!empty($opts['httpheaders'])) {
|
||||
$data['headers'] = array_merge($opts['httpheaders'], $data['headers']);
|
||||
}
|
||||
|
||||
return elFinder::getStreamByUrl($data);
|
||||
}
|
||||
}
|
||||
|
@ -1677,7 +1726,7 @@ class elFinderVolumeGoogleDrive extends elFinderVolumeDriver
|
|||
**/
|
||||
protected function _fclose($fp, $path = '')
|
||||
{
|
||||
fclose($fp);
|
||||
is_resource($fp) && fclose($fp);
|
||||
if ($path) {
|
||||
unlink($this->getTempFile($path));
|
||||
}
|
||||
|
@ -1876,7 +1925,7 @@ class elFinderVolumeGoogleDrive extends elFinderVolumeDriver
|
|||
protected function _save($fp, $path, $name, $stat)
|
||||
{
|
||||
if ($name !== '') {
|
||||
$path .= '/' . $name;
|
||||
$path .= '/' . str_replace('/', '\\/', $name);
|
||||
}
|
||||
list($parentId, $itemId, $parent) = $this->_gd_splitPath($path);
|
||||
if ($name === '') {
|
||||
|
|
|
@ -75,7 +75,6 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver
|
|||
$this->options['alias'] = ''; // alias to replace root dir name
|
||||
$this->options['dirMode'] = 0755; // new dirs mode
|
||||
$this->options['fileMode'] = 0644; // new files mode
|
||||
$this->options['quarantine'] = '.quarantine'; // quarantine folder name - required to check archive (must be hidden)
|
||||
$this->options['rootCssClass'] = 'elfinder-navbar-root-local';
|
||||
$this->options['followSymLinks'] = true;
|
||||
$this->options['detectDirIcon'] = ''; // file name that is detected as a folder icon e.g. '.diricon.png'
|
||||
|
@ -114,11 +113,11 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver
|
|||
}
|
||||
// detect systemRoot
|
||||
if (!isset($this->options['systemRoot'])) {
|
||||
if ($cwd[0] === $this->separator || $this->root[0] === $this->separator) {
|
||||
$this->systemRoot = $this->separator;
|
||||
} else if (preg_match('/^([a-zA-Z]:' . preg_quote($this->separator, '/') . ')/', $this->root, $m)) {
|
||||
if ($cwd[0] === DIRECTORY_SEPARATOR || $this->root[0] === DIRECTORY_SEPARATOR) {
|
||||
$this->systemRoot = DIRECTORY_SEPARATOR;
|
||||
} else if (preg_match('/^([a-zA-Z]:' . preg_quote(DIRECTORY_SEPARATOR, '/') . ')/', $this->root, $m)) {
|
||||
$this->systemRoot = $m[1];
|
||||
} else if (preg_match('/^([a-zA-Z]:' . preg_quote($this->separator, '/') . ')/', $cwd, $m)) {
|
||||
} else if (preg_match('/^([a-zA-Z]:' . preg_quote(DIRECTORY_SEPARATOR, '/') . ')/', $cwd, $m)) {
|
||||
$this->systemRoot = $m[1];
|
||||
}
|
||||
}
|
||||
|
@ -150,28 +149,48 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver
|
|||
*/
|
||||
protected function configure()
|
||||
{
|
||||
$hiddens = array();
|
||||
$root = $this->stat($this->root);
|
||||
|
||||
// chek thumbnails path
|
||||
if ($this->options['tmbPath']) {
|
||||
$this->options['tmbPath'] = strpos($this->options['tmbPath'], DIRECTORY_SEPARATOR) === false
|
||||
// tmb path set as dirname under root dir
|
||||
? $this->_abspath($this->options['tmbPath'])
|
||||
// tmb path as full path
|
||||
: $this->_normpath($this->options['tmbPath']);
|
||||
// check thumbnails path
|
||||
if (!empty($this->options['tmbPath'])) {
|
||||
if (strpos($this->options['tmbPath'], DIRECTORY_SEPARATOR) === false) {
|
||||
$hiddens['tmb'] = $this->options['tmbPath'];
|
||||
$this->options['tmbPath'] = $this->_abspath($this->options['tmbPath']);
|
||||
} else {
|
||||
$this->options['tmbPath'] = $this->_normpath($this->options['tmbPath']);
|
||||
}
|
||||
}
|
||||
// check temp path
|
||||
if (!empty($this->options['tmpPath'])) {
|
||||
if (strpos($this->options['tmpPath'], DIRECTORY_SEPARATOR) === false) {
|
||||
$hiddens['temp'] = $this->options['tmpPath'];
|
||||
$this->options['tmpPath'] = $this->_abspath($this->options['tmpPath']);
|
||||
} else {
|
||||
$this->options['tmpPath'] = $this->_normpath($this->options['tmpPath']);
|
||||
}
|
||||
}
|
||||
// check quarantine path
|
||||
$_quarantine = '';
|
||||
if (!empty($this->options['quarantine'])) {
|
||||
if (strpos($this->options['quarantine'], DIRECTORY_SEPARATOR) === false) {
|
||||
//$hiddens['quarantine'] = $this->options['quarantine'];
|
||||
//$this->options['quarantine'] = $this->_abspath($this->options['quarantine']);
|
||||
$_quarantine = $this->_abspath($this->options['quarantine']);
|
||||
$this->options['quarantine'] = '';
|
||||
} else {
|
||||
$this->options['quarantine'] = $this->_normpath($this->options['quarantine']);
|
||||
}
|
||||
} else {
|
||||
$_quarantine = $this->_abspath('.quarantine');
|
||||
}
|
||||
is_dir($_quarantine) && self::localRmdirRecursive($_quarantine);
|
||||
|
||||
parent::configure();
|
||||
|
||||
// set $this->tmp by options['tmpPath']
|
||||
$this->tmp = '';
|
||||
if (!empty($this->options['tmpPath'])) {
|
||||
if ((is_dir($this->options['tmpPath']) || mkdir($this->options['tmpPath'], 0755, true)) && is_writable($this->options['tmpPath'])) {
|
||||
$this->tmp = $this->options['tmpPath'];
|
||||
}
|
||||
}
|
||||
if (!$this->tmp && ($tmp = elFinder::getStaticVar('commonTempPath'))) {
|
||||
$this->tmp = $tmp;
|
||||
// check tmbPath
|
||||
if (!$this->tmbPath && isset($hiddens['tmb'])) {
|
||||
unset($hiddens['tmb']);
|
||||
}
|
||||
|
||||
// if no thumbnails url - try detect it
|
||||
|
@ -184,20 +203,33 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver
|
|||
}
|
||||
}
|
||||
|
||||
// set $this->tmp by options['tmpPath']
|
||||
$this->tmp = '';
|
||||
if (!empty($this->options['tmpPath'])) {
|
||||
if ((is_dir($this->options['tmpPath']) || mkdir($this->options['tmpPath'], $this->options['dirMode'], true)) && is_writable($this->options['tmpPath'])) {
|
||||
$this->tmp = $this->options['tmpPath'];
|
||||
} else {
|
||||
if (isset($hiddens['temp'])) {
|
||||
unset($hiddens['temp']);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!$this->tmp && ($tmp = elFinder::getStaticVar('commonTempPath'))) {
|
||||
$this->tmp = $tmp;
|
||||
}
|
||||
|
||||
// check quarantine dir
|
||||
$this->quarantine = '';
|
||||
if (!empty($this->options['quarantine'])) {
|
||||
if (is_dir($this->options['quarantine'])) {
|
||||
if (is_writable($this->options['quarantine'])) {
|
||||
$this->quarantine = $this->options['quarantine'];
|
||||
}
|
||||
$this->options['quarantine'] = '';
|
||||
if ((is_dir($this->options['quarantine']) || mkdir($this->options['quarantine'], $this->options['dirMode'], true)) && is_writable($this->options['quarantine'])) {
|
||||
$this->quarantine = $this->options['quarantine'];
|
||||
} else {
|
||||
$this->quarantine = $this->_abspath($this->options['quarantine']);
|
||||
if ((!is_dir($this->quarantine) && !mkdir($this->quarantine)) || !is_writable($this->quarantine)) {
|
||||
$this->options['quarantine'] = $this->quarantine = '';
|
||||
if (isset($hiddens['quarantine'])) {
|
||||
unset($hiddens['quarantine']);
|
||||
}
|
||||
}
|
||||
} else if ($_path = elFinder::getCommonTempPath()) {
|
||||
$this->quarantine = $_path;
|
||||
}
|
||||
|
||||
if (!$this->quarantine) {
|
||||
|
@ -209,14 +241,16 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver
|
|||
}
|
||||
}
|
||||
|
||||
if ($this->options['quarantine']) {
|
||||
$this->attributes[] = array(
|
||||
'pattern' => '~^' . preg_quote(DIRECTORY_SEPARATOR . $this->options['quarantine']) . '$~',
|
||||
'read' => false,
|
||||
'write' => false,
|
||||
'locked' => true,
|
||||
'hidden' => true
|
||||
);
|
||||
if ($hiddens) {
|
||||
foreach ($hiddens as $hidden) {
|
||||
$this->attributes[] = array(
|
||||
'pattern' => '~^' . preg_quote(DIRECTORY_SEPARATOR . $hidden, '~') . '$~',
|
||||
'read' => false,
|
||||
'write' => false,
|
||||
'locked' => true,
|
||||
'hidden' => true
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($this->options['keepTimestamp'])) {
|
||||
|
@ -319,7 +353,20 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver
|
|||
**/
|
||||
protected function _joinPath($dir, $name)
|
||||
{
|
||||
return rtrim($dir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . $name;
|
||||
$dir = rtrim($dir, DIRECTORY_SEPARATOR);
|
||||
$path = realpath($dir . DIRECTORY_SEPARATOR . $name);
|
||||
// realpath() returns FALSE if the file does not exist
|
||||
if ($path === false || strpos($path, $this->root) !== 0) {
|
||||
if (DIRECTORY_SEPARATOR !== '/') {
|
||||
$name = str_replace('/', DIRECTORY_SEPARATOR, $name);
|
||||
}
|
||||
// Directory traversal measures
|
||||
if (strpos($name, '..' . DIRECTORY_SEPARATOR) !== false) {
|
||||
$name = basename($name);
|
||||
}
|
||||
$path = $dir . DIRECTORY_SEPARATOR . $name;
|
||||
}
|
||||
return $path;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -423,8 +470,9 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver
|
|||
if ($path === DIRECTORY_SEPARATOR) {
|
||||
return $this->root;
|
||||
} else {
|
||||
if ($path[0] === DIRECTORY_SEPARATOR) {
|
||||
// for link
|
||||
if (strpos($path, $this->systemRoot) === 0) {
|
||||
return $path;
|
||||
} else if (DIRECTORY_SEPARATOR !== '/' && preg_match('/^[a-zA-Z]:' . preg_quote(DIRECTORY_SEPARATOR, '/') . '/', $path)) {
|
||||
return $path;
|
||||
} else {
|
||||
return $this->_joinPath($this->root, $path);
|
||||
|
@ -677,7 +725,7 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver
|
|||
protected function _dimensions($path, $mime)
|
||||
{
|
||||
clearstatcache();
|
||||
return strpos($mime, 'image') === 0 && is_readable($path) && ($s = getimagesize($path)) !== false
|
||||
return strpos($mime, 'image') === 0 && is_readable($path) && filesize($path) && ($s = getimagesize($path)) !== false
|
||||
? $s[0] . 'x' . $s[1]
|
||||
: false;
|
||||
}
|
||||
|
@ -1116,7 +1164,11 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver
|
|||
}
|
||||
|
||||
// extract in quarantine
|
||||
$this->unpackArchive($path, $arc, $archive ? true : $dir);
|
||||
try {
|
||||
$this->unpackArchive($path, $arc, $archive ? true : $dir);
|
||||
} catch(Exception $e) {
|
||||
return $this->setError($e->getMessage());
|
||||
}
|
||||
|
||||
// get files list
|
||||
try {
|
||||
|
@ -1387,5 +1439,23 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver
|
|||
return ($this->stripos($name, $this->doSearchCurrentQuery['q']) === false) ? false : true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a symbolic link
|
||||
*
|
||||
* @param string $target The target
|
||||
* @param string $link The link
|
||||
*
|
||||
* @return boolean ( result of symlink() )
|
||||
*/
|
||||
protected function localFileSystemSymlink($target, $link)
|
||||
{
|
||||
$res = false;
|
||||
$errlev = error_reporting();
|
||||
error_reporting($errlev ^ E_WARNING);
|
||||
if ($res = symlink(realpath($target), $link)) {
|
||||
$res = is_readable($link);
|
||||
}
|
||||
error_reporting($errlev);
|
||||
return $res;
|
||||
}
|
||||
} // END class
|
||||
|
||||
|
|
|
@ -79,7 +79,8 @@ class elFinderVolumeMySQL extends elFinderVolumeDriver
|
|||
'tmbPath' => '',
|
||||
'tmpPath' => '',
|
||||
'rootCssClass' => 'elfinder-navbar-root-sql',
|
||||
'noSessionCache' => array('hasdirs')
|
||||
'noSessionCache' => array('hasdirs'),
|
||||
'isLocalhost' => false
|
||||
);
|
||||
$this->options = array_merge($this->options, $opts);
|
||||
$this->options['mimeDetect'] = 'internal';
|
||||
|
@ -105,13 +106,25 @@ class elFinderVolumeMySQL extends elFinderVolumeDriver
|
|||
|| !$this->options['db']
|
||||
|| !$this->options['path']
|
||||
|| !$this->options['files_table']) {
|
||||
return false;
|
||||
return $this->setError('Required options "host", "socket", "user", "pass", "db", "path" or "files_table" are undefined.');
|
||||
}
|
||||
|
||||
$err = null;
|
||||
if ($this->db = @new mysqli($this->options['host'], $this->options['user'], $this->options['pass'], $this->options['db'], $this->options['port'], $this->options['socket'])) {
|
||||
if ($this->db && $this->db->connect_error) {
|
||||
$err = $this->db->connect_error;
|
||||
}
|
||||
} else {
|
||||
$err = mysqli_connect_error();
|
||||
}
|
||||
if ($err) {
|
||||
return $this->setError(array('Unable to connect to MySQL server.', $err));
|
||||
}
|
||||
|
||||
$this->db = new mysqli($this->options['host'], $this->options['user'], $this->options['pass'], $this->options['db'], $this->options['port'], $this->options['socket']);
|
||||
if ($this->db->connect_error || mysqli_connect_error()) {
|
||||
return false;
|
||||
if (!$this->needOnline && empty($this->ARGS['init'])) {
|
||||
$this->db->close();
|
||||
$this->db = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
$this->db->set_charset('utf8');
|
||||
|
@ -126,7 +139,7 @@ class elFinderVolumeMySQL extends elFinderVolumeDriver
|
|||
}
|
||||
|
||||
if (!$this->tbf) {
|
||||
return false;
|
||||
return $this->setError('The specified database table cannot be found.');
|
||||
}
|
||||
|
||||
$this->updateCache($this->options['path'], $this->_stat($this->options['path']));
|
||||
|
@ -134,6 +147,9 @@ class elFinderVolumeMySQL extends elFinderVolumeDriver
|
|||
// enable command archive
|
||||
$this->options['useRemoteArchive'] = true;
|
||||
|
||||
// check isLocalhost
|
||||
$this->isLocalhost = $this->options['isLocalhost'] || $this->options['host'] === 'localhost' || $this->options['host'] === '127.0.0.1' || $this->options['host'] === '::1';
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -178,7 +194,7 @@ class elFinderVolumeMySQL extends elFinderVolumeDriver
|
|||
**/
|
||||
public function umount()
|
||||
{
|
||||
$this->db->close();
|
||||
$this->db && $this->db->close();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -251,10 +267,10 @@ class elFinderVolumeMySQL extends elFinderVolumeDriver
|
|||
$this->dirsCache[$path] = array();
|
||||
|
||||
$sql = 'SELECT f.id, f.parent_id, f.name, f.size, f.mtime AS ts, f.mime, f.read, f.write, f.locked, f.hidden, f.width, f.height, IF(ch.id, 1, 0) AS dirs
|
||||
FROM ' . $this->tbf . ' AS f
|
||||
LEFT JOIN ' . $this->tbf . ' AS ch ON ch.parent_id=f.id AND ch.mime=\'directory\'
|
||||
WHERE f.parent_id=\'' . $path . '\'
|
||||
GROUP BY f.id, ch.id';
|
||||
FROM ' . $this->tbf . ' AS f
|
||||
LEFT JOIN ' . $this->tbf . ' AS ch ON ch.parent_id=f.id AND ch.mime=\'directory\'
|
||||
WHERE f.parent_id=\'' . $path . '\'
|
||||
GROUP BY f.id, ch.id';
|
||||
|
||||
$res = $this->query($sql);
|
||||
if ($res) {
|
||||
|
@ -385,8 +401,8 @@ class elFinderVolumeMySQL extends elFinderVolumeDriver
|
|||
}
|
||||
|
||||
$sql = 'SELECT f.id, f.parent_id, f.name, f.size, f.mtime AS ts, f.mime, f.read, f.write, f.locked, f.hidden, f.width, f.height, 0 AS dirs
|
||||
FROM %s AS f
|
||||
WHERE %s';
|
||||
FROM %s AS f
|
||||
WHERE %s';
|
||||
|
||||
$sql = sprintf($sql, $this->tbf, $whr);
|
||||
|
||||
|
@ -453,7 +469,7 @@ class elFinderVolumeMySQL extends elFinderVolumeDriver
|
|||
**/
|
||||
protected function _basename($path)
|
||||
{
|
||||
return ($stat = $this->stat($path)) ? $stat['name'] : false;
|
||||
return (($stat = $this->stat($path)) && isset($stat['name'])) ? $stat['name'] : false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -577,10 +593,10 @@ class elFinderVolumeMySQL extends elFinderVolumeDriver
|
|||
protected function _stat($path)
|
||||
{
|
||||
$sql = 'SELECT f.id, f.parent_id, f.name, f.size, f.mtime AS ts, f.mime, f.read, f.write, f.locked, f.hidden, f.width, f.height, IF(ch.id, 1, 0) AS dirs
|
||||
FROM ' . $this->tbf . ' AS f
|
||||
LEFT JOIN ' . $this->tbf . ' AS ch ON ch.parent_id=f.id AND ch.mime=\'directory\'
|
||||
WHERE f.id=\'' . $path . '\'
|
||||
GROUP BY f.id, ch.id';
|
||||
FROM ' . $this->tbf . ' AS f
|
||||
LEFT JOIN ' . $this->tbf . ' AS ch ON ch.parent_id=f.id AND ch.mime=\'directory\'
|
||||
WHERE f.id=\'' . $path . '\'
|
||||
GROUP BY f.id, ch.id';
|
||||
|
||||
$res = $this->query($sql);
|
||||
|
||||
|
@ -849,29 +865,32 @@ class elFinderVolumeMySQL extends elFinderVolumeDriver
|
|||
{
|
||||
$this->clearcache();
|
||||
|
||||
$mime = $stat['mime'];
|
||||
$mime = !empty($stat['mime']) ? $stat['mime'] : $this->mimetype($name, true);
|
||||
$w = !empty($stat['width']) ? $stat['width'] : 0;
|
||||
$h = !empty($stat['height']) ? $stat['height'] : 0;
|
||||
$ts = !empty($stat['ts']) ? $stat['ts'] : time();
|
||||
|
||||
$id = $this->_joinPath($dir, $name);
|
||||
elFinder::rewind($fp);
|
||||
$stat = fstat($fp);
|
||||
$size = $stat['size'];
|
||||
if (!isset($stat['size'])) {
|
||||
$stat = fstat($fp);
|
||||
$size = $stat['size'];
|
||||
} else {
|
||||
$size = $stat['size'];
|
||||
}
|
||||
|
||||
if (($tmpfile = tempnam($this->tmpPath, $this->id))) {
|
||||
if ($this->isLocalhost && ($tmpfile = tempnam($this->tmpPath, $this->id))) {
|
||||
if (($trgfp = fopen($tmpfile, 'wb')) == false) {
|
||||
unlink($tmpfile);
|
||||
} else {
|
||||
while (!feof($fp)) {
|
||||
fwrite($trgfp, fread($fp, 8192));
|
||||
}
|
||||
elFinder::rewind($fp);
|
||||
stream_copy_to_stream($fp, $trgfp);
|
||||
fclose($trgfp);
|
||||
chmod($tmpfile, 0644);
|
||||
|
||||
$sql = $id > 0
|
||||
? 'REPLACE INTO %s (id, parent_id, name, content, size, mtime, mime, width, height) VALUES (' . $id . ', %d, \'%s\', LOAD_FILE(\'%s\'), %d, %d, \'%s\', %d, %d)'
|
||||
: 'INSERT INTO %s (parent_id, name, content, size, mtime, mime, width, height) VALUES (%d, \'%s\', LOAD_FILE(\'%s\'), %d, %d, \'%s\', %d, %d)';
|
||||
$sql = sprintf($sql, $this->tbf, $dir, $this->db->real_escape_string($name), $this->loadFilePath($tmpfile), $size, time(), $mime, $w, $h);
|
||||
$sql = sprintf($sql, $this->tbf, $dir, $this->db->real_escape_string($name), $this->loadFilePath($tmpfile), $size, $ts, $mime, $w, $h);
|
||||
|
||||
$res = $this->query($sql);
|
||||
unlink($tmpfile);
|
||||
|
@ -892,7 +911,7 @@ class elFinderVolumeMySQL extends elFinderVolumeDriver
|
|||
$sql = $id > 0
|
||||
? 'REPLACE INTO %s (id, parent_id, name, content, size, mtime, mime, width, height) VALUES (' . $id . ', %d, \'%s\', \'%s\', %d, %d, \'%s\', %d, %d)'
|
||||
: 'INSERT INTO %s (parent_id, name, content, size, mtime, mime, width, height) VALUES (%d, \'%s\', \'%s\', %d, %d, \'%s\', %d, %d)';
|
||||
$sql = sprintf($sql, $this->tbf, $dir, $this->db->real_escape_string($name), $this->db->real_escape_string($content), $size, time(), $mime, $w, $h);
|
||||
$sql = sprintf($sql, $this->tbf, $dir, $this->db->real_escape_string($name), $this->db->real_escape_string($content), $size, $ts, $mime, $w, $h);
|
||||
|
||||
unset($content);
|
||||
|
||||
|
|
|
@ -83,6 +83,13 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
|
|||
**/
|
||||
private $expires;
|
||||
|
||||
/**
|
||||
* Path to access token file for permanent mount
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $aTokenFile = '';
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Extend options with required fields.
|
||||
|
@ -127,7 +134,7 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
|
|||
* @throws Exception Thrown if the redirect URI of this Client instance's
|
||||
* state is not set
|
||||
*/
|
||||
protected function _od_obtainAccessToken($client_id, $client_secret, $code)
|
||||
protected function _od_obtainAccessToken($client_id, $client_secret, $code, $nodeid)
|
||||
{
|
||||
if (null === $client_id) {
|
||||
return 'The client ID must be set to call obtainAccessToken()';
|
||||
|
@ -137,6 +144,11 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
|
|||
return 'The client Secret must be set to call obtainAccessToken()';
|
||||
}
|
||||
|
||||
$redirect = elFinder::getConnectorUrl();
|
||||
if (strpos($redirect, '/netmount/onedrive/') === false) {
|
||||
$redirect .= '/netmount/onedrive/' . ($nodeid === 'elfinder'? '1' : $nodeid);
|
||||
}
|
||||
|
||||
$url = self::TOKEN_URL;
|
||||
|
||||
$curl = curl_init();
|
||||
|
@ -144,7 +156,7 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
|
|||
$fields = http_build_query(
|
||||
array(
|
||||
'client_id' => $client_id,
|
||||
'redirect_uri' => elFinder::getConnectorUrl(),
|
||||
'redirect_uri' => $redirect,
|
||||
'client_secret' => $client_secret,
|
||||
'code' => $code,
|
||||
'grant_type' => 'authorization_code',
|
||||
|
@ -164,17 +176,7 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
|
|||
CURLOPT_URL => $url,
|
||||
));
|
||||
|
||||
$result = curl_exec($curl);
|
||||
|
||||
if (false === $result) {
|
||||
if (curl_errno($curl)) {
|
||||
throw new \Exception('curl_setopt_array() failed: '
|
||||
. curl_error($curl));
|
||||
} else {
|
||||
throw new \Exception('curl_setopt_array(): empty response');
|
||||
}
|
||||
}
|
||||
curl_close($curl);
|
||||
$result = elFinder::curlExec($curl);
|
||||
|
||||
$decoded = json_decode($result);
|
||||
|
||||
|
@ -182,29 +184,26 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
|
|||
throw new \Exception('json_decode() failed');
|
||||
}
|
||||
|
||||
return (object)array(
|
||||
$res = (object)array(
|
||||
'expires' => time() + $decoded->expires_in - 30,
|
||||
'data' => $decoded,
|
||||
'initialToken' => '',
|
||||
'data' => $decoded
|
||||
);
|
||||
if (!empty($decoded->refresh_token)) {
|
||||
$res->initialToken = md5($client_id . $decoded->refresh_token);
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get token and auto refresh.
|
||||
*
|
||||
* @return true|Exception
|
||||
* @return true
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function _od_refreshToken()
|
||||
{
|
||||
if (!property_exists($this->token, 'expires') || $this->token->expires < time()) {
|
||||
if (!$token = $this->session->get('OneDriveTokens')) {
|
||||
$token = $this->token;
|
||||
}
|
||||
if (empty($token->data->refresh_token)) {
|
||||
$this->session->remove('OneDriveTokens');
|
||||
throw new \Exception(elFinder::ERROR_REAUTH_REQUIRE);
|
||||
}
|
||||
|
||||
if (!$this->options['client_id']) {
|
||||
$this->options['client_id'] = ELFINDER_ONEDRIVE_CLIENTID;
|
||||
}
|
||||
|
@ -213,6 +212,13 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
|
|||
$this->options['client_secret'] = ELFINDER_ONEDRIVE_CLIENTSECRET;
|
||||
}
|
||||
|
||||
if (empty($this->token->data->refresh_token)) {
|
||||
throw new \Exception(elFinder::ERROR_REAUTH_REQUIRE);
|
||||
} else {
|
||||
$refresh_token = $this->token->data->refresh_token;
|
||||
$initialToken = $this->_od_getInitialToken();
|
||||
}
|
||||
|
||||
$url = self::TOKEN_URL;
|
||||
|
||||
$curl = curl_init();
|
||||
|
@ -224,21 +230,12 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
|
|||
CURLOPT_POSTFIELDS => 'client_id=' . urlencode($this->options['client_id'])
|
||||
. '&client_secret=' . urlencode($this->options['client_secret'])
|
||||
. '&grant_type=refresh_token'
|
||||
. '&refresh_token=' . urlencode($token->data->refresh_token),
|
||||
. '&refresh_token=' . urlencode($this->token->data->refresh_token),
|
||||
|
||||
CURLOPT_URL => $url,
|
||||
));
|
||||
|
||||
$result = curl_exec($curl);
|
||||
|
||||
if (!$result) {
|
||||
if (curl_errno($curl)) {
|
||||
throw new \Exception('curl_setopt_array() failed: ' . curl_error($curl));
|
||||
} else {
|
||||
throw new \Exception('curl_setopt_array(): empty response');
|
||||
}
|
||||
}
|
||||
curl_close($curl);
|
||||
$result = elFinder::curlExec($curl);
|
||||
|
||||
$decoded = json_decode($result);
|
||||
|
||||
|
@ -247,20 +244,47 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
|
|||
}
|
||||
|
||||
if (empty($decoded->access_token)) {
|
||||
throw new \Exception(elFinder::ERROR_REAUTH_REQUIRE);
|
||||
if ($this->aTokenFile) {
|
||||
if (is_file($this->aTokenFile)) {
|
||||
unlink($this->aTokenFile);
|
||||
}
|
||||
}
|
||||
$err = property_exists($decoded, 'error')? ' ' . $decoded->error : '';
|
||||
$err .= property_exists($decoded, 'error_description')? ' ' . $decoded->error_description : '';
|
||||
throw new \Exception($err? $err : elFinder::ERROR_REAUTH_REQUIRE);
|
||||
}
|
||||
|
||||
$token = (object)array(
|
||||
'expires' => time() + $decoded->expires_in - 30,
|
||||
'initialToken' => $initialToken,
|
||||
'data' => $decoded,
|
||||
);
|
||||
|
||||
$this->session->set('OneDriveTokens', $token);
|
||||
$this->options['accessToken'] = json_encode($token);
|
||||
$this->token = $token;
|
||||
$json = json_encode($token);
|
||||
|
||||
if (!empty($this->options['netkey'])) {
|
||||
elFinder::$instance->updateNetVolumeOption($this->options['netkey'], 'accessToken', $this->options['accessToken']);
|
||||
if (!empty($decoded->refresh_token)) {
|
||||
if (empty($this->options['netkey']) && $this->aTokenFile) {
|
||||
file_put_contents($this->aTokenFile, json_encode($token));
|
||||
$this->options['accessToken'] = $json;
|
||||
} else if (!empty($this->options['netkey'])) {
|
||||
// OAuth2 refresh token can be used only once,
|
||||
// so update it if it is the same as the token file
|
||||
$aTokenFile = $this->_od_getATokenFile();
|
||||
if ($aTokenFile && is_file($aTokenFile)) {
|
||||
if ($_token = json_decode(file_get_contents($aTokenFile))) {
|
||||
if ($_token->data->refresh_token === $refresh_token) {
|
||||
file_put_contents($aTokenFile, $json);
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->options['accessToken'] = $json;
|
||||
// update session value
|
||||
elFinder::$instance->updateNetVolumeOption($this->options['netkey'], 'accessToken', $this->options['accessToken']);
|
||||
$this->session->set('OneDriveTokens', $token);
|
||||
} else {
|
||||
throw new \Exception(elFinder::ERROR_CREATING_TEMP_DIR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -336,8 +360,7 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
|
|||
if ($contents) {
|
||||
$res = elFinder::curlExec($curl);
|
||||
} else {
|
||||
$result = json_decode(curl_exec($curl));
|
||||
curl_close($curl);
|
||||
$result = json_decode(elFinder::curlExec($curl));
|
||||
if (isset($result->value)) {
|
||||
$res = $result->value;
|
||||
unset($result->value);
|
||||
|
@ -524,8 +547,7 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
|
|||
CURLOPT_POST => true,
|
||||
CURLOPT_POSTFIELDS => '{}',
|
||||
));
|
||||
$sess = json_decode(curl_exec($curl));
|
||||
curl_close($curl);
|
||||
$sess = json_decode(elFinder::curlExec($curl));
|
||||
|
||||
if ($sess) {
|
||||
if (isset($sess->error)) {
|
||||
|
@ -543,7 +565,8 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
|
|||
elFinder::extendTimeLimit();
|
||||
$putFp = tmpfile();
|
||||
fwrite($putFp, $send);
|
||||
fseek($putFp, 0);
|
||||
rewind($putFp);
|
||||
$_size = strlen($send);
|
||||
$url = $sess->uploadUrl;
|
||||
$curl = curl_init();
|
||||
$options = array(
|
||||
|
@ -551,14 +574,14 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
|
|||
CURLOPT_PUT => true,
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_INFILE => $putFp,
|
||||
CURLOPT_INFILESIZE => $_size,
|
||||
CURLOPT_HTTPHEADER => array(
|
||||
'Content-Length: ' . strlen($send),
|
||||
'Content-Length: ' . $_size,
|
||||
'Content-Range: bytes ' . $range,
|
||||
),
|
||||
);
|
||||
curl_setopt_array($curl, $options);
|
||||
$sess = json_decode(curl_exec($curl));
|
||||
curl_close($curl);
|
||||
$sess = json_decode(elFinder::curlExec($curl));
|
||||
if ($sess) {
|
||||
if (isset($sess->error)) {
|
||||
throw new Exception($sess->error->message);
|
||||
|
@ -635,6 +658,39 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
|
|||
return $contents;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get AccessToken file path
|
||||
*
|
||||
* @return string ( description_of_the_return_value )
|
||||
*/
|
||||
protected function _od_getATokenFile()
|
||||
{
|
||||
$tmp = $aTokenFile = '';
|
||||
if (!empty($this->token->data->refresh_token)) {
|
||||
if (!$this->tmp) {
|
||||
$tmp = elFinder::getStaticVar('commonTempPath');
|
||||
if (!$tmp) {
|
||||
$tmp = $this->getTempPath();
|
||||
}
|
||||
$this->tmp = $tmp;
|
||||
}
|
||||
if ($tmp) {
|
||||
$aTokenFile = $tmp . DIRECTORY_SEPARATOR . $this->_od_getInitialToken() . '.otoken';
|
||||
}
|
||||
}
|
||||
return $aTokenFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Initial Token (MD5 hash)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function _od_getInitialToken()
|
||||
{
|
||||
return (empty($this->token->initialToken)? md5($this->options['client_id'] . (!empty($this->token->data->refresh_token)? $this->token->data->refresh_token : $this->token->data->access_token)) : $this->token->initialToken);
|
||||
}
|
||||
|
||||
/*********************************************************************/
|
||||
/* OVERRIDE FUNCTIONS */
|
||||
/*********************************************************************/
|
||||
|
@ -669,24 +725,52 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
|
|||
$this->session->set('nodeId', $_id);
|
||||
}
|
||||
|
||||
if (!empty($options['tmpPath'])) {
|
||||
if ((is_dir($options['tmpPath']) || mkdir($this->options['tmpPath'])) && is_writable($options['tmpPath'])) {
|
||||
$this->tmp = $options['tmpPath'];
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
if (empty($options['client_id']) || empty($options['client_secret'])) {
|
||||
return array('exit' => true, 'body' => '{msg:errNetMountNoDriver}');
|
||||
}
|
||||
|
||||
if (isset($_GET['code'])) {
|
||||
$itpCare = isset($options['code']);
|
||||
$code = $itpCare? $options['code'] : (isset($_GET['code'])? $_GET['code'] : '');
|
||||
if ($code) {
|
||||
try {
|
||||
// Obtain the token using the code received by the OneDrive API
|
||||
$this->session->set('OneDriveTokens',
|
||||
$this->_od_obtainAccessToken($options['client_id'], $options['client_secret'], $_GET['code']));
|
||||
if (!empty($options['id'])) {
|
||||
// Obtain the token using the code received by the OneDrive API
|
||||
$this->session->set('OneDriveTokens',
|
||||
$this->_od_obtainAccessToken($options['client_id'], $options['client_secret'], $code, $options['id']));
|
||||
|
||||
$out = array(
|
||||
'node' => $options['id'],
|
||||
'json' => '{"protocol": "onedrive", "mode": "done", "reset": 1}',
|
||||
'bind' => 'netmount',
|
||||
);
|
||||
|
||||
return array('exit' => 'callback', 'out' => $out);
|
||||
$out = array(
|
||||
'node' => $options['id'],
|
||||
'json' => '{"protocol": "onedrive", "mode": "done", "reset": 1}',
|
||||
'bind' => 'netmount',
|
||||
);
|
||||
} else {
|
||||
$nodeid = ($_GET['host'] === '1')? 'elfinder' : $_GET['host'];
|
||||
$out = array(
|
||||
'node' => $nodeid,
|
||||
'json' => json_encode(array(
|
||||
'protocol' => 'onedrive',
|
||||
'host' => $nodeid,
|
||||
'mode' => 'redirect',
|
||||
'options' => array(
|
||||
'id' => $nodeid,
|
||||
'code'=> $code
|
||||
)
|
||||
)),
|
||||
'bind' => 'netmount'
|
||||
);
|
||||
}
|
||||
if (!$itpCare) {
|
||||
return array('exit' => 'callback', 'out' => $out);
|
||||
} else {
|
||||
return array('exit' => true, 'body' => $out['json']);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
$out = array(
|
||||
'node' => $options['id'],
|
||||
|
@ -733,20 +817,6 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
|
|||
}
|
||||
|
||||
if ($result === false) {
|
||||
$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 (empty($options['url'])) {
|
||||
$options['url'] = elFinder::getConnectorUrl();
|
||||
}
|
||||
$callback = $options['url']
|
||||
. '?cmd=netmount&protocol=onedrive&host=onedrive.com&user=init&pass=return&node=' . $options['id'] . $cdata;
|
||||
|
||||
try {
|
||||
$this->session->set('OneDriveTokens', (object)array('token' => null));
|
||||
|
||||
|
@ -756,22 +826,21 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
|
|||
$offline = ' offline_access';
|
||||
}
|
||||
|
||||
$redirect_uri = $options['url'] . '/netmount/onedrive/1';
|
||||
$redirect_uri = elFinder::getConnectorUrl() . '/netmount/onedrive/' . ($options['id'] === 'elfinder'? '1' : $options['id']);
|
||||
$url = self::AUTH_URL
|
||||
. '?client_id=' . urlencode($options['client_id'])
|
||||
. '&scope=' . urlencode('files.readwrite.all' . $offline)
|
||||
. '&response_type=code'
|
||||
. '&redirect_uri=' . urlencode($redirect_uri);
|
||||
|
||||
$url .= '&oauth_callback=' . rawurlencode($callback);
|
||||
} catch (Exception $e) {
|
||||
return array('exit' => true, 'body' => '{msg:errAccess}');
|
||||
}
|
||||
|
||||
$html = '<input id="elf-volumedriver-onedrive-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 = '<input id="elf-volumedriver-onedrive-host-btn" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" value="{msg:btnApprove}" type="button">';
|
||||
$html .= '<script>
|
||||
$("#' . $options['id'] . '").elfinder("instance").trigger("netmount", {protocol: "onedrive", mode: "makebtn"});
|
||||
</script>';
|
||||
$("#' . $options['id'] . '").elfinder("instance").trigger("netmount", {protocol: "onedrive", mode: "makebtn", url: "' . $url . '"});
|
||||
</script>';
|
||||
|
||||
return array('exit' => true, 'body' => $html);
|
||||
} else {
|
||||
|
@ -792,11 +861,12 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
|
|||
$folders = json_encode($folders);
|
||||
|
||||
$expires = empty($this->token->data->refresh_token) ? (int)$this->token->expires : 0;
|
||||
$json = '{"protocol": "onedrive", "mode": "done", "folders": ' . $folders . ', "expires": ' . $expires . '}';
|
||||
$mnt2res = empty($this->token->data->refresh_token) ? '' : ', "mnt2res": 1';
|
||||
$json = '{"protocol": "onedrive", "mode": "done", "folders": ' . $folders . ', "expires": ' . $expires . $mnt2res .'}';
|
||||
$html = 'OneDrive.com';
|
||||
$html .= '<script>
|
||||
$("#' . $options['id'] . '").elfinder("instance").trigger("netmount", ' . $json . ');
|
||||
</script>';
|
||||
$("#' . $options['id'] . '").elfinder("instance").trigger("netmount", ' . $json . ');
|
||||
</script>';
|
||||
|
||||
return array('exit' => true, 'body' => $html);
|
||||
}
|
||||
|
@ -807,7 +877,11 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
|
|||
|
||||
if ($_aToken = $this->session->get('OneDriveTokens')) {
|
||||
$options['accessToken'] = json_encode($_aToken);
|
||||
if ($this->options['path'] === 'root' || !$this->options['path']) {
|
||||
$this->options['path'] = '/';
|
||||
}
|
||||
} else {
|
||||
$this->session->remove('OneDriveTokens');
|
||||
$this->setError(elFinder::ERROR_NETMOUNT, $options['host'], implode(' ', $this->error()));
|
||||
|
||||
return array('exit' => true, 'error' => $this->error());
|
||||
|
@ -829,7 +903,7 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
|
|||
*/
|
||||
public function netunmount($netVolumes, $key)
|
||||
{
|
||||
if ($tmbs = glob(rtrim($this->options['tmbPath'], '\\/') . DIRECTORY_SEPARATOR . $this->tmbPrefix . '*.png')) {
|
||||
if (!$this->options['useApiThumbnail'] && ($tmbs = glob(rtrim($this->options['tmbPath'], '\\/') . DIRECTORY_SEPARATOR . $this->tmbPrefix . '*.png'))) {
|
||||
foreach ($tmbs as $file) {
|
||||
unlink($file);
|
||||
}
|
||||
|
@ -846,7 +920,7 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
|
|||
public function debug()
|
||||
{
|
||||
$res = parent::debug();
|
||||
if (!empty($this->options['accessToken'])) {
|
||||
if (!empty($this->options['netkey']) && !empty($this->options['accessToken'])) {
|
||||
$res['accessToken'] = $this->options['accessToken'];
|
||||
}
|
||||
|
||||
|
@ -872,24 +946,66 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
|
|||
return $this->setError('Required option `accessToken` is undefined.');
|
||||
}
|
||||
|
||||
try {
|
||||
$this->token = json_decode($this->options['accessToken']);
|
||||
$this->_od_refreshToken();
|
||||
} catch (Exception $e) {
|
||||
$this->token = null;
|
||||
$this->session->remove('OneDriveTokens');
|
||||
|
||||
return $this->setError($e->getMessage());
|
||||
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'];
|
||||
}
|
||||
}
|
||||
|
||||
$this->expires = empty($this->token->data->refresh_token) ? (int)$this->token->expires : 0;
|
||||
$error = false;
|
||||
try {
|
||||
$this->token = json_decode($this->options['accessToken']);
|
||||
if (!is_object($this->token)) {
|
||||
throw new Exception('Required option `accessToken` is invalid JSON.');
|
||||
}
|
||||
|
||||
if (empty($options['netkey'])) {
|
||||
// make net mount key
|
||||
$_tokenKey = isset($this->token->data->refresh_token) ? $this->token->data->refresh_token : $this->token->data->access_token;
|
||||
$this->netMountKey = md5(implode('-', array('box', $this->options['path'], $_tokenKey)));
|
||||
} else {
|
||||
$this->netMountKey = $options['netkey'];
|
||||
if (empty($this->options['netkey'])) {
|
||||
$this->netMountKey = $this->_od_getInitialToken();
|
||||
} else {
|
||||
$this->netMountKey = $this->options['netkey'];
|
||||
}
|
||||
|
||||
if ($this->aTokenFile = $this->_od_getATokenFile()) {
|
||||
if (empty($this->options['netkey'])) {
|
||||
if ($this->aTokenFile) {
|
||||
if (is_file($this->aTokenFile)) {
|
||||
$this->token = json_decode(file_get_contents($this->aTokenFile));
|
||||
if (!is_object($this->token)) {
|
||||
unlink($this->aTokenFile);
|
||||
throw new Exception('Required option `accessToken` is invalid JSON.');
|
||||
}
|
||||
} else {
|
||||
file_put_contents($this->aTokenFile, $this->token);
|
||||
}
|
||||
}
|
||||
} else if (is_file($this->aTokenFile)) {
|
||||
// If the refresh token is the same as the permanent volume
|
||||
$this->token = json_decode(file_get_contents($this->aTokenFile));
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->needOnline) {
|
||||
$this->_od_refreshToken();
|
||||
|
||||
$this->expires = empty($this->token->data->refresh_token) ? (int)$this->token->expires : 0;
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
$this->token = null;
|
||||
$error = true;
|
||||
$this->setError($e->getMessage());
|
||||
}
|
||||
|
||||
if ($this->netMountKey) {
|
||||
$this->tmbPrefix = 'onedrive' . base_convert($this->netMountKey, 16, 32);
|
||||
}
|
||||
|
||||
if ($error) {
|
||||
if (empty($this->options['netkey']) && $this->tmbPrefix) {
|
||||
// for delete thumbnail
|
||||
$this->netunmount(null, null);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// normalize root path
|
||||
|
@ -899,26 +1015,21 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
|
|||
|
||||
$this->root = $this->options['path'] = $this->_normpath($this->options['path']);
|
||||
|
||||
$this->options['root'] == '' ? $this->options['root'] = 'OneDrive.com' : $this->options['root'];
|
||||
$this->options['root'] = ($this->options['root'] == '')? 'OneDrive.com' : $this->options['root'];
|
||||
|
||||
if (empty($this->options['alias'])) {
|
||||
$this->options['alias'] = ($this->options['path'] === '/') ? $this->options['root'] :
|
||||
$this->_od_query(basename($this->options['path']), $fetch_self = true)->name . '@OneDrive';
|
||||
}
|
||||
|
||||
$this->rootName = $this->options['alias'];
|
||||
|
||||
$this->tmbPrefix = 'onedrive' . base_convert($this->netMountKey, 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->needOnline) {
|
||||
$this->options['alias'] = ($this->options['path'] === '/') ? $this->options['root'] :
|
||||
$this->_od_query(basename($this->options['path']), $fetch_self = true)->name . '@OneDrive';
|
||||
if (!empty($this->options['netkey'])) {
|
||||
elFinder::$instance->updateNetVolumeOption($this->options['netkey'], 'alias', $this->options['alias']);
|
||||
}
|
||||
} else {
|
||||
$this->options['alias'] = $this->options['root'];
|
||||
}
|
||||
}
|
||||
|
||||
if (!$this->tmp && ($tmp = elFinder::getStaticVar('commonTempPath'))) {
|
||||
$this->tmp = $tmp;
|
||||
}
|
||||
$this->rootName = $this->options['alias'];
|
||||
|
||||
// This driver dose not support `syncChkAsTs`
|
||||
$this->options['syncChkAsTs'] = false;
|
||||
|
@ -1234,8 +1345,7 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
|
|||
CURLOPT_POSTFIELDS => json_encode($data),
|
||||
));
|
||||
|
||||
$result = curl_exec($curl);
|
||||
curl_close($curl);
|
||||
$result = elFinder::curlExec($curl);
|
||||
if ($result) {
|
||||
$result = json_decode($result);
|
||||
if (isset($result->link)) {
|
||||
|
@ -1467,7 +1577,7 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
|
|||
}
|
||||
$raw = $this->_od_query($itemId, true, false, $options);
|
||||
|
||||
if ($raw && $img = $raw->image) {
|
||||
if ($raw && property_exists($raw, 'image') && $img = $raw->image) {
|
||||
if (isset($img->width) && isset($img->height)) {
|
||||
$ret = array('dim' => $img->width . 'x' . $img->height);
|
||||
if ($tmbSize) {
|
||||
|
@ -1536,6 +1646,16 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
|
|||
'headers' => array('Authorization: Bearer ' . $this->token->data->access_token),
|
||||
);
|
||||
|
||||
// to support range request
|
||||
if (func_num_args() > 2) {
|
||||
$opts = func_get_arg(2);
|
||||
} else {
|
||||
$opts = array();
|
||||
}
|
||||
if (!empty($opts['httpheaders'])) {
|
||||
$data['headers'] = array_merge($opts['httpheaders'], $data['headers']);
|
||||
}
|
||||
|
||||
return elFinder::getStreamByUrl($data);
|
||||
}
|
||||
|
||||
|
@ -1552,7 +1672,7 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
|
|||
**/
|
||||
protected function _fclose($fp, $path = '')
|
||||
{
|
||||
fclose($fp);
|
||||
is_resource($fp) && fclose($fp);
|
||||
if ($path) {
|
||||
unlink($this->getTempFile($path));
|
||||
}
|
||||
|
@ -1592,8 +1712,7 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
|
|||
));
|
||||
|
||||
//create the Folder in the Parent
|
||||
$result = curl_exec($curl);
|
||||
curl_close($curl);
|
||||
$result = elFinder::curlExec($curl);
|
||||
$folder = json_decode($result);
|
||||
|
||||
return $this->_joinPath($path, $folder->id);
|
||||
|
@ -1671,8 +1790,7 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
|
|||
),
|
||||
CURLOPT_POSTFIELDS => json_encode($data),
|
||||
));
|
||||
$result = curl_exec($curl);
|
||||
curl_close($curl);
|
||||
$result = elFinder::curlExec($curl);
|
||||
|
||||
$res = new stdClass();
|
||||
if (preg_match('/Location: (.+)/', $result, $m)) {
|
||||
|
@ -1686,8 +1804,7 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
|
|||
'Content-Type: application/json',
|
||||
),
|
||||
));
|
||||
$res = json_decode(curl_exec($curl));
|
||||
curl_close($curl);
|
||||
$res = json_decode(elFinder::curlExec($curl));
|
||||
if (isset($res->status)) {
|
||||
if ($res->status === 'completed' || $res->status === 'failed') {
|
||||
break;
|
||||
|
@ -1748,8 +1865,7 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
|
|||
CURLOPT_POSTFIELDS => json_encode($data),
|
||||
));
|
||||
|
||||
$result = json_decode(curl_exec($curl));
|
||||
curl_close($curl);
|
||||
$result = json_decode(elFinder::curlExec($curl));
|
||||
if ($result && isset($result->id)) {
|
||||
return $targetDir . '/' . $result->id;
|
||||
} else {
|
||||
|
@ -1784,8 +1900,7 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
|
|||
));
|
||||
|
||||
//unlink or delete File or Folder in the Parent
|
||||
$result = curl_exec($curl);
|
||||
curl_close($curl);
|
||||
$result = elFinder::curlExec($curl);
|
||||
} catch (Exception $e) {
|
||||
return $this->setError('OneDrive error: ' . $e->getMessage());
|
||||
}
|
||||
|
@ -1851,6 +1966,16 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
|
|||
}
|
||||
|
||||
try {
|
||||
// for unseekable file pointer
|
||||
if (!elFinder::isSeekableStream($fp)) {
|
||||
if ($tfp = tmpfile()) {
|
||||
if (stream_copy_to_stream($fp, $tfp, $size? $size : -1) !== false) {
|
||||
rewind($tfp);
|
||||
$fp = $tfp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Create or Update a file
|
||||
if ($itemId === '') {
|
||||
$url = self::API_URL . $parentId . ':/' . rawurlencode($name) . ':/content';
|
||||
|
@ -1872,8 +1997,7 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
|
|||
curl_setopt_array($curl, $options);
|
||||
|
||||
//create or update File in the Target
|
||||
$file = json_decode(curl_exec($curl));
|
||||
curl_close($curl);
|
||||
$file = json_decode(elFinder::curlExec($curl));
|
||||
|
||||
return $this->_joinPath($parent, $file->id);
|
||||
} catch (Exception $e) {
|
||||
|
|
838
include/thirdparty/elFinder/php/elFinderVolumeSFTPphpseclib.class.php
vendored
Normal file
838
include/thirdparty/elFinder/php/elFinderVolumeSFTPphpseclib.class.php
vendored
Normal file
|
@ -0,0 +1,838 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Simple elFinder driver for SFTP using phpseclib 1
|
||||
*
|
||||
* @author Dmitry (dio) Levashov
|
||||
* @author Cem (discofever), sitecode
|
||||
* @reference http://phpseclib.sourceforge.net/sftp/2.0/examples.html
|
||||
**/
|
||||
class elFinderVolumeSFTPphpseclib extends elFinderVolumeFTP {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Extend options with required fields
|
||||
*
|
||||
* @author Dmitry (dio) Levashov
|
||||
* @author Cem (DiscoFever)
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$opts = array(
|
||||
'host' => 'localhost',
|
||||
'user' => '',
|
||||
'pass' => '',
|
||||
'port' => 22,
|
||||
'path' => '/',
|
||||
'timeout' => 20,
|
||||
'owner' => true,
|
||||
'tmbPath' => '',
|
||||
'tmpPath' => '',
|
||||
'separator' => '/',
|
||||
'phpseclibDir' => '../phpseclib/',
|
||||
'connectCallback' => null, //provide your own already instantiated phpseclib $Sftp object returned by this callback
|
||||
//'connectCallback'=> function($options) {
|
||||
// //load and instantiate phpseclib $sftp
|
||||
// return $sftp;
|
||||
// },
|
||||
'checkSubfolders' => -1,
|
||||
'dirMode' => 0755,
|
||||
'fileMode' => 0644,
|
||||
'rootCssClass' => 'elfinder-navbar-root-ftp',
|
||||
);
|
||||
$this->options = array_merge($this->options, $opts);
|
||||
$this->options['mimeDetect'] = 'internal';
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare
|
||||
* Call from elFinder::netmout() before volume->mount()
|
||||
*
|
||||
* @param $options
|
||||
*
|
||||
* @return array volume root options
|
||||
* @author Naoki Sawada
|
||||
*/
|
||||
public function netmountPrepare($options)
|
||||
{
|
||||
$options['statOwner'] = true;
|
||||
$options['allowChmodReadOnly'] = true;
|
||||
$options['acceptedName'] = '#^[^/\\?*:|"<>]*[^./\\?*:|"<>]$#';
|
||||
return $options;
|
||||
}
|
||||
|
||||
/*********************************************************************/
|
||||
/* INIT AND CONFIGURE */
|
||||
/*********************************************************************/
|
||||
|
||||
/**
|
||||
* Prepare SFTP connection
|
||||
* Connect to remote server and check if credentials are correct, if so, store the connection
|
||||
*
|
||||
* @return bool
|
||||
* @author Dmitry (dio) Levashov
|
||||
* @author Cem (DiscoFever)
|
||||
**/
|
||||
protected function init()
|
||||
{
|
||||
if (!$this->options['connectCallback']) {
|
||||
if (!$this->options['host']
|
||||
|| !$this->options['port']) {
|
||||
return $this->setError('Required options undefined.');
|
||||
}
|
||||
|
||||
if (!$this->options['path']) {
|
||||
$this->options['path'] = '/';
|
||||
}
|
||||
|
||||
// make net mount key
|
||||
$this->netMountKey = md5(join('-', array('sftpphpseclib', $this->options['host'], $this->options['port'], $this->options['path'], $this->options['user'])));
|
||||
|
||||
set_include_path(get_include_path() . PATH_SEPARATOR . getcwd().'/'.$this->options['phpseclibDir']);
|
||||
include_once('Net/SFTP.php');
|
||||
|
||||
if (!class_exists('Net_SFTP')) {
|
||||
return $this->setError('SFTP extension not loaded. Install phpseclib version 1: http://phpseclib.sourceforge.net/ Set option "phpseclibDir" accordingly.');
|
||||
}
|
||||
|
||||
// remove protocol from host
|
||||
$scheme = parse_url($this->options['host'], PHP_URL_SCHEME);
|
||||
|
||||
if ($scheme) {
|
||||
$this->options['host'] = substr($this->options['host'], strlen($scheme) + 3);
|
||||
}
|
||||
} else {
|
||||
// make net mount key
|
||||
$this->netMountKey = md5(join('-', array('sftpphpseclib', $this->options['path'])));
|
||||
}
|
||||
|
||||
// normalize root path
|
||||
$this->root = $this->options['path'] = $this->_normpath($this->options['path']);
|
||||
|
||||
if (empty($this->options['alias'])) {
|
||||
$this->options['alias'] = $this->options['user'] . '@' . $this->options['host'];
|
||||
if (!empty($this->options['netkey'])) {
|
||||
elFinder::$instance->updateNetVolumeOption($this->options['netkey'], 'alias', $this->options['alias']);
|
||||
}
|
||||
}
|
||||
|
||||
$this->rootName = $this->options['alias'];
|
||||
$this->options['separator'] = '/';
|
||||
|
||||
if (is_null($this->options['syncChkAsTs'])) {
|
||||
$this->options['syncChkAsTs'] = true;
|
||||
}
|
||||
|
||||
return $this->needOnline? $this->connect() : true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Configure after successfull mount.
|
||||
*
|
||||
* @return void
|
||||
* @throws elFinderAbortException
|
||||
* @author Dmitry (dio) Levashov
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
parent::configure();
|
||||
|
||||
if (!$this->tmp) {
|
||||
$this->disabled[] = 'mkfile';
|
||||
$this->disabled[] = 'paste';
|
||||
$this->disabled[] = 'upload';
|
||||
$this->disabled[] = 'edit';
|
||||
//$this->disabled[] = 'archive';
|
||||
//$this->disabled[] = 'extract';
|
||||
}
|
||||
|
||||
$this->disabled[] = 'archive';
|
||||
$this->disabled[] = 'extract';
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to sftp server
|
||||
*
|
||||
* @return bool
|
||||
* @author sitecode
|
||||
**/
|
||||
protected function connect()
|
||||
{
|
||||
//use ca
|
||||
if ($this->options['connectCallback']) {
|
||||
$this->connect = $this->options['connectCallback']($this->options);
|
||||
if (!$this->connect || !$this->connect->isConnected()) {
|
||||
return $this->setError('Unable to connect successfully');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
try{
|
||||
$host = $this->options['host'] . ($this->options['port'] != 22 ? ':' . $this->options['port'] : '');
|
||||
$this->connect = new Net_SFTP($host);
|
||||
//TODO check fingerprint before login, fail if no match to last time
|
||||
if (!$this->connect->login($this->options['user'], $this->options['pass'])) {
|
||||
return $this->setError('Unable to connect to SFTP server ' . $host);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
return $this->setError('Error while connecting to SFTP server ' . $host . ': ' . $e->getMessage());
|
||||
}
|
||||
|
||||
if (!$this->connect->chdir($this->root)
|
||||
/*|| $this->root != $this->connect->pwd()*/) {
|
||||
//$this->umount();
|
||||
return $this->setError('Unable to open root folder.');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call rawlist
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function ftpRawList($path)
|
||||
{
|
||||
return $this->connect->rawlist($path ?: '.') ?: [];
|
||||
/*
|
||||
$raw = $this->connect->rawlist($path ?: '.') ?: [];
|
||||
$raw = array_map(function($key, $value) {
|
||||
$value['name'] = $key;
|
||||
return $value;
|
||||
}, array_keys($raw), $raw);
|
||||
return $raw;
|
||||
*/
|
||||
}
|
||||
|
||||
/*********************************************************************/
|
||||
/* FS API */
|
||||
/*********************************************************************/
|
||||
|
||||
/**
|
||||
* Close opened connection
|
||||
*
|
||||
* @return void
|
||||
* @author Dmitry (dio) Levashov
|
||||
**/
|
||||
public function umount()
|
||||
{
|
||||
$this->connect && $this->connect->disconnect();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse line from rawlist() output and return file stat (array)
|
||||
*
|
||||
* @param string $raw line from rawlist() output
|
||||
* @param $base
|
||||
* @param bool $nameOnly
|
||||
*
|
||||
* @return array
|
||||
* @author Dmitry Levashov
|
||||
*/
|
||||
protected function parseRaw($raw, $base, $nameOnly = false)
|
||||
{
|
||||
$info = $raw;
|
||||
$stat = array();
|
||||
|
||||
if ($info['filename'] == '.' || $info['filename'] == '..') {
|
||||
return false;
|
||||
}
|
||||
|
||||
$name = $info['filename'];
|
||||
|
||||
if (preg_match('|(.+)\-\>(.+)|', $name, $m)) {
|
||||
$name = trim($m[1]);
|
||||
// check recursive processing
|
||||
if ($this->cacheDirTarget && $this->_joinPath($base, $name) !== $this->cacheDirTarget) {
|
||||
return array();
|
||||
}
|
||||
if (!$nameOnly) {
|
||||
$target = trim($m[2]);
|
||||
if (substr($target, 0, 1) !== $this->separator) {
|
||||
$target = $this->getFullPath($target, $base);
|
||||
}
|
||||
$target = $this->_normpath($target);
|
||||
$stat['name'] = $name;
|
||||
$stat['target'] = $target;
|
||||
return $stat;
|
||||
}
|
||||
}
|
||||
|
||||
if ($nameOnly) {
|
||||
return array('name' => $name);
|
||||
}
|
||||
|
||||
$stat['ts'] = $info['mtime'];
|
||||
|
||||
if ($this->options['statOwner']) {
|
||||
$stat['owner'] = $info['uid'];
|
||||
$stat['group'] = $info['gid'];
|
||||
$stat['perm'] = $info['permissions'];
|
||||
$stat['isowner'] = isset($stat['owner']) ? ($this->options['owner'] ? true : ($stat['owner'] == $this->options['user'])) : true;
|
||||
}
|
||||
|
||||
$owner_computed = isset($stat['isowner']) ? $stat['isowner'] : $this->options['owner'];
|
||||
$perm = $this->parsePermissions($info['permissions'], $owner_computed);
|
||||
$stat['name'] = $name;
|
||||
$stat['mime'] = $info['type'] == NET_SFTP_TYPE_DIRECTORY ? 'directory' : $this->mimetype($stat['name'], true);
|
||||
$stat['size'] = $stat['mime'] == 'directory' ? 0 : $info['size'];
|
||||
$stat['read'] = $perm['read'];
|
||||
$stat['write'] = $perm['write'];
|
||||
|
||||
return $stat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse permissions string. Return array(read => true/false, write => true/false)
|
||||
*
|
||||
* @param int $perm
|
||||
* The isowner parameter is computed by the caller.
|
||||
* If the owner parameter in the options is true, the user is the actual owner of all objects even if the user used in the ftp Login
|
||||
* is different from the file owner id.
|
||||
* If the owner parameter is false to understand if the user is the file owner we compare the ftp user with the file owner id.
|
||||
* @param Boolean $isowner . Tell if the current user is the owner of the object.
|
||||
*
|
||||
* @return array
|
||||
* @author Dmitry (dio) Levashov
|
||||
* @author sitecode
|
||||
*/
|
||||
protected function parsePermissions($permissions, $isowner = true)
|
||||
{
|
||||
$permissions = decoct($permissions);
|
||||
$perm = $isowner ? decbin($permissions[-3]) : decbin($permissions[-1]);
|
||||
|
||||
return array(
|
||||
'read' => $perm[-3],
|
||||
'write' => $perm[-2]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cache dir contents
|
||||
*
|
||||
* @param string $path dir path
|
||||
*
|
||||
* @return void
|
||||
* @author Dmitry Levashov, sitecode
|
||||
**/
|
||||
protected function cacheDir($path)
|
||||
{
|
||||
$this->dirsCache[$path] = array();
|
||||
$hasDir = false;
|
||||
|
||||
$list = array();
|
||||
$encPath = $this->convEncIn($path);
|
||||
foreach ($this->ftpRawList($encPath) as $raw) {
|
||||
if (($stat = $this->parseRaw($raw, $encPath))) {
|
||||
$list[] = $stat;
|
||||
}
|
||||
}
|
||||
$list = $this->convEncOut($list);
|
||||
$prefix = ($path === $this->separator) ? $this->separator : $path . $this->separator;
|
||||
$targets = array();
|
||||
foreach ($list as $stat) {
|
||||
$p = $prefix . $stat['name'];
|
||||
if (isset($stat['target'])) {
|
||||
// stat later
|
||||
$targets[$stat['name']] = $stat['target'];
|
||||
} else {
|
||||
$stat = $this->updateCache($p, $stat);
|
||||
if (empty($stat['hidden'])) {
|
||||
if (!$hasDir && $stat['mime'] === 'directory') {
|
||||
$hasDir = true;
|
||||
}
|
||||
$this->dirsCache[$path][] = $p;
|
||||
}
|
||||
}
|
||||
}
|
||||
// stat link targets
|
||||
foreach ($targets as $name => $target) {
|
||||
$stat = array();
|
||||
$stat['name'] = $name;
|
||||
$p = $prefix . $name;
|
||||
$cacheDirTarget = $this->cacheDirTarget;
|
||||
$this->cacheDirTarget = $this->convEncIn($target, true);
|
||||
if ($tstat = $this->stat($target)) {
|
||||
$stat['size'] = $tstat['size'];
|
||||
$stat['alias'] = $target;
|
||||
$stat['thash'] = $tstat['hash'];
|
||||
$stat['mime'] = $tstat['mime'];
|
||||
$stat['read'] = $tstat['read'];
|
||||
$stat['write'] = $tstat['write'];
|
||||
|
||||
if (isset($tstat['ts'])) {
|
||||
$stat['ts'] = $tstat['ts'];
|
||||
}
|
||||
if (isset($tstat['owner'])) {
|
||||
$stat['owner'] = $tstat['owner'];
|
||||
}
|
||||
if (isset($tstat['group'])) {
|
||||
$stat['group'] = $tstat['group'];
|
||||
}
|
||||
if (isset($tstat['perm'])) {
|
||||
$stat['perm'] = $tstat['perm'];
|
||||
}
|
||||
if (isset($tstat['isowner'])) {
|
||||
$stat['isowner'] = $tstat['isowner'];
|
||||
}
|
||||
} else {
|
||||
|
||||
$stat['mime'] = 'symlink-broken';
|
||||
$stat['read'] = false;
|
||||
$stat['write'] = false;
|
||||
$stat['size'] = 0;
|
||||
|
||||
}
|
||||
$this->cacheDirTarget = $cacheDirTarget;
|
||||
$stat = $this->updateCache($p, $stat);
|
||||
if (empty($stat['hidden'])) {
|
||||
if (!$hasDir && $stat['mime'] === 'directory') {
|
||||
$hasDir = true;
|
||||
}
|
||||
$this->dirsCache[$path][] = $p;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($this->sessionCache['subdirs'])) {
|
||||
$this->sessionCache['subdirs'][$path] = $hasDir;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************** 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)
|
||||
{
|
||||
$outPath = $this->convEncOut($path);
|
||||
if (isset($this->cache[$outPath])) {
|
||||
return $this->convEncIn($this->cache[$outPath]);
|
||||
} else {
|
||||
$this->convEncIn();
|
||||
}
|
||||
if ($path === $this->root) {
|
||||
$res = array(
|
||||
'name' => $this->root,
|
||||
'mime' => 'directory',
|
||||
'dirs' => -1
|
||||
);
|
||||
if ($this->needOnline && (($this->ARGS['cmd'] === 'open' && $this->ARGS['target'] === $this->encode($this->root)) || $this->isMyReload())) {
|
||||
$check = array(
|
||||
'ts' => true,
|
||||
'dirs' => true,
|
||||
);
|
||||
$ts = 0;
|
||||
foreach ($this->ftpRawList($path) as $str) {
|
||||
$info = preg_split('/\s+/', $str, 9);
|
||||
if ($info[8] === '.') {
|
||||
$info[8] = 'root';
|
||||
if ($stat = $this->parseRaw(join(' ', $info), $path)) {
|
||||
unset($stat['name']);
|
||||
$res = array_merge($res, $stat);
|
||||
if ($res['ts']) {
|
||||
$ts = 0;
|
||||
unset($check['ts']);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($check && ($stat = $this->parseRaw($str, $path))) {
|
||||
if (isset($stat['ts']) && !empty($stat['ts'])) {
|
||||
$ts = max($ts, $stat['ts']);
|
||||
}
|
||||
if (isset($stat['dirs']) && $stat['mime'] === 'directory') {
|
||||
$res['dirs'] = 1;
|
||||
unset($stat['dirs']);
|
||||
}
|
||||
if (!$check) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($ts) {
|
||||
$res['ts'] = $ts;
|
||||
}
|
||||
$this->cache[$outPath] = $res;
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
$pPath = $this->_dirname($path);
|
||||
if ($this->_inPath($pPath, $this->root)) {
|
||||
$outPPpath = $this->convEncOut($pPath);
|
||||
if (!isset($this->dirsCache[$outPPpath])) {
|
||||
$parentSubdirs = null;
|
||||
if (isset($this->sessionCache['subdirs']) && isset($this->sessionCache['subdirs'][$outPPpath])) {
|
||||
$parentSubdirs = $this->sessionCache['subdirs'][$outPPpath];
|
||||
}
|
||||
$this->cacheDir($outPPpath);
|
||||
if ($parentSubdirs) {
|
||||
$this->sessionCache['subdirs'][$outPPpath] = $parentSubdirs;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$stat = $this->convEncIn(isset($this->cache[$outPath]) ? $this->cache[$outPath] : array());
|
||||
if (!$this->mounted) {
|
||||
// dispose incomplete cache made by calling `stat` by 'startPath' option
|
||||
$this->cache = array();
|
||||
}
|
||||
|
||||
return $stat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if path is dir and has at least one childs directory
|
||||
*
|
||||
* @param string $path dir path
|
||||
*
|
||||
* @return bool
|
||||
* @author Dmitry (dio) Levashov, sitecode
|
||||
**/
|
||||
protected function _subdirs($path)
|
||||
{
|
||||
foreach ($this->ftpRawList($path) as $info) {
|
||||
$name = $info['filename'];
|
||||
if ($name && $name !== '.' && $name !== '..' && $info['type'] == NET_SFTP_TYPE_DIRECTORY) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/******************** file/dir content *********************/
|
||||
|
||||
/**
|
||||
* Open file and return file pointer
|
||||
*
|
||||
* @param string $path file path
|
||||
* @param string $mode
|
||||
*
|
||||
* @return false|resource
|
||||
* @throws elFinderAbortException
|
||||
* @internal param bool $write open file for writing
|
||||
* @author Dmitry (dio) Levashov
|
||||
*/
|
||||
protected function _fopen($path, $mode = 'rb')
|
||||
{
|
||||
if ($this->tmp) {
|
||||
$local = $this->getTempFile($path);
|
||||
$this->connect->get($path, $local);
|
||||
return @fopen($local, $mode);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close opened file
|
||||
*
|
||||
* @param resource $fp file pointer
|
||||
* @param string $path
|
||||
*
|
||||
* @return void
|
||||
* @author Dmitry (dio) Levashov
|
||||
*/
|
||||
protected function _fclose($fp, $path = '')
|
||||
{
|
||||
is_resource($fp) && 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->_joinPath($path, $this->_basename($name));
|
||||
if ($this->connect->mkdir($path) === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->options['dirMode'] && $this->connect->chmod($this->options['dirMode'], $path);
|
||||
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 sitecode
|
||||
**/
|
||||
protected function _mkfile($path, $name)
|
||||
{
|
||||
$path = $this->_joinPath($path, $this->_basename($name));
|
||||
return $this->connect->put($path, '') ? $path : false;
|
||||
/*
|
||||
if ($this->tmp) {
|
||||
$path = $this->_joinPath($path, $name);
|
||||
$local = $this->getTempFile();
|
||||
$res = touch($local) && $this->connect->put($path, $local, NET_SFTP_LOCAL_FILE);
|
||||
unlink($local);
|
||||
return $res ? $path : false;
|
||||
}
|
||||
|
||||
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, sitecode
|
||||
**/
|
||||
protected function _copy($source, $targetDir, $name)
|
||||
{
|
||||
$res = false;
|
||||
|
||||
$target = $this->_joinPath($targetDir, $this->_basename($name));
|
||||
if ($this->tmp) {
|
||||
$local = $this->getTempFile();
|
||||
|
||||
if ($this->connect->get($source, $local)
|
||||
&& $this->connect->put($target, $local, NET_SFTP_LOCAL_FILE)) {
|
||||
$res = true;
|
||||
}
|
||||
unlink($local);
|
||||
} else {
|
||||
//not memory efficient
|
||||
$res = $this->_filePutContents($target, $this->_getContents($source));
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move file into another parent dir.
|
||||
* Return new file path or false.
|
||||
*
|
||||
* @param string $source source file path
|
||||
* @param $targetDir
|
||||
* @param string $name file name
|
||||
*
|
||||
* @return bool|string
|
||||
* @internal param string $target target dir path
|
||||
* @author Dmitry (dio) Levashov
|
||||
*/
|
||||
protected function _move($source, $targetDir, $name)
|
||||
{
|
||||
$target = $this->_joinPath($targetDir, $this->_basename($name));
|
||||
return $this->connect->rename($source, $target) ? $target : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove file
|
||||
*
|
||||
* @param string $path file path
|
||||
*
|
||||
* @return bool
|
||||
* @author Dmitry (dio) Levashov
|
||||
**/
|
||||
protected function _unlink($path)
|
||||
{
|
||||
return $this->connect->delete($path, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove dir
|
||||
*
|
||||
* @param string $path dir path
|
||||
*
|
||||
* @return bool
|
||||
* @author Dmitry (dio) Levashov
|
||||
**/
|
||||
protected function _rmdir($path)
|
||||
{
|
||||
return $this->connect->delete($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, $dir, $name, $stat)
|
||||
{
|
||||
//TODO optionally encrypt $fp before uploading if mime is not already encrypted type
|
||||
$path = $this->_joinPath($dir, $this->_basename($name));
|
||||
return $this->connect->put($path, $fp)
|
||||
? $path
|
||||
: false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get file contents
|
||||
*
|
||||
* @param string $path file path
|
||||
*
|
||||
* @return string|false
|
||||
* @throws elFinderAbortException
|
||||
* @author Dmitry (dio) Levashov
|
||||
*/
|
||||
protected function _getContents($path)
|
||||
{
|
||||
return $this->connect->get($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
return $this->connect->put($path, $content);
|
||||
}
|
||||
|
||||
/**
|
||||
* chmod availability
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $mode
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function _chmod($path, $mode)
|
||||
{
|
||||
$modeOct = is_string($mode) ? octdec($mode) : octdec(sprintf("%04o", $mode));
|
||||
return $this->connect->chmod($modeOct, $path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract files from archive
|
||||
*
|
||||
* @param string $path archive path
|
||||
* @param array $arc archiver command and arguments (same as in $this->archivers)
|
||||
*
|
||||
* @return true
|
||||
* @throws elFinderAbortException
|
||||
* @author Dmitry (dio) Levashov,
|
||||
* @author Alexey Sukhotin
|
||||
*/
|
||||
protected function _extract($path, $arc)
|
||||
{
|
||||
return false; //TODO
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @throws elFinderAbortException
|
||||
* @author Dmitry (dio) Levashov,
|
||||
* @author Alexey Sukhotin
|
||||
*/
|
||||
protected function _archive($dir, $files, $name, $arc)
|
||||
{
|
||||
return false; //TODO
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an array of absolute remote SFTP paths of files and
|
||||
* folders in $remote_directory omitting symbolic links.
|
||||
*
|
||||
* @param $remote_directory string remote SFTP path to scan for file and folders recursively
|
||||
* @param $targets array Array of target item. `null` is to get all of items
|
||||
*
|
||||
* @return array of elements each of which is an array of two elements:
|
||||
* <ul>
|
||||
* <li>$item['path'] - absolute remote SFTP path</li>
|
||||
* <li>$item['type'] - either 'f' for file or 'd' for directory</li>
|
||||
* </ul>
|
||||
*/
|
||||
protected function ftp_scan_dir($remote_directory, $targets = null)
|
||||
{
|
||||
$buff = $this->ftpRawList($remote_directory);
|
||||
$items = array();
|
||||
if ($targets && is_array($targets)) {
|
||||
$targets = array_flip($targets);
|
||||
} else {
|
||||
$targets = false;
|
||||
}
|
||||
foreach ($buff as $info) {
|
||||
$name = $info['filename'];
|
||||
if ($name !== '.' && $name !== '..' && (!$targets || isset($targets[$name]))) {
|
||||
switch ($info['type']) {
|
||||
case NET_SFTP_TYPE_SYMLINK : //omit symbolic links
|
||||
case NET_SFTP_TYPE_DIRECTORY :
|
||||
$remote_file_path = $this->_joinPath($remote_directory, $name);
|
||||
$item = array();
|
||||
$item['path'] = $remote_file_path;
|
||||
$item['type'] = 'd'; // normal file
|
||||
$items[] = $item;
|
||||
$items = array_merge($items, $this->ftp_scan_dir($remote_file_path));
|
||||
break;
|
||||
default:
|
||||
$remote_file_path = $this->_joinPath($remote_directory, $name);
|
||||
$item = array();
|
||||
$item['path'] = $remote_file_path;
|
||||
$item['type'] = 'f'; // normal file
|
||||
$items[] = $item;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $items;
|
||||
}
|
||||
|
||||
} // END class
|
|
@ -84,6 +84,10 @@ class elFinderPluginAutoResize extends elFinderPlugin
|
|||
|
||||
public function onUpLoadPreSave(&$thash, &$name, $src, $elfinder, $volume)
|
||||
{
|
||||
if (!$src) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$opts = $this->getCurrentOpts($volume);
|
||||
|
||||
if (!$this->iaEnabled($opts, $elfinder)) {
|
||||
|
|
|
@ -69,6 +69,10 @@ class elFinderPluginAutoRotate extends elFinderPlugin
|
|||
|
||||
public function onUpLoadPreSave(&$thash, &$name, $src, $elfinder, $volume)
|
||||
{
|
||||
if (!$src) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$opts = $this->getCurrentOpts($volume);
|
||||
|
||||
if (!$this->iaEnabled($opts, $elfinder)) {
|
||||
|
@ -114,7 +118,10 @@ class elFinderPluginAutoRotate extends elFinderPlugin
|
|||
return false;
|
||||
}
|
||||
$degree = 0;
|
||||
$errlev =error_reporting();
|
||||
error_reporting($errlev ^ E_WARNING);
|
||||
$exif = exif_read_data($src);
|
||||
error_reporting($errlev);
|
||||
if ($exif && !empty($exif['Orientation'])) {
|
||||
switch ($exif['Orientation']) {
|
||||
case 8:
|
||||
|
@ -128,6 +135,9 @@ class elFinderPluginAutoRotate extends elFinderPlugin
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (!$degree) {
|
||||
return false;
|
||||
}
|
||||
$opts = array(
|
||||
'degree' => $degree,
|
||||
'jpgQuality' => $quality,
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
* 'upload.pre mkdir.pre mkfile.pre rename.pre archive.pre ls.pre' => array(
|
||||
* 'Plugin.Normalizer.cmdPreprocess'
|
||||
* ),
|
||||
* 'upload.presave' => array(
|
||||
* 'upload.presave paste.copyfrom' => array(
|
||||
* 'Plugin.Normalizer.onUpLoadPreSave'
|
||||
* )
|
||||
* ),
|
||||
|
@ -169,7 +169,11 @@ class elFinderPluginNormalizer extends elFinderPlugin
|
|||
$str = Normalizer::normalize($str, Normalizer::FORM_KC);
|
||||
} else {
|
||||
if (!class_exists('I18N_UnicodeNormalizer', false)) {
|
||||
include_once 'I18N/UnicodeNormalizer.php';
|
||||
if (is_readable('I18N/UnicodeNormalizer.php')) {
|
||||
include_once 'I18N/UnicodeNormalizer.php';
|
||||
} else {
|
||||
trigger_error('Plugin Normalizer\'s options "nfc" or "nfkc" require PHP class "Normalizer" or PEAR package "I18N_UnicodeNormalizer"', E_USER_WARNING);
|
||||
}
|
||||
}
|
||||
if (class_exists('I18N_UnicodeNormalizer', false)) {
|
||||
$normalizer = new I18N_UnicodeNormalizer();
|
||||
|
@ -182,7 +186,7 @@ class elFinderPluginNormalizer extends elFinderPlugin
|
|||
}
|
||||
if ($opts['umlauts']) {
|
||||
if (strpos($str = htmlentities($str, ENT_QUOTES, 'UTF-8'), '&') !== false) {
|
||||
$str = html_entity_decode(preg_replace('~&([a-z]{1,2})(?:acute|cedil|circ|grave|lig|orn|ring|slash|tilde|uml);~i', '$1', $str), ENT_QUOTES, 'utf-8');
|
||||
$str = html_entity_decode(preg_replace('~&([a-z]{1,2})(?:acute|caron|cedil|circ|grave|lig|orn|ring|slash|tilde|uml);~i', '$1', $str), ENT_QUOTES, 'utf-8');
|
||||
}
|
||||
}
|
||||
if ($opts['convmap'] && is_array($opts['convmap'])) {
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
* 'upload.pre mkdir.pre mkfile.pre rename.pre archive.pre ls.pre' => array(
|
||||
* 'Plugin.Sanitizer.cmdPreprocess'
|
||||
* ),
|
||||
* 'upload.presave' => array(
|
||||
* 'upload.presave paste.copyfrom' => array(
|
||||
* 'Plugin.Sanitizer.onUpLoadPreSave'
|
||||
* )
|
||||
* ),
|
||||
|
|
|
@ -100,6 +100,10 @@ class elFinderPluginWatermark extends elFinderPlugin
|
|||
|
||||
public function onUpLoadPreSave(&$thash, &$name, $src, $elfinder, $volume)
|
||||
{
|
||||
if (!$src) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$opts = $this->getCurrentOpts($volume);
|
||||
|
||||
if (!$this->iaEnabled($opts, $elfinder)) {
|
||||
|
@ -232,15 +236,16 @@ class elFinderPluginWatermark extends elFinderPlugin
|
|||
// check interlace
|
||||
$opts['interlace'] = ($opts['interlace'] & $imgTypes[$imageType]);
|
||||
|
||||
if (class_exists('Imagick', false)) {
|
||||
return $this->watermarkPrint_imagick($src, $watermark, $dest_x, $dest_y, $quality, $transparency, $watermarkImgInfo, $opts);
|
||||
} else {
|
||||
// Repeated use of Imagick::compositeImage() may cause PHP to hang, so disable it
|
||||
//if (class_exists('Imagick', false)) {
|
||||
// return $this->watermarkPrint_imagick($src, $watermark, $dest_x, $dest_y, $quality, $transparency, $watermarkImgInfo, $opts);
|
||||
//} else {
|
||||
elFinder::expandMemoryForGD(array($watermarkImgInfo, $srcImgInfo));
|
||||
return $this->watermarkPrint_gd($src, $watermark, $dest_x, $dest_y, $quality, $transparency, $watermarkImgInfo, $srcImgInfo, $opts);
|
||||
}
|
||||
//}
|
||||
}
|
||||
|
||||
private function watermarkPrint_imagick($src, $watermark, $dest_x, $dest_y, $quality, $transparency, $watermarkImgInfo, $opts)
|
||||
private function watermarkPrint_imagick($src, $watermarkSrc, $dest_x, $dest_y, $quality, $transparency, $watermarkImgInfo, $opts)
|
||||
{
|
||||
|
||||
try {
|
||||
|
@ -249,7 +254,7 @@ class elFinderPluginWatermark extends elFinderPlugin
|
|||
$img = new Imagick($src);
|
||||
|
||||
// Open the watermark
|
||||
$watermark = new Imagick($watermark);
|
||||
$watermark = new Imagick($watermarkSrc);
|
||||
|
||||
// zoom
|
||||
if ($opts['ratio']) {
|
||||
|
|
Loading…
Reference in a new issue