initial
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
order deny,allow
|
||||
deny from all
|
||||
@@ -0,0 +1,47 @@
|
||||
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(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_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');
|
||||
|
||||
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');
|
||||
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
define('ELFINDER_PHP_ROOT_PATH', dirname(__FILE__));
|
||||
|
||||
function elFinderAutoloader($name)
|
||||
{
|
||||
$map = array(
|
||||
'elFinder' => 'elFinder.class.php',
|
||||
'elFinderConnector' => 'elFinderConnector.class.php',
|
||||
'elFinderEditor' => 'editors/editor.php',
|
||||
'elFinderLibGdBmp' => 'libs/GdBmp.php',
|
||||
'elFinderPlugin' => 'elFinderPlugin.php',
|
||||
'elFinderPluginAutoResize' => 'plugins/AutoResize/plugin.php',
|
||||
'elFinderPluginAutoRotate' => 'plugins/AutoRotate/plugin.php',
|
||||
'elFinderPluginNormalizer' => 'plugins/Normalizer/plugin.php',
|
||||
'elFinderPluginSanitizer' => 'plugins/Sanitizer/plugin.php',
|
||||
'elFinderPluginWatermark' => 'plugins/Watermark/plugin.php',
|
||||
'elFinderSession' => 'elFinderSession.php',
|
||||
'elFinderSessionInterface' => 'elFinderSessionInterface.php',
|
||||
'elFinderVolumeDriver' => 'elFinderVolumeDriver.class.php',
|
||||
'elFinderVolumeDropbox2' => 'elFinderVolumeDropbox2.class.php',
|
||||
'elFinderVolumeFTP' => 'elFinderVolumeFTP.class.php',
|
||||
'elFinderVolumeFlysystemGoogleDriveCache' => 'elFinderFlysystemGoogleDriveNetmount.php',
|
||||
'elFinderVolumeFlysystemGoogleDriveNetmount' => 'elFinderFlysystemGoogleDriveNetmount.php',
|
||||
'elFinderVolumeGoogleDrive' => 'elFinderVolumeGoogleDrive.class.php',
|
||||
'elFinderVolumeGroup' => 'elFinderVolumeGroup.class.php',
|
||||
'elFinderVolumeLocalFileSystem' => 'elFinderVolumeLocalFileSystem.class.php',
|
||||
'elFinderVolumeMySQL' => 'elFinderVolumeMySQL.class.php',
|
||||
'elFinderVolumeSFTPphpseclib' => 'elFinderVolumeSFTPphpseclib.class.php',
|
||||
'elFinderVolumeTrash' => 'elFinderVolumeTrash.class.php',
|
||||
);
|
||||
if (isset($map[$name])) {
|
||||
return include_once(ELFINDER_PHP_ROOT_PATH . '/' . $map[$name]);
|
||||
}
|
||||
$prefix = substr($name, 0, 14);
|
||||
if (substr($prefix, 0, 8) === 'elFinder') {
|
||||
if ($prefix === 'elFinderVolume') {
|
||||
$file = ELFINDER_PHP_ROOT_PATH . '/' . $name . '.class.php';
|
||||
return (is_file($file) && include_once($file));
|
||||
} else if ($prefix === 'elFinderPlugin') {
|
||||
$file = ELFINDER_PHP_ROOT_PATH . '/plugins/' . substr($name, 14) . '/plugin.php';
|
||||
return (is_file($file) && include_once($file));
|
||||
} else if ($prefix === 'elFinderEditor') {
|
||||
$file = ELFINDER_PHP_ROOT_PATH . '/editors/' . substr($name, 14) . '/editor.php';
|
||||
return (is_file($file) && include_once($file));
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (version_compare(PHP_VERSION, '5.3', '<')) {
|
||||
spl_autoload_register('elFinderAutoloader');
|
||||
} else {
|
||||
spl_autoload_register('elFinderAutoloader', true, true);
|
||||
}
|
||||
|
||||
+449
@@ -0,0 +1,449 @@
|
||||
<?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';
|
||||
// // OneDrive Netmount driver need next two settings. You can get at
|
||||
// // https://portal.azure.com/#blade/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/RegisteredApps
|
||||
// // 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();
|
||||
|
||||
+180
@@ -0,0 +1,180 @@
|
||||
<?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"
|
||||
// // 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` 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"
|
||||
// // 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 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"
|
||||
// // 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
|
||||
// // * cURL PHP extension required
|
||||
// // * HTTP server PATH_INFO supports required
|
||||
// // Enable network mount
|
||||
// elFinder::$netDrivers['onedrive'] = 'OneDrive';
|
||||
// // OneDrive Netmount driver need next two settings. You can get at
|
||||
// // https://portal.azure.com/#blade/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/RegisteredApps
|
||||
// // 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', '');
|
||||
// ===============================================
|
||||
|
||||
// // 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"
|
||||
// // 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', '');
|
||||
// ===============================================
|
||||
|
||||
|
||||
// // 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
|
||||
}
|
||||
|
||||
|
||||
// Documentation for connector options:
|
||||
// https://github.com/Studio-42/elFinder/wiki/Connector-configuration-options
|
||||
$opts = array(
|
||||
// 'debug' => true,
|
||||
'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)
|
||||
),
|
||||
// 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
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
// run elFinder
|
||||
$connector = new elFinderConnector(new elFinder($opts));
|
||||
$connector->run();
|
||||
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
<?php
|
||||
|
||||
class elFinderEditorOnlineConvert extends elFinderEditor
|
||||
{
|
||||
protected $allowed = array('init', 'api');
|
||||
|
||||
public function enabled()
|
||||
{
|
||||
return defined('ELFINDER_ONLINE_CONVERT_APIKEY') && ELFINDER_ONLINE_CONVERT_APIKEY && (!defined('ELFINDER_DISABLE_ONLINE_CONVERT') || !ELFINDER_DISABLE_ONLINE_CONVERT);
|
||||
}
|
||||
|
||||
public function init()
|
||||
{
|
||||
return array('api' => defined('ELFINDER_ONLINE_CONVERT_APIKEY') && ELFINDER_ONLINE_CONVERT_APIKEY && function_exists('curl_init'));
|
||||
}
|
||||
|
||||
public function api()
|
||||
{
|
||||
// return array('apires' => array('message' => 'Currently disabled for developping...'));
|
||||
$endpoint = 'https://api2.online-convert.com/jobs';
|
||||
$category = $this->argValue('category');
|
||||
$convert = $this->argValue('convert');
|
||||
$options = $this->argValue('options');
|
||||
$source = $this->argValue('source');
|
||||
$filename = $this->argValue('filename');
|
||||
$mime = $this->argValue('mime');
|
||||
$jobid = $this->argValue('jobid');
|
||||
$string_method = '';
|
||||
$options = array();
|
||||
// Currently these converts are make error with API call. I don't know why.
|
||||
$nonApi = array('android', 'blackberry', 'dpg', 'ipad', 'iphone', 'ipod', 'nintendo-3ds', 'nintendo-ds', 'ps3', 'psp', 'wii', 'xbox');
|
||||
if (in_array($convert, $nonApi)) {
|
||||
return array('apires' => array());
|
||||
}
|
||||
$ch = null;
|
||||
if ($convert && $source) {
|
||||
$request = array(
|
||||
'input' => array(array(
|
||||
'type' => 'remote',
|
||||
'source' => $source
|
||||
)),
|
||||
'conversion' => array(array(
|
||||
'target' => $convert
|
||||
))
|
||||
);
|
||||
|
||||
if ($filename !== '') {
|
||||
$request['input'][0]['filename'] = $filename;
|
||||
}
|
||||
|
||||
if ($mime !== '') {
|
||||
$request['input'][0]['content_type'] = $mime;
|
||||
}
|
||||
|
||||
if ($category) {
|
||||
$request['conversion'][0]['category'] = $category;
|
||||
}
|
||||
|
||||
if ($options && $options !== 'null') {
|
||||
$options = json_decode($options, true);
|
||||
}
|
||||
if (!is_array($options)) {
|
||||
$options = array();
|
||||
}
|
||||
if ($options) {
|
||||
$request['conversion'][0]['options'] = $options;
|
||||
}
|
||||
|
||||
$ch = curl_init($endpoint);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($request));
|
||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
|
||||
'X-Oc-Api-Key: ' . ELFINDER_ONLINE_CONVERT_APIKEY,
|
||||
'Content-Type: application/json',
|
||||
'cache-control: no-cache'
|
||||
));
|
||||
} else if ($jobid) {
|
||||
$ch = curl_init($endpoint . '/' . $jobid);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
|
||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
|
||||
'X-Oc-Api-Key: ' . ELFINDER_ONLINE_CONVERT_APIKEY,
|
||||
'cache-control: no-cache'
|
||||
));
|
||||
}
|
||||
|
||||
if ($ch) {
|
||||
$response = curl_exec($ch);
|
||||
$info = curl_getinfo($ch);
|
||||
$error = curl_error($ch);
|
||||
curl_close($ch);
|
||||
|
||||
if (!empty($error)) {
|
||||
$res = array('error' => $error);
|
||||
} else {
|
||||
$data = json_decode($response, true);
|
||||
if (isset($data['status']) && isset($data['status']['code']) && $data['status']['code'] === 'completed') {
|
||||
/** @var elFinderSession $session */
|
||||
$session = $this->elfinder->getSession();
|
||||
$urlContentSaveIds = $session->get('urlContentSaveIds', array());
|
||||
$urlContentSaveIds['OnlineConvert-' . $data['id']] = true;
|
||||
$session->set('urlContentSaveIds', $urlContentSaveIds);
|
||||
}
|
||||
$res = array('apires' => $data);
|
||||
}
|
||||
|
||||
return $res;
|
||||
} else {
|
||||
return array('error' => array('errCmdParams', 'editor.OnlineConvert.api'));
|
||||
}
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
class elFinderEditorZipArchive extends elFinderEditor
|
||||
{
|
||||
public function enabled()
|
||||
{
|
||||
return (!defined('ELFINDER_DISABLE_ZIPEDITOR') || !ELFINDER_DISABLE_ZIPEDITOR) &&
|
||||
class_exists('Barryvdh\elFinderFlysystemDriver\Driver') &&
|
||||
class_exists('League\Flysystem\Filesystem') &&
|
||||
class_exists('League\Flysystem\ZipArchive\ZipArchiveAdapter');
|
||||
}
|
||||
}
|
||||
+225
@@ -0,0 +1,225 @@
|
||||
<?php
|
||||
|
||||
class elFinderEditorZohoOffice extends elFinderEditor
|
||||
{
|
||||
private static $curlTimeout = 20;
|
||||
|
||||
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://api.office-integrator.com/writer/officeapi/v1/document',
|
||||
'sheet' => 'https://api.office-integrator.com/sheet/officeapi/v1/spreadsheet',
|
||||
'show' => 'https://api.office-integrator.com/show/officeapi/v1/presentation',
|
||||
);
|
||||
|
||||
private $srvs = array(
|
||||
'application/msword' => 'writer',
|
||||
'application/vnd.openxmlformats-officedocument.wordprocessingml.document' => 'writer',
|
||||
'application/pdf' => 'writer',
|
||||
'application/vnd.oasis.opendocument.text' => 'writer',
|
||||
'application/rtf' => 'writer',
|
||||
'text/html' => 'writer',
|
||||
'application/vnd.ms-excel' => 'sheet',
|
||||
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' => 'sheet',
|
||||
'application/vnd.oasis.opendocument.spreadsheet' => 'sheet',
|
||||
'application/vnd.sun.xml.calc' => 'sheet',
|
||||
'text/csv' => 'sheet',
|
||||
'text/tab-separated-values' => 'sheet',
|
||||
'application/vnd.ms-powerpoint' => 'show',
|
||||
'application/vnd.openxmlformats-officedocument.presentationml.presentation' => 'show',
|
||||
'application/vnd.openxmlformats-officedocument.presentationml.slideshow' => 'show',
|
||||
'application/vnd.oasis.opendocument.presentation' => 'show',
|
||||
'application/vnd.sun.xml.impress' => 'show',
|
||||
);
|
||||
|
||||
private $myName = '';
|
||||
|
||||
protected function extentionNormrize($extention, $srvsName) {
|
||||
switch($srvsName) {
|
||||
case 'writer':
|
||||
if (!in_array($extention, array('zdoc', 'docx', 'rtf', 'odt', 'html', 'txt'))) {
|
||||
$extention = 'docx';
|
||||
}
|
||||
break;
|
||||
case 'sheet':
|
||||
if (!in_array($extention, array('zsheet', 'xls', 'xlsx', 'ods', 'csv', 'tsv'))) {
|
||||
$extention = 'xlsx';
|
||||
}
|
||||
break;
|
||||
case 'show':
|
||||
if (!in_array($extention, array('zslides', 'pptx', 'pps', 'ppsx', 'odp', 'sxi'))) {
|
||||
$extention = 'pptx';
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
return $extention;
|
||||
}
|
||||
|
||||
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');
|
||||
}
|
||||
|
||||
public function init()
|
||||
{
|
||||
if (!defined('ELFINDER_ZOHO_OFFICE_APIKEY') || !function_exists('curl_init')) {
|
||||
return array('error', array(elFinder::ERROR_CONF, '`ELFINDER_ZOHO_OFFICE_APIKEY` or curl extension'));
|
||||
}
|
||||
if (!empty($this->args['target'])) {
|
||||
$fp = $cfile = null;
|
||||
$hash = $this->args['target'];
|
||||
/** @var elFinderVolumeDriver $srcVol */
|
||||
if (($srcVol = $this->elfinder->getVolume($hash)) && ($file = $srcVol->file($hash))) {
|
||||
$cdata = empty($this->args['cdata']) ? '' : $this->args['cdata'];
|
||||
$cookie = $this->elfinder->getFetchCookieFile();
|
||||
$save = false;
|
||||
$ch = curl_init();
|
||||
$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);
|
||||
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie);
|
||||
}
|
||||
$res = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
if ($res) {
|
||||
if ($data = json_decode($res, true)) {
|
||||
$save = !empty($data['cansave']);
|
||||
}
|
||||
}
|
||||
|
||||
if ($size = $file['size']) {
|
||||
$src = $srcVol->open($hash);
|
||||
$fp = tmpfile();
|
||||
stream_copy_to_stream($src, $fp);
|
||||
$srcVol->close($src, $hash);
|
||||
$info = stream_get_meta_data($fp);
|
||||
if ($info && !empty($info['uri'])) {
|
||||
$srcFile = $info['uri'];
|
||||
if (class_exists('CURLFile')) {
|
||||
$cfile = new CURLFile($srcFile);
|
||||
$cfile->setPostFilename($file['name']);
|
||||
$cfile->setMimeType($file['mime']);
|
||||
} else {
|
||||
$cfile = '@' . $srcFile;
|
||||
}
|
||||
}
|
||||
}
|
||||
//$srv = $this->args['service'];
|
||||
$srvsName = $this->srvs[$file['mime']];
|
||||
$format = $this->extentionNormrize($srcVol->getExtentionByMime($file['mime']), $srvsName);
|
||||
if (!$format) {
|
||||
$format = substr($file['name'], strrpos($file['name'], '.') * -1);
|
||||
}
|
||||
$lang = $this->args['lang'];
|
||||
if ($lang === 'jp') {
|
||||
$lang = 'ja';
|
||||
}
|
||||
$data = array(
|
||||
'apikey' => ELFINDER_ZOHO_OFFICE_APIKEY,
|
||||
'callback_settings' => array(
|
||||
'save_format' => $format,
|
||||
'save_url_params' => 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) {
|
||||
$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['document'] = $cfile;
|
||||
}
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $this->urls[$srvsName]);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, self::$curlTimeout);
|
||||
curl_setopt($ch, CURLOPT_HEADER, 0);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($ch, CURLOPT_POST, 1);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
|
||||
$res = curl_exec($ch);
|
||||
$error = curl_error($ch);
|
||||
curl_close($ch);
|
||||
|
||||
$fp && fclose($fp);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
if ($error) {
|
||||
return array('error' => is_string($error)? preg_split('/[\r\n]+/', $error) : 'Error code: ' . $error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return array('error' => array('errCmdParams', 'editor.' . $this->myName . '.init'));
|
||||
}
|
||||
|
||||
public function save()
|
||||
{
|
||||
if (!empty($_POST) && !empty($_POST['hash']) && !empty($_FILES) && !empty($_FILES['content'])) {
|
||||
$hash = $_POST['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');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return array('raw' => true, 'error' => '', 'header' => 'HTTP/1.1 500 Internal Server Error');
|
||||
}
|
||||
|
||||
public function chk()
|
||||
{
|
||||
$hash = $this->args['target'];
|
||||
$res = false;
|
||||
/** @var elFinderVolumeDriver $volume */
|
||||
if ($volume = $this->elfinder->getVolume($hash)) {
|
||||
if ($file = $volume->file($hash)) {
|
||||
$res = (bool)$file['write'];
|
||||
}
|
||||
}
|
||||
return array('cansave' => $res);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Abstract class of editor plugins.
|
||||
*
|
||||
* @author Naoki Sawada
|
||||
*/
|
||||
class elFinderEditor
|
||||
{
|
||||
/**
|
||||
* Array of allowed method by request from client side.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $allowed = array();
|
||||
|
||||
/**
|
||||
* elFinder instance
|
||||
*
|
||||
* @var object elFinder instance
|
||||
*/
|
||||
protected $elfinder;
|
||||
|
||||
/**
|
||||
* Arguments
|
||||
*
|
||||
* @var array argValues
|
||||
*/
|
||||
protected $args;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param object $elfinder
|
||||
* @param array $args
|
||||
*/
|
||||
public function __construct($elfinder, $args)
|
||||
{
|
||||
$this->elfinder = $elfinder;
|
||||
$this->args = $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return boolean that this plugin is enabled.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function enabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return boolean that $name method is allowed.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isAllowedMethod($name)
|
||||
{
|
||||
$checker = array_flip($this->allowed);
|
||||
|
||||
return isset($checker[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return $this->args value of the key
|
||||
*
|
||||
* @param string $key target key
|
||||
* @param string $empty empty value
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function argValue($key, $empty = '')
|
||||
{
|
||||
return isset($this->args[$key]) ? $this->args[$key] : $empty;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
+380
@@ -0,0 +1,380 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Default elFinder connector
|
||||
*
|
||||
* @author Dmitry (dio) Levashov
|
||||
**/
|
||||
class elFinderConnector
|
||||
{
|
||||
/**
|
||||
* elFinder instance
|
||||
*
|
||||
* @var elFinder
|
||||
**/
|
||||
protected $elFinder;
|
||||
|
||||
/**
|
||||
* Options
|
||||
*
|
||||
* @var array
|
||||
**/
|
||||
protected $options = array();
|
||||
|
||||
/**
|
||||
* Must be use output($data) $data['header']
|
||||
*
|
||||
* @var string
|
||||
* @deprecated
|
||||
**/
|
||||
protected $header = '';
|
||||
|
||||
/**
|
||||
* HTTP request method
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reqMethod = '';
|
||||
|
||||
/**
|
||||
* Content type of output JSON
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected static $contentType = 'Content-Type: application/json; charset=utf-8';
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param $elFinder
|
||||
* @param bool $debug
|
||||
*
|
||||
* @author Dmitry (dio) Levashov
|
||||
*/
|
||||
public function __construct($elFinder, $debug = false)
|
||||
{
|
||||
|
||||
$this->elFinder = $elFinder;
|
||||
$this->reqMethod = strtoupper($_SERVER["REQUEST_METHOD"]);
|
||||
if ($debug) {
|
||||
self::$contentType = 'Content-Type: text/plain; charset=utf-8';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute elFinder command and output result
|
||||
*
|
||||
* @return void
|
||||
* @throws Exception
|
||||
* @author Dmitry (dio) Levashov
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$isPost = $this->reqMethod === 'POST';
|
||||
$src = $isPost ? array_merge($_GET, $_POST) : $_GET;
|
||||
$maxInputVars = (!$src || isset($src['targets'])) ? ini_get('max_input_vars') : null;
|
||||
if ((!$src || $maxInputVars) && $rawPostData = file_get_contents('php://input')) {
|
||||
// for max_input_vars and supports IE XDomainRequest()
|
||||
$parts = explode('&', $rawPostData);
|
||||
if (!$src || $maxInputVars < count($parts)) {
|
||||
$src = array();
|
||||
foreach ($parts as $part) {
|
||||
list($key, $value) = array_pad(explode('=', $part), 2, '');
|
||||
$key = rawurldecode($key);
|
||||
if (preg_match('/^(.+?)\[([^\[\]]*)\]$/', $key, $m)) {
|
||||
$key = $m[1];
|
||||
$idx = $m[2];
|
||||
if (!isset($src[$key])) {
|
||||
$src[$key] = array();
|
||||
}
|
||||
if ($idx) {
|
||||
$src[$key][$idx] = rawurldecode($value);
|
||||
} else {
|
||||
$src[$key][] = rawurldecode($value);
|
||||
}
|
||||
} else {
|
||||
$src[$key] = rawurldecode($value);
|
||||
}
|
||||
}
|
||||
$_POST = $this->input_filter($src);
|
||||
$_REQUEST = $this->input_filter(array_merge_recursive($src, $_REQUEST));
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($src['targets']) && $this->elFinder->maxTargets && count($src['targets']) > $this->elFinder->maxTargets) {
|
||||
$this->output(array('error' => $this->elFinder->error(elFinder::ERROR_MAX_TARGTES)));
|
||||
}
|
||||
|
||||
$cmd = isset($src['cmd']) ? $src['cmd'] : '';
|
||||
$args = array();
|
||||
|
||||
if (!function_exists('json_encode')) {
|
||||
$error = $this->elFinder->error(elFinder::ERROR_CONF, elFinder::ERROR_CONF_NO_JSON);
|
||||
$this->output(array('error' => '{"error":["' . implode('","', $error) . '"]}', 'raw' => true));
|
||||
}
|
||||
|
||||
if (!$this->elFinder->loaded()) {
|
||||
$this->output(array('error' => $this->elFinder->error(elFinder::ERROR_CONF, elFinder::ERROR_CONF_NO_VOL), 'debug' => $this->elFinder->mountErrors));
|
||||
}
|
||||
|
||||
// telepat_mode: on
|
||||
if (!$cmd && $isPost) {
|
||||
$this->output(array('error' => $this->elFinder->error(elFinder::ERROR_UPLOAD, elFinder::ERROR_UPLOAD_TOTAL_SIZE), 'header' => 'Content-Type: text/html'));
|
||||
}
|
||||
// telepat_mode: off
|
||||
|
||||
if (!$this->elFinder->commandExists($cmd)) {
|
||||
$this->output(array('error' => $this->elFinder->error(elFinder::ERROR_UNKNOWN_CMD)));
|
||||
}
|
||||
|
||||
// collect required arguments to exec command
|
||||
$hasFiles = false;
|
||||
foreach ($this->elFinder->commandArgsList($cmd) as $name => $req) {
|
||||
if ($name === 'FILES') {
|
||||
if (isset($_FILES)) {
|
||||
$hasFiles = true;
|
||||
} elseif ($req) {
|
||||
$this->output(array('error' => $this->elFinder->error(elFinder::ERROR_INV_PARAMS, $cmd)));
|
||||
}
|
||||
} else {
|
||||
$arg = isset($src[$name]) ? $src[$name] : '';
|
||||
|
||||
if (!is_array($arg) && $req !== '') {
|
||||
$arg = trim($arg);
|
||||
}
|
||||
if ($req && $arg === '') {
|
||||
$this->output(array('error' => $this->elFinder->error(elFinder::ERROR_INV_PARAMS, $cmd)));
|
||||
}
|
||||
$args[$name] = $arg;
|
||||
}
|
||||
}
|
||||
|
||||
$args['debug'] = isset($src['debug']) ? !!$src['debug'] : false;
|
||||
|
||||
$args = $this->input_filter($args);
|
||||
if ($hasFiles) {
|
||||
$args['FILES'] = $_FILES;
|
||||
}
|
||||
|
||||
try {
|
||||
$this->output($this->elFinder->exec($cmd, $args));
|
||||
} catch (elFinderAbortException $e) {
|
||||
// connection aborted
|
||||
// unlock session data for multiple access
|
||||
$this->elFinder->getSession()->close();
|
||||
// HTTP response code
|
||||
header('HTTP/1.0 204 No Content');
|
||||
// clear output buffer
|
||||
while (ob_get_level() && ob_end_clean()) {
|
||||
}
|
||||
exit();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the header.
|
||||
*
|
||||
* @param array|string $value HTTP header(s)
|
||||
*/
|
||||
public function setHeader($value)
|
||||
{
|
||||
$this->header = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Output json
|
||||
*
|
||||
* @param array data to output
|
||||
*
|
||||
* @return void
|
||||
* @throws elFinderAbortException
|
||||
* @author Dmitry (dio) Levashov
|
||||
*/
|
||||
protected function output(array $data)
|
||||
{
|
||||
// unlock session data for multiple access
|
||||
$this->elFinder->getSession()->close();
|
||||
// client disconnect should abort
|
||||
ignore_user_abort(false);
|
||||
|
||||
if ($this->header) {
|
||||
self::sendHeader($this->header);
|
||||
}
|
||||
|
||||
if (isset($data['pointer'])) {
|
||||
// set time limit to 0
|
||||
elFinder::extendTimeLimit(0);
|
||||
|
||||
// send optional header
|
||||
if (!empty($data['header'])) {
|
||||
self::sendHeader($data['header']);
|
||||
}
|
||||
|
||||
// clear output buffer
|
||||
while (ob_get_level() && ob_end_clean()) {
|
||||
}
|
||||
|
||||
$toEnd = true;
|
||||
$fp = $data['pointer'];
|
||||
$sendData = !($this->reqMethod === 'HEAD' || !empty($data['info']['xsendfile']));
|
||||
$psize = null;
|
||||
if (($this->reqMethod === 'GET' || !$sendData)
|
||||
&& (elFinder::isSeekableStream($fp) || elFinder::isSeekableUrl($fp))
|
||||
&& (array_search('Accept-Ranges: none', headers_list()) === false)) {
|
||||
header('Accept-Ranges: bytes');
|
||||
if (!empty($_SERVER['HTTP_RANGE'])) {
|
||||
$size = $data['info']['size'];
|
||||
$end = $size - 1;
|
||||
if (preg_match('/bytes=(\d*)-(\d*)(,?)/i', $_SERVER['HTTP_RANGE'], $matches)) {
|
||||
if (empty($matches[3])) {
|
||||
if (empty($matches[1]) && $matches[1] !== '0') {
|
||||
$start = $size - $matches[2];
|
||||
} else {
|
||||
$start = intval($matches[1]);
|
||||
if (!empty($matches[2])) {
|
||||
$end = intval($matches[2]);
|
||||
if ($end >= $size) {
|
||||
$end = $size - 1;
|
||||
}
|
||||
$toEnd = ($end == ($size - 1));
|
||||
}
|
||||
}
|
||||
$psize = $end - $start + 1;
|
||||
|
||||
header('HTTP/1.1 206 Partial Content');
|
||||
header('Content-Length: ' . $psize);
|
||||
header('Content-Range: bytes ' . $start . '-' . $end . '/' . $size);
|
||||
|
||||
// Apache mod_xsendfile dose not support range request
|
||||
if (isset($data['info']['xsendfile']) && strtolower($data['info']['xsendfile']) === 'x-sendfile') {
|
||||
if (function_exists('header_remove')) {
|
||||
header_remove($data['info']['xsendfile']);
|
||||
} else {
|
||||
header($data['info']['xsendfile'] . ':');
|
||||
}
|
||||
unset($data['info']['xsendfile']);
|
||||
if ($this->reqMethod !== 'HEAD') {
|
||||
$sendData = true;
|
||||
}
|
||||
}
|
||||
|
||||
$sendData && !elFinder::isSeekableUrl($fp) && fseek($fp, $start);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($sendData && is_null($psize)) {
|
||||
elFinder::rewind($fp);
|
||||
}
|
||||
} else {
|
||||
header('Accept-Ranges: none');
|
||||
if (isset($data['info']) && !$data['info']['size']) {
|
||||
if (function_exists('header_remove')) {
|
||||
header_remove('Content-Length');
|
||||
} else {
|
||||
header('Content-Length:');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($sendData) {
|
||||
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', '<')) {
|
||||
file_put_contents('php://output', $fp);
|
||||
} else {
|
||||
fpassthru($fp);
|
||||
}
|
||||
} else {
|
||||
$out = fopen('php://output', 'wb');
|
||||
stream_copy_to_stream($fp, $out, $psize);
|
||||
fclose($out);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($data['volume'])) {
|
||||
$data['volume']->close($fp, $data['info']['hash']);
|
||||
} else {
|
||||
fclose($fp);
|
||||
}
|
||||
exit();
|
||||
} else {
|
||||
self::outputJson($data);
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove null & stripslashes applies on "magic_quotes_gpc"
|
||||
*
|
||||
* @param mixed $args
|
||||
*
|
||||
* @return mixed
|
||||
* @author Naoki Sawada
|
||||
*/
|
||||
protected function input_filter($args)
|
||||
{
|
||||
static $magic_quotes_gpc = NULL;
|
||||
|
||||
if ($magic_quotes_gpc === NULL)
|
||||
$magic_quotes_gpc = (version_compare(PHP_VERSION, '5.4', '<') && get_magic_quotes_gpc());
|
||||
|
||||
if (is_array($args)) {
|
||||
return array_map(array(& $this, 'input_filter'), $args);
|
||||
}
|
||||
$res = str_replace("\0", '', $args);
|
||||
$magic_quotes_gpc && ($res = stripslashes($res));
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send HTTP header
|
||||
*
|
||||
* @param string|array $header optional header
|
||||
*/
|
||||
protected static function sendHeader($header = null)
|
||||
{
|
||||
if ($header) {
|
||||
if (is_array($header)) {
|
||||
foreach ($header as $h) {
|
||||
header($h);
|
||||
}
|
||||
} else {
|
||||
header($header);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Output JSON
|
||||
*
|
||||
* @param array $data
|
||||
*/
|
||||
public static function outputJson($data)
|
||||
{
|
||||
// send header
|
||||
$header = isset($data['header']) ? $data['header'] : self::$contentType;
|
||||
self::sendHeader($header);
|
||||
|
||||
unset($data['header']);
|
||||
|
||||
if (!empty($data['raw']) && isset($data['error'])) {
|
||||
$out = $data['error'];
|
||||
} else {
|
||||
if (isset($data['debug']) && isset($data['debug']['backendErrors'])) {
|
||||
$data['debug']['backendErrors'] = array_merge($data['debug']['backendErrors'], elFinder::$phpErrors);
|
||||
}
|
||||
$out = json_encode($data);
|
||||
}
|
||||
|
||||
// clear output buffer
|
||||
while (ob_get_level() && ob_end_clean()) {
|
||||
}
|
||||
|
||||
header('Content-Length: ' . strlen($out));
|
||||
|
||||
echo $out;
|
||||
|
||||
flush();
|
||||
}
|
||||
}// END class
|
||||
+380
@@ -0,0 +1,380 @@
|
||||
<?php
|
||||
|
||||
use League\Flysystem\Filesystem;
|
||||
use League\Flysystem\Adapter\Local;
|
||||
use League\Flysystem\Cached\CachedAdapter;
|
||||
use League\Flysystem\Cached\Storage\Adapter as ACache;
|
||||
use Hypweb\Flysystem\GoogleDrive\GoogleDriveAdapter;
|
||||
use Hypweb\Flysystem\Cached\Extra\Hasdir;
|
||||
use Hypweb\Flysystem\Cached\Extra\DisableEnsureParentDirectories;
|
||||
use Hypweb\elFinderFlysystemDriverExt\Driver as ExtDriver;
|
||||
|
||||
elFinder::$netDrivers['googledrive'] = 'FlysystemGoogleDriveNetmount';
|
||||
|
||||
if (!class_exists('elFinderVolumeFlysystemGoogleDriveCache', false)) {
|
||||
class elFinderVolumeFlysystemGoogleDriveCache extends ACache
|
||||
{
|
||||
use Hasdir;
|
||||
use DisableEnsureParentDirectories;
|
||||
}
|
||||
}
|
||||
|
||||
class elFinderVolumeFlysystemGoogleDriveNetmount extends ExtDriver
|
||||
{
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$opts = array(
|
||||
'acceptedName' => '#^[^/\\?*:|"<>]*[^./\\?*:|"<>]$#',
|
||||
'rootCssClass' => 'elfinder-navbar-root-googledrive',
|
||||
'gdAlias' => '%s@GDrive',
|
||||
'gdCacheDir' => __DIR__ . '/.tmp',
|
||||
'gdCachePrefix' => 'gd-',
|
||||
'gdCacheExpire' => 600
|
||||
);
|
||||
|
||||
$this->options = array_merge($this->options, $opts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare driver before mount volume.
|
||||
* Return true if volume is ready.
|
||||
*
|
||||
* @return bool
|
||||
**/
|
||||
protected function init()
|
||||
{
|
||||
if (empty($this->options['icon'])) {
|
||||
$this->options['icon'] = true;
|
||||
}
|
||||
if ($res = parent::init()) {
|
||||
if ($this->options['icon'] === true) {
|
||||
unset($this->options['icon']);
|
||||
}
|
||||
// enable command archive
|
||||
$this->options['useRemoteArchive'] = true;
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare
|
||||
* Call from elFinder::netmout() before volume->mount()
|
||||
*
|
||||
* @param $options
|
||||
*
|
||||
* @return Array
|
||||
* @author Naoki Sawada
|
||||
*/
|
||||
public function netmountPrepare($options)
|
||||
{
|
||||
if (empty($options['client_id']) && defined('ELFINDER_GOOGLEDRIVE_CLIENTID')) {
|
||||
$options['client_id'] = ELFINDER_GOOGLEDRIVE_CLIENTID;
|
||||
}
|
||||
if (empty($options['client_secret']) && defined('ELFINDER_GOOGLEDRIVE_CLIENTSECRET')) {
|
||||
$options['client_secret'] = ELFINDER_GOOGLEDRIVE_CLIENTSECRET;
|
||||
}
|
||||
|
||||
if (!isset($options['pass'])) {
|
||||
$options['pass'] = '';
|
||||
}
|
||||
|
||||
try {
|
||||
$client = new \Google_Client();
|
||||
$client->setClientId($options['client_id']);
|
||||
$client->setClientSecret($options['client_secret']);
|
||||
|
||||
if ($options['pass'] === 'reauth') {
|
||||
$options['pass'] = '';
|
||||
$this->session->set('GoogleDriveAuthParams', [])->set('GoogleDriveTokens', []);
|
||||
} else if ($options['pass'] === 'googledrive') {
|
||||
$options['pass'] = '';
|
||||
}
|
||||
|
||||
$options = array_merge($this->session->get('GoogleDriveAuthParams', []), $options);
|
||||
|
||||
if (!isset($options['access_token'])) {
|
||||
$options['access_token'] = $this->session->get('GoogleDriveTokens', []);
|
||||
$this->session->remove('GoogleDriveTokens');
|
||||
}
|
||||
$aToken = $options['access_token'];
|
||||
|
||||
$rootObj = $service = null;
|
||||
if ($aToken) {
|
||||
try {
|
||||
$client->setAccessToken($aToken);
|
||||
if ($client->isAccessTokenExpired()) {
|
||||
$aToken = array_merge($aToken, $client->fetchAccessTokenWithRefreshToken());
|
||||
$client->setAccessToken($aToken);
|
||||
}
|
||||
$service = new \Google_Service_Drive($client);
|
||||
$rootObj = $service->files->get('root');
|
||||
|
||||
$options['access_token'] = $aToken;
|
||||
$this->session->set('GoogleDriveAuthParams', $options);
|
||||
|
||||
} catch (Exception $e) {
|
||||
$aToken = [];
|
||||
$options['access_token'] = [];
|
||||
if ($options['user'] !== 'init') {
|
||||
$this->session->set('GoogleDriveAuthParams', $options);
|
||||
return array('exit' => true, 'error' => elFinder::ERROR_REAUTH_REQUIRE);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$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();
|
||||
}
|
||||
|
||||
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($code)) {
|
||||
$client->setScopes([Google_Service_Drive::DRIVE]);
|
||||
if (!empty($options['offline'])) {
|
||||
$client->setApprovalPrompt('force');
|
||||
$client->setAccessType('offline');
|
||||
}
|
||||
$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">';
|
||||
$html .= '<script>
|
||||
$("#' . $options['id'] . '").elfinder("instance").trigger("netmount", {protocol: "googledrive", mode: "makebtn", url: "' . $url . '"});
|
||||
</script>';
|
||||
if (empty($options['pass']) && $options['host'] !== '1') {
|
||||
$options['pass'] = 'return';
|
||||
$this->session->set('GoogleDriveAuthParams', $options);
|
||||
return array('exit' => true, 'body' => $html);
|
||||
} else {
|
||||
$out = array(
|
||||
'node' => $options['id'],
|
||||
'json' => '{"protocol": "googledrive", "mode": "makebtn", "body" : "' . str_replace($html, '"', '\\"') . '", "error" : "' . elFinder::ERROR_ACCESS_DENIED . '"}',
|
||||
'bind' => 'netmount'
|
||||
);
|
||||
return array('exit' => 'callback', 'out' => $out);
|
||||
}
|
||||
} else {
|
||||
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([
|
||||
'pageSize' => 1000,
|
||||
'q' => 'trashed = false and mimeType = "application/vnd.google-apps.folder"'
|
||||
]) as $f) {
|
||||
$folders[$f->getId()] = $f->getName();
|
||||
}
|
||||
natcasesort($folders);
|
||||
$folders = ['root' => $rootObj->getName()] + $folders;
|
||||
$folders = json_encode($folders);
|
||||
$json = '{"protocol": "googledrive", "mode": "done", "folders": ' . $folders . '}';
|
||||
$options['pass'] = 'return';
|
||||
$html = 'Google.com';
|
||||
$html .= '<script>
|
||||
$("#' . $options['id'] . '").elfinder("instance").trigger("netmount", ' . $json . ');
|
||||
</script>';
|
||||
$this->session->set('GoogleDriveAuthParams', $options);
|
||||
return array('exit' => true, 'body' => $html);
|
||||
}
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
$this->session->remove('GoogleDriveAuthParams')->remove('GoogleDriveTokens');
|
||||
if (empty($options['pass'])) {
|
||||
return array('exit' => true, 'body' => '{msg:' . elFinder::ERROR_ACCESS_DENIED . '}' . ' ' . $e->getMessage());
|
||||
} else {
|
||||
return array('exit' => true, 'error' => [elFinder::ERROR_ACCESS_DENIED, $e->getMessage()]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$aToken) {
|
||||
return array('exit' => true, 'error' => elFinder::ERROR_REAUTH_REQUIRE);
|
||||
}
|
||||
|
||||
if ($options['path'] === '/') {
|
||||
$options['path'] = 'root';
|
||||
}
|
||||
|
||||
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) {
|
||||
return array('exit' => true, 'error' => [elFinder::ERROR_TRGDIR_NOT_FOUND, $options['path']]);
|
||||
} else {
|
||||
return array('exit' => true, 'error' => $e->getMessage());
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
return array('exit' => true, 'error' => $e->getMessage());
|
||||
}
|
||||
|
||||
foreach (['host', 'user', 'pass', 'id', 'offline'] as $key) {
|
||||
unset($options[$key]);
|
||||
}
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* process of on netunmount
|
||||
* Drop table `dropbox` & rm thumbs
|
||||
*
|
||||
* @param $netVolumes
|
||||
* @param $key
|
||||
*
|
||||
* @return bool
|
||||
* @internal param array $options
|
||||
*/
|
||||
public function netunmount($netVolumes, $key)
|
||||
{
|
||||
$cache = $this->options['gdCacheDir'] . DIRECTORY_SEPARATOR . $this->options['gdCachePrefix'] . $this->netMountKey;
|
||||
if (file_exists($cache) && is_writeable($cache)) {
|
||||
unlink($cache);
|
||||
}
|
||||
if ($tmbs = glob($this->tmbPath . DIRECTORY_SEPARATOR . $this->netMountKey . '*')) {
|
||||
foreach ($tmbs as $file) {
|
||||
unlink($file);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* "Mount" volume.
|
||||
* Return true if volume available for read or write,
|
||||
* false - otherwise
|
||||
*
|
||||
* @param array $opts
|
||||
*
|
||||
* @return bool
|
||||
* @author Naoki Sawada
|
||||
*/
|
||||
public function mount(array $opts)
|
||||
{
|
||||
$creds = null;
|
||||
if (isset($opts['access_token'])) {
|
||||
$this->netMountKey = md5(join('-', array('googledrive', $opts['path'], (isset($opts['access_token']['refresh_token']) ? $opts['access_token']['refresh_token'] : $opts['access_token']['access_token']))));
|
||||
}
|
||||
|
||||
$client = new \Google_Client();
|
||||
$client->setClientId($opts['client_id']);
|
||||
$client->setClientSecret($opts['client_secret']);
|
||||
|
||||
if (!empty($opts['access_token'])) {
|
||||
$client->setAccessToken($opts['access_token']);
|
||||
}
|
||||
if ($this->needOnline && $client->isAccessTokenExpired()) {
|
||||
try {
|
||||
$creds = $client->fetchAccessTokenWithRefreshToken();
|
||||
} catch (LogicException $e) {
|
||||
$this->session->remove('GoogleDriveAuthParams');
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
$service = new \Google_Service_Drive($client);
|
||||
|
||||
// If path is not set, use the root
|
||||
if (!isset($opts['path']) || $opts['path'] === '') {
|
||||
$opts['path'] = 'root';
|
||||
}
|
||||
|
||||
$googleDrive = new GoogleDriveAdapter($service, $opts['path'], ['useHasDir' => true]);
|
||||
|
||||
$opts['fscache'] = null;
|
||||
if ($this->options['gdCacheDir'] && is_writeable($this->options['gdCacheDir'])) {
|
||||
if ($this->options['gdCacheExpire']) {
|
||||
$opts['fscache'] = new elFinderVolumeFlysystemGoogleDriveCache(new Local($this->options['gdCacheDir']), $this->options['gdCachePrefix'] . $this->netMountKey, $this->options['gdCacheExpire']);
|
||||
}
|
||||
}
|
||||
if ($opts['fscache']) {
|
||||
$filesystem = new Filesystem(new CachedAdapter($googleDrive, $opts['fscache']));
|
||||
} else {
|
||||
$filesystem = new Filesystem($googleDrive);
|
||||
}
|
||||
|
||||
$opts['driver'] = 'FlysystemExt';
|
||||
$opts['filesystem'] = $filesystem;
|
||||
$opts['separator'] = '/';
|
||||
$opts['checkSubfolders'] = true;
|
||||
if (!isset($opts['alias'])) {
|
||||
$opts['alias'] = 'GoogleDrive';
|
||||
}
|
||||
|
||||
if ($res = parent::mount($opts)) {
|
||||
// update access_token of session data
|
||||
if ($creds) {
|
||||
$netVolumes = $this->session->get('netvolume');
|
||||
$netVolumes[$this->netMountKey]['access_token'] = array_merge($netVolumes[$this->netMountKey]['access_token'], $creds);
|
||||
$this->session->set('netvolume', $netVolumes);
|
||||
}
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
protected function tmbname($stat)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* elFinder Plugin Abstract
|
||||
*
|
||||
* @package elfinder
|
||||
* @author Naoki Sawada
|
||||
* @license New BSD
|
||||
*/
|
||||
class elFinderPlugin
|
||||
{
|
||||
|
||||
/**
|
||||
* This plugin's options
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $opts = array();
|
||||
|
||||
/**
|
||||
* Get current volume's options
|
||||
*
|
||||
* @param object $volume
|
||||
*
|
||||
* @return array options
|
||||
*/
|
||||
protected function getCurrentOpts($volume)
|
||||
{
|
||||
$name = substr(get_class($this), 14); // remove "elFinderPlugin"
|
||||
$opts = $this->opts;
|
||||
if (is_object($volume)) {
|
||||
$volOpts = $volume->getOptionsPlugin($name);
|
||||
if (is_array($volOpts)) {
|
||||
$opts = array_merge($opts, $volOpts);
|
||||
}
|
||||
}
|
||||
return $opts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is enabled with options
|
||||
*
|
||||
* @param array $opts
|
||||
* @param elFinder $elfinder
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
protected function iaEnabled($opts, $elfinder = null)
|
||||
{
|
||||
if (!$opts['enable']) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// check post var 'contentSaveId' to disable this plugin
|
||||
if ($elfinder && !empty($opts['disableWithContentSaveId'])) {
|
||||
$session = $elfinder->getSession();
|
||||
$urlContentSaveIds = $session->get('urlContentSaveIds', array());
|
||||
if (!empty(elFinder::$currentArgs['contentSaveId']) && ($contentSaveId = elFinder::$currentArgs['contentSaveId'])) {
|
||||
if (!empty($urlContentSaveIds[$contentSaveId])) {
|
||||
$elfinder->removeUrlContentSaveId($contentSaveId);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($opts['onDropWith']) && !is_null($opts['onDropWith'])) {
|
||||
// plugin disabled by default, enabled only if given key is pressed
|
||||
if (isset($_REQUEST['dropWith']) && $_REQUEST['dropWith']) {
|
||||
$onDropWith = $opts['onDropWith'];
|
||||
$action = (int)$_REQUEST['dropWith'];
|
||||
if (!is_array($onDropWith)) {
|
||||
$onDropWith = array($onDropWith);
|
||||
}
|
||||
foreach ($onDropWith as $key) {
|
||||
$key = (int)$key;
|
||||
if (($action & $key) === $key) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isset($opts['offDropWith']) && !is_null($opts['offDropWith']) && isset($_REQUEST['dropWith'])) {
|
||||
// plugin enabled by default, disabled only if given key is pressed
|
||||
$offDropWith = $opts['offDropWith'];
|
||||
$action = (int)$_REQUEST['dropWith'];
|
||||
if (!is_array($offDropWith)) {
|
||||
$offDropWith = array($offDropWith);
|
||||
}
|
||||
$res = true;
|
||||
foreach ($offDropWith as $key) {
|
||||
$key = (int)$key;
|
||||
if ($key === 0) {
|
||||
if ($action === 0) {
|
||||
$res = false;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (($action & $key) === $key) {
|
||||
$res = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!$res) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,335 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* elFinder - file manager for web.
|
||||
* Session Wrapper Class.
|
||||
*
|
||||
* @package elfinder
|
||||
* @author Naoki Sawada
|
||||
**/
|
||||
|
||||
class elFinderSession implements elFinderSessionInterface
|
||||
{
|
||||
/**
|
||||
* A flag of session started
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
protected $started = false;
|
||||
|
||||
/**
|
||||
* To fix PHP bug that duplicate Set-Cookie header to be sent
|
||||
*
|
||||
* @var boolean
|
||||
* @see https://bugs.php.net/bug.php?id=75554
|
||||
*/
|
||||
protected $fixCookieRegist = false;
|
||||
|
||||
/**
|
||||
* Array of session keys of this instance
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $keys = array();
|
||||
|
||||
/**
|
||||
* Is enabled base64encode
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
protected $base64encode = false;
|
||||
|
||||
/**
|
||||
* Default options array
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $opts = array(
|
||||
'base64encode' => false,
|
||||
'keys' => array(
|
||||
'default' => 'elFinderCaches',
|
||||
'netvolume' => 'elFinderNetVolumes'
|
||||
),
|
||||
'cookieParams' => array()
|
||||
);
|
||||
|
||||
/**
|
||||
* Constractor
|
||||
*
|
||||
* @param array $opts The options
|
||||
*
|
||||
* @return self Instanse of this class
|
||||
*/
|
||||
public function __construct($opts)
|
||||
{
|
||||
$this->opts = array_merge($this->opts, $opts);
|
||||
$this->base64encode = !empty($this->opts['base64encode']);
|
||||
$this->keys = $this->opts['keys'];
|
||||
if (function_exists('apache_get_version') || $this->opts['cookieParams']) {
|
||||
$this->fixCookieRegist = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get($key, $empty = null)
|
||||
{
|
||||
$closed = false;
|
||||
if (!$this->started) {
|
||||
$closed = true;
|
||||
$this->start();
|
||||
}
|
||||
|
||||
$data = null;
|
||||
|
||||
if ($this->started) {
|
||||
$session =& $this->getSessionRef($key);
|
||||
$data = $session;
|
||||
if ($data && $this->base64encode) {
|
||||
$data = $this->decodeData($data);
|
||||
}
|
||||
}
|
||||
|
||||
$checkFn = null;
|
||||
if (!is_null($empty)) {
|
||||
if (is_string($empty)) {
|
||||
$checkFn = 'is_string';
|
||||
} elseif (is_array($empty)) {
|
||||
$checkFn = 'is_array';
|
||||
} elseif (is_object($empty)) {
|
||||
$checkFn = 'is_object';
|
||||
} elseif (is_float($empty)) {
|
||||
$checkFn = 'is_float';
|
||||
} elseif (is_int($empty)) {
|
||||
$checkFn = 'is_int';
|
||||
}
|
||||
}
|
||||
|
||||
if (is_null($data) || ($checkFn && !$checkFn($data))) {
|
||||
$session = $data = $empty;
|
||||
}
|
||||
|
||||
if ($closed) {
|
||||
$this->close();
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
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) {
|
||||
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 {
|
||||
session_start();
|
||||
}
|
||||
$this->started = session_id() ? true : false;
|
||||
|
||||
restore_error_handler();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get variable reference of $_SESSION
|
||||
*
|
||||
* @param string $key key of $_SESSION array
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
protected function & getSessionRef($key)
|
||||
{
|
||||
$session = null;
|
||||
if ($this->started) {
|
||||
list($cat, $name) = array_pad(explode('.', $key, 2), 2, null);
|
||||
if (is_null($name)) {
|
||||
if (!isset($this->keys[$cat])) {
|
||||
$name = $cat;
|
||||
$cat = 'default';
|
||||
}
|
||||
}
|
||||
if (isset($this->keys[$cat])) {
|
||||
$cat = $this->keys[$cat];
|
||||
} else {
|
||||
$name = $cat . '.' . $name;
|
||||
$cat = $this->keys['default'];
|
||||
}
|
||||
if (is_null($name)) {
|
||||
if (!isset($_SESSION[$cat])) {
|
||||
$_SESSION[$cat] = null;
|
||||
}
|
||||
$session =& $_SESSION[$cat];
|
||||
} else {
|
||||
if (!isset($_SESSION[$cat]) || !is_array($_SESSION[$cat])) {
|
||||
$_SESSION[$cat] = array();
|
||||
}
|
||||
if (!isset($_SESSION[$cat][$name])) {
|
||||
$_SESSION[$cat][$name] = null;
|
||||
}
|
||||
$session =& $_SESSION[$cat][$name];
|
||||
}
|
||||
}
|
||||
return $session;
|
||||
}
|
||||
|
||||
/**
|
||||
* base64 decode of session val
|
||||
*
|
||||
* @param $data
|
||||
*
|
||||
* @return bool|mixed|string|null
|
||||
*/
|
||||
protected function decodeData($data)
|
||||
{
|
||||
if ($this->base64encode) {
|
||||
if (is_string($data)) {
|
||||
if (($data = base64_decode($data)) !== false) {
|
||||
$data = unserialize($data);
|
||||
} else {
|
||||
$data = null;
|
||||
}
|
||||
} else {
|
||||
$data = null;
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
if ($this->started) {
|
||||
if ($this->fixCookieRegist === true) {
|
||||
// regist cookie only once for apache2 SAPI
|
||||
$cParm = session_get_cookie_params();
|
||||
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();
|
||||
}
|
||||
$this->started = false;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function set($key, $data)
|
||||
{
|
||||
$closed = false;
|
||||
if (!$this->started) {
|
||||
$closed = true;
|
||||
$this->start();
|
||||
}
|
||||
$session =& $this->getSessionRef($key);
|
||||
if ($this->base64encode) {
|
||||
$data = $this->encodeData($data);
|
||||
}
|
||||
$session = $data;
|
||||
|
||||
if ($closed) {
|
||||
$this->close();
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* base64 encode for session val
|
||||
*
|
||||
* @param $data
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function encodeData($data)
|
||||
{
|
||||
if ($this->base64encode) {
|
||||
$data = base64_encode(serialize($data));
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function remove($key)
|
||||
{
|
||||
$closed = false;
|
||||
if (!$this->started) {
|
||||
$closed = true;
|
||||
$this->start();
|
||||
}
|
||||
|
||||
list($cat, $name) = array_pad(explode('.', $key, 2), 2, null);
|
||||
if (is_null($name)) {
|
||||
if (!isset($this->keys[$cat])) {
|
||||
$name = $cat;
|
||||
$cat = 'default';
|
||||
}
|
||||
}
|
||||
if (isset($this->keys[$cat])) {
|
||||
$cat = $this->keys[$cat];
|
||||
} else {
|
||||
$name = $cat . '.' . $name;
|
||||
$cat = $this->keys['default'];
|
||||
}
|
||||
if (is_null($name)) {
|
||||
unset($_SESSION[$cat]);
|
||||
} else {
|
||||
if (isset($_SESSION[$cat]) && is_array($_SESSION[$cat])) {
|
||||
unset($_SESSION[$cat][$name]);
|
||||
}
|
||||
}
|
||||
|
||||
if ($closed) {
|
||||
$this->close();
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* sessioin error handler (Only for suppression of error at session start)
|
||||
*
|
||||
* @param $errno
|
||||
* @param $errstr
|
||||
*/
|
||||
protected function session_start_error($errno, $errstr)
|
||||
{
|
||||
}
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* elFinder - file manager for web.
|
||||
* Session Wrapper Interface.
|
||||
*
|
||||
* @package elfinder
|
||||
* @author Naoki Sawada
|
||||
**/
|
||||
|
||||
interface elFinderSessionInterface
|
||||
{
|
||||
/**
|
||||
* Session start
|
||||
*
|
||||
* @return self
|
||||
**/
|
||||
public function start();
|
||||
|
||||
/**
|
||||
* Session write & close
|
||||
*
|
||||
* @return self
|
||||
**/
|
||||
public function close();
|
||||
|
||||
/**
|
||||
* Get session data
|
||||
* This method must be equipped with an automatic start / close.
|
||||
*
|
||||
* @param string $key Target key
|
||||
* @param mixed $empty Return value of if session target key does not exist
|
||||
*
|
||||
* @return mixed
|
||||
**/
|
||||
public function get($key, $empty = '');
|
||||
|
||||
/**
|
||||
* Set session data
|
||||
* This method must be equipped with an automatic start / close.
|
||||
*
|
||||
* @param string $key Target key
|
||||
* @param mixed $data Value
|
||||
*
|
||||
* @return self
|
||||
**/
|
||||
public function set($key, $data);
|
||||
|
||||
/**
|
||||
* Get session data
|
||||
*
|
||||
* @param string $key Target key
|
||||
*
|
||||
* @return self
|
||||
**/
|
||||
public function remove($key);
|
||||
}
|
||||
+1972
File diff suppressed because it is too large
Load Diff
+7693
File diff suppressed because it is too large
Load Diff
+1464
File diff suppressed because it is too large
Load Diff
+1516
File diff suppressed because it is too large
Load Diff
+1810
File diff suppressed because it is too large
Load Diff
+2163
File diff suppressed because it is too large
Load Diff
+315
@@ -0,0 +1,315 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* elFinder driver for Volume Group.
|
||||
*
|
||||
* @author Naoki Sawada
|
||||
**/
|
||||
class elFinderVolumeGroup extends elFinderVolumeDriver
|
||||
{
|
||||
|
||||
/**
|
||||
* Driver id
|
||||
* Must be started from letter and contains [a-z0-9]
|
||||
* Used as part of volume id
|
||||
*
|
||||
* @var string
|
||||
**/
|
||||
protected $driverId = 'g';
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Extend options with required fields
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->options['type'] = 'group';
|
||||
$this->options['path'] = '/';
|
||||
$this->options['dirUrlOwn'] = true;
|
||||
$this->options['syncMinMs'] = 0;
|
||||
$this->options['tmbPath'] = '';
|
||||
$this->options['disabled'] = array(
|
||||
'archive',
|
||||
'copy',
|
||||
'cut',
|
||||
'duplicate',
|
||||
'edit',
|
||||
'empty',
|
||||
'extract',
|
||||
'getfile',
|
||||
'mkdir',
|
||||
'mkfile',
|
||||
'paste',
|
||||
'resize',
|
||||
'rm',
|
||||
'upload'
|
||||
);
|
||||
}
|
||||
|
||||
/*********************************************************************/
|
||||
/* FS API */
|
||||
/*********************************************************************/
|
||||
|
||||
/*********************** paths/urls *************************/
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
**/
|
||||
protected function _dirname($path)
|
||||
{
|
||||
return '/';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
**/
|
||||
protected function _basename($path)
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
**/
|
||||
protected function _joinPath($dir, $name)
|
||||
{
|
||||
return '/' . $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
**/
|
||||
protected function _normpath($path)
|
||||
{
|
||||
return '/';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
**/
|
||||
protected function _relpath($path)
|
||||
{
|
||||
return '/';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
**/
|
||||
protected function _abspath($path)
|
||||
{
|
||||
return '/';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
**/
|
||||
protected function _path($path)
|
||||
{
|
||||
return '/';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
**/
|
||||
protected function _inpath($path, $parent)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************** file stat ********************/
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
**/
|
||||
protected function _stat($path)
|
||||
{
|
||||
if ($path === '/') {
|
||||
return array(
|
||||
'size' => 0,
|
||||
'ts' => 0,
|
||||
'mime' => 'directory',
|
||||
'read' => true,
|
||||
'write' => false,
|
||||
'locked' => true,
|
||||
'hidden' => false,
|
||||
'dirs' => 0
|
||||
);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
**/
|
||||
protected function _subdirs($path)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
**/
|
||||
protected function _dimensions($path, $mime)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
/******************** file/dir content *********************/
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
**/
|
||||
protected function readlink($path)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
**/
|
||||
protected function _scandir($path)
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
**/
|
||||
protected function _fopen($path, $mode = 'rb')
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
**/
|
||||
protected function _fclose($fp, $path = '')
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/******************** file/dir manipulations *************************/
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
**/
|
||||
protected function _mkdir($path, $name)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
**/
|
||||
protected function _mkfile($path, $name)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
**/
|
||||
protected function _symlink($source, $targetDir, $name)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
**/
|
||||
protected function _copy($source, $targetDir, $name)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
**/
|
||||
protected function _move($source, $targetDir, $name)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
**/
|
||||
protected function _unlink($path)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
**/
|
||||
protected function _rmdir($path)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
**/
|
||||
protected function _save($fp, $dir, $name, $stat)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
**/
|
||||
protected function _getContents($path)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
**/
|
||||
protected function _filePutContents($path, $content)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
**/
|
||||
protected function _checkArchivers()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
**/
|
||||
protected function _chmod($path, $mode)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
**/
|
||||
protected function _findSymlinks($path)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
**/
|
||||
protected function _extract($path, $arc)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
**/
|
||||
protected function _archive($dir, $files, $name, $arc)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+1483
File diff suppressed because it is too large
Load Diff
+1042
File diff suppressed because it is too large
Load Diff
+2132
File diff suppressed because it is too large
Load Diff
+853
@@ -0,0 +1,853 @@
|
||||
<?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 {
|
||||
|
||||
/**
|
||||
* Simple hack that could break for quick compatibility with phpseclib version 1-3
|
||||
* Same value substitue for reference NET_SFTP_LOCAL_FILE and SFTP::SOURCE_LOCAL_FILE
|
||||
*/
|
||||
const NET_SFTP_LOCAL_FILE = 1;
|
||||
|
||||
/**
|
||||
* 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 ?: '.') ?: [];
|
||||
}
|
||||
|
||||
/*********************************************************************/
|
||||
/* 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 array $info from rawlist() output
|
||||
* @param $base
|
||||
* @param bool $nameOnly
|
||||
*
|
||||
* @return array
|
||||
* @author Dmitry Levashov
|
||||
*/
|
||||
protected function parseRaw($info, $base, $nameOnly = false)
|
||||
{
|
||||
$stat = array();
|
||||
|
||||
if ($info['filename'] == '.' || $info['filename'] == '..') {
|
||||
return false;
|
||||
}
|
||||
|
||||
$name = $info['filename'];
|
||||
//for compatability with phpseclib version 2/3
|
||||
if (empty($info['permissions'])) {
|
||||
$info['permissions'] = $info['mode'];
|
||||
}
|
||||
|
||||
if ($info['type'] === 3) {
|
||||
// check recursive processing
|
||||
if ($this->cacheDirTarget && $this->_joinPath($base, $name) !== $this->cacheDirTarget) {
|
||||
return array();
|
||||
}
|
||||
if (!$nameOnly) {
|
||||
$target = $this->connect->readlink($name);
|
||||
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;
|
||||
if ($info['type'] === NET_SFTP_TYPE_DIRECTORY) {
|
||||
$stat['mime'] = 'directory';
|
||||
$stat['size'] = 0;
|
||||
|
||||
} elseif ($info['type'] === NET_SFTP_TYPE_SYMLINK) {
|
||||
$stat['mime'] = 'symlink';
|
||||
$stat['size'] = 0;
|
||||
|
||||
} else {
|
||||
$stat['mime'] = $this->mimetype($stat['name'], true);
|
||||
$stat['size'] = $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((int)$permissions[-3]) : decbin((int)$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 $info) {
|
||||
if (($stat = $this->parseRaw($info, $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;
|
||||
} elseif (!$hasDir && $stat['mime'] === 'symlink') {
|
||||
$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 $info) {
|
||||
if ($info['filename'] === '.') {
|
||||
$info['filename'] = 'root';
|
||||
if ($stat = $this->parseRaw($info, $path)) {
|
||||
unset($stat['name']);
|
||||
$res = array_merge($res, $stat);
|
||||
if ($res['ts']) {
|
||||
$ts = 0;
|
||||
unset($check['ts']);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($check && ($stat = $this->parseRaw($info, $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;
|
||||
}
|
||||
if ($name && $name !== '.' && $name !== '..' && $info['type'] == NET_SFTP_TYPE_SYMLINK) {
|
||||
//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, self::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, self::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
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* elFinder driver for trash bin at local filesystem.
|
||||
*
|
||||
* @author NaokiSawada
|
||||
**/
|
||||
class elFinderVolumeTrash extends elFinderVolumeLocalFileSystem
|
||||
{
|
||||
/**
|
||||
* Driver id
|
||||
* Must be started from letter and contains [a-z0-9]
|
||||
* Used as part of volume id.
|
||||
*
|
||||
* @var string
|
||||
**/
|
||||
protected $driverId = 't';
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
// original option of the Trash
|
||||
$this->options['lockEverything'] = false; // Lock all items in the trash to disable delete, move, rename.
|
||||
|
||||
// common options as the volume driver
|
||||
$this->options['alias'] = 'Trash';
|
||||
$this->options['quarantine'] = '';
|
||||
$this->options['rootCssClass'] = 'elfinder-navbar-root-trash';
|
||||
$this->options['copyOverwrite'] = false;
|
||||
$this->options['uiCmdMap'] = array('paste' => 'hidden', 'mkdir' => 'hidden', 'copy' => 'restore');
|
||||
$this->options['disabled'] = array('archive', 'duplicate', 'edit', 'extract', 'mkfile', 'places', 'put', 'rename', 'resize', 'upload');
|
||||
}
|
||||
|
||||
public function mount(array $opts)
|
||||
{
|
||||
if ($this->options['lockEverything']) {
|
||||
if (!is_array($opts['attributes'])) {
|
||||
$opts['attributes'] = array();
|
||||
}
|
||||
$attr = array(
|
||||
'pattern' => '/./',
|
||||
'locked' => true,
|
||||
);
|
||||
array_unshift($opts['attributes'], $attr);
|
||||
}
|
||||
// force set `copyJoin` to true
|
||||
$opts['copyJoin'] = true;
|
||||
|
||||
return parent::mount($opts);
|
||||
}
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* elFinder driver for trash bin at MySQL Database
|
||||
*
|
||||
* @author NaokiSawada
|
||||
**/
|
||||
class elFinderVolumeTrashMySQL extends elFinderVolumeMySQL
|
||||
{
|
||||
/**
|
||||
* Driver id
|
||||
* Must be started from letter and contains [a-z0-9]
|
||||
* Used as part of volume id.
|
||||
*
|
||||
* @var string
|
||||
**/
|
||||
protected $driverId = 'tm';
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
// original option of the Trash
|
||||
$this->options['lockEverything'] = false; // Lock all items in the trash to disable delete, move, rename.
|
||||
|
||||
// common options as the volume driver
|
||||
$this->options['alias'] = 'Trash';
|
||||
$this->options['quarantine'] = '';
|
||||
$this->options['rootCssClass'] = 'elfinder-navbar-root-trash';
|
||||
$this->options['copyOverwrite'] = false;
|
||||
$this->options['uiCmdMap'] = array('paste' => 'hidden', 'mkdir' => 'hidden', 'copy' => 'restore');
|
||||
$this->options['disabled'] = array('archive', 'duplicate', 'edit', 'extract', 'mkfile', 'places', 'put', 'rename', 'resize', 'upload');
|
||||
}
|
||||
|
||||
public function mount(array $opts)
|
||||
{
|
||||
if ($this->options['lockEverything']) {
|
||||
if (!is_array($opts['attributes'])) {
|
||||
$opts['attributes'] = array();
|
||||
}
|
||||
$attr = array(
|
||||
'pattern' => '/./',
|
||||
'locked' => true,
|
||||
);
|
||||
array_unshift($opts['attributes'], $attr);
|
||||
}
|
||||
// force set `copyJoin` to true
|
||||
$opts['copyJoin'] = true;
|
||||
|
||||
return parent::mount($opts);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,473 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (c) 2011, oov. All rights reserved.
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* - Neither the name of the oov nor the names of its contributors may be used to
|
||||
* endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* bmp ファイルを GD で使えるように
|
||||
* 使用例:
|
||||
* //ファイルから読み込む場合はGDでPNGなどを読み込むのと同じような方法で可
|
||||
* $image = imagecreatefrombmp("test.bmp");
|
||||
* imagedestroy($image);
|
||||
* //文字列から読み込む場合は以下の方法で可
|
||||
* $image = GdBmp::loadFromString(file_get_contents("test.bmp"));
|
||||
* //自動判定されるので破損ファイルでなければこれでも上手くいく
|
||||
* //$image = imagecreatefrombmp(file_get_contents("test.bmp"));
|
||||
* imagedestroy($image);
|
||||
* //その他任意のストリームからの読み込みも可能
|
||||
* $stream = fopen("http://127.0.0.1/test.bmp");
|
||||
* $image = GdBmp::loadFromStream($stream);
|
||||
* //自動判定されるのでこれでもいい
|
||||
* //$image = imagecreatefrombmp($stream);
|
||||
* fclose($stream);
|
||||
* imagedestroy($image);
|
||||
* 対応フォーマット
|
||||
* 1bit
|
||||
* 4bit
|
||||
* 4bitRLE
|
||||
* 8bit
|
||||
* 8bitRLE
|
||||
* 16bit(任意のビットフィールド)
|
||||
* 24bit
|
||||
* 32bit(任意のビットフィールド)
|
||||
* BITMAPINFOHEADER の biCompression が BI_PNG / BI_JPEG の画像
|
||||
* すべての形式でトップダウン/ボトムアップの両方をサポート
|
||||
* 特殊なビットフィールドでもビットフィールドデータが正常なら読み込み可能
|
||||
* 以下のものは非対応
|
||||
* BITMAPV4HEADER と BITMAPV5HEADER に含まれる色空間に関する様々な機能
|
||||
*
|
||||
* @param $filename_or_stream_or_binary
|
||||
*
|
||||
* @return bool|resource
|
||||
*/
|
||||
|
||||
if (!function_exists('imagecreatefrombmp')) {
|
||||
function imagecreatefrombmp($filename_or_stream_or_binary)
|
||||
{
|
||||
return elFinderLibGdBmp::load($filename_or_stream_or_binary);
|
||||
}
|
||||
}
|
||||
|
||||
class elFinderLibGdBmp
|
||||
{
|
||||
public static function load($filename_or_stream_or_binary)
|
||||
{
|
||||
if (is_resource($filename_or_stream_or_binary)) {
|
||||
return self::loadFromStream($filename_or_stream_or_binary);
|
||||
} else if (is_string($filename_or_stream_or_binary) && strlen($filename_or_stream_or_binary) >= 26) {
|
||||
$bfh = unpack("vtype/Vsize", $filename_or_stream_or_binary);
|
||||
if ($bfh["type"] == 0x4d42 && ($bfh["size"] == 0 || $bfh["size"] == strlen($filename_or_stream_or_binary))) {
|
||||
return self::loadFromString($filename_or_stream_or_binary);
|
||||
}
|
||||
}
|
||||
return self::loadFromFile($filename_or_stream_or_binary);
|
||||
}
|
||||
|
||||
public static function loadFromFile($filename)
|
||||
{
|
||||
$fp = fopen($filename, "rb");
|
||||
if ($fp === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$bmp = self::loadFromStream($fp);
|
||||
|
||||
fclose($fp);
|
||||
return $bmp;
|
||||
}
|
||||
|
||||
public static function loadFromString($str)
|
||||
{
|
||||
//data scheme より古いバージョンから対応しているようなので php://memory を使う
|
||||
$fp = fopen("php://memory", "r+b");
|
||||
if ($fp === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fwrite($fp, $str) != strlen($str)) {
|
||||
fclose($fp);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fseek($fp, 0) === -1) {
|
||||
fclose($fp);
|
||||
return false;
|
||||
}
|
||||
|
||||
$bmp = self::loadFromStream($fp);
|
||||
|
||||
fclose($fp);
|
||||
return $bmp;
|
||||
}
|
||||
|
||||
public static function loadFromStream($stream)
|
||||
{
|
||||
$buf = fread($stream, 14); //2+4+2+2+4
|
||||
if ($buf === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//シグネチャチェック
|
||||
if ($buf[0] != 'B' || $buf[1] != 'M') {
|
||||
return false;
|
||||
}
|
||||
|
||||
$bitmap_file_header = unpack(
|
||||
//BITMAPFILEHEADER構造体
|
||||
"vtype/" .
|
||||
"Vsize/" .
|
||||
"vreserved1/" .
|
||||
"vreserved2/" .
|
||||
"Voffbits", $buf
|
||||
);
|
||||
|
||||
return self::loadFromStreamAndFileHeader($stream, $bitmap_file_header);
|
||||
}
|
||||
|
||||
public static function loadFromStreamAndFileHeader($stream, array $bitmap_file_header)
|
||||
{
|
||||
if ($bitmap_file_header["type"] != 0x4d42) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//情報ヘッダサイズを元に形式を区別して読み込み
|
||||
$buf = fread($stream, 4);
|
||||
if ($buf === false) {
|
||||
return false;
|
||||
}
|
||||
list(, $header_size) = unpack("V", $buf);
|
||||
|
||||
|
||||
if ($header_size == 12) {
|
||||
$buf = fread($stream, $header_size - 4);
|
||||
if ($buf === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
extract(unpack(
|
||||
//BITMAPCOREHEADER構造体 - OS/2 Bitmap
|
||||
"vwidth/" .
|
||||
"vheight/" .
|
||||
"vplanes/" .
|
||||
"vbit_count", $buf
|
||||
));
|
||||
//飛んでこない分は 0 で初期化しておく
|
||||
$clr_used = $clr_important = $alpha_mask = $compression = 0;
|
||||
|
||||
//マスク類は初期化されないのでここで割り当てておく
|
||||
$red_mask = 0x00ff0000;
|
||||
$green_mask = 0x0000ff00;
|
||||
$blue_mask = 0x000000ff;
|
||||
} else if (124 < $header_size || $header_size < 40) {
|
||||
//未知の形式
|
||||
return false;
|
||||
} else {
|
||||
//この時点で36バイト読めることまではわかっている
|
||||
$buf = fread($stream, 36); //既に読んだ部分は除外しつつBITMAPINFOHEADERのサイズだけ読む
|
||||
if ($buf === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//BITMAPINFOHEADER構造体 - Windows Bitmap
|
||||
extract(unpack(
|
||||
"Vwidth/" .
|
||||
"Vheight/" .
|
||||
"vplanes/" .
|
||||
"vbit_count/" .
|
||||
"Vcompression/" .
|
||||
"Vsize_image/" .
|
||||
"Vx_pels_per_meter/" .
|
||||
"Vy_pels_per_meter/" .
|
||||
"Vclr_used/" .
|
||||
"Vclr_important", $buf
|
||||
));
|
||||
/**
|
||||
* @var integer $width
|
||||
* @var integer $height
|
||||
* @var integer $planes
|
||||
* @var integer $bit_count
|
||||
* @var integer $compression
|
||||
* @var integer $size_image
|
||||
* @var integer $x_pels_per_meter
|
||||
* @var integer $y_pels_per_meter
|
||||
* @var integer $clr_used
|
||||
* @var integer $clr_important
|
||||
*/
|
||||
//負の整数を受け取る可能性があるものは自前で変換する
|
||||
if ($width & 0x80000000) {
|
||||
$width = -(~$width & 0xffffffff) - 1;
|
||||
}
|
||||
if ($height & 0x80000000) {
|
||||
$height = -(~$height & 0xffffffff) - 1;
|
||||
}
|
||||
if ($x_pels_per_meter & 0x80000000) {
|
||||
$x_pels_per_meter = -(~$x_pels_per_meter & 0xffffffff) - 1;
|
||||
}
|
||||
if ($y_pels_per_meter & 0x80000000) {
|
||||
$y_pels_per_meter = -(~$y_pels_per_meter & 0xffffffff) - 1;
|
||||
}
|
||||
|
||||
//ファイルによっては BITMAPINFOHEADER のサイズがおかしい(書き込み間違い?)ケースがある
|
||||
//自分でファイルサイズを元に逆算することで回避できることもあるので再計算できそうなら正当性を調べる
|
||||
//シークできないストリームの場合全体のファイルサイズは取得できないので、$bitmap_file_headerにサイズ申告がなければやらない
|
||||
if ($bitmap_file_header["size"] != 0) {
|
||||
$colorsize = $bit_count == 1 || $bit_count == 4 || $bit_count == 8 ? ($clr_used ? $clr_used : pow(2, $bit_count)) << 2 : 0;
|
||||
$bodysize = $size_image ? $size_image : ((($width * $bit_count + 31) >> 3) & ~3) * abs($height);
|
||||
$calcsize = $bitmap_file_header["size"] - $bodysize - $colorsize - 14;
|
||||
|
||||
//本来であれば一致するはずなのに合わない時は、値がおかしくなさそうなら(BITMAPV5HEADERの範囲内なら)計算して求めた値を採用する
|
||||
if ($header_size < $calcsize && 40 <= $header_size && $header_size <= 124) {
|
||||
$header_size = $calcsize;
|
||||
}
|
||||
}
|
||||
|
||||
//BITMAPV4HEADER や BITMAPV5HEADER の場合まだ読むべきデータが残っている可能性がある
|
||||
if ($header_size - 40 > 0) {
|
||||
$buf = fread($stream, $header_size - 40);
|
||||
if ($buf === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
extract(unpack(
|
||||
//BITMAPV4HEADER構造体(Windows95以降)
|
||||
//BITMAPV5HEADER構造体(Windows98/2000以降)
|
||||
"Vred_mask/" .
|
||||
"Vgreen_mask/" .
|
||||
"Vblue_mask/" .
|
||||
"Valpha_mask", $buf . str_repeat("\x00", 120)
|
||||
));
|
||||
} else {
|
||||
$alpha_mask = $red_mask = $green_mask = $blue_mask = 0;
|
||||
}
|
||||
|
||||
//パレットがないがカラーマスクもない時
|
||||
if (
|
||||
($bit_count == 16 || $bit_count == 24 || $bit_count == 32) &&
|
||||
$compression == 0 &&
|
||||
$red_mask == 0 && $green_mask == 0 && $blue_mask == 0
|
||||
) {
|
||||
//もしカラーマスクを所持していない場合は
|
||||
//規定のカラーマスクを適用する
|
||||
switch ($bit_count) {
|
||||
case 16:
|
||||
$red_mask = 0x7c00;
|
||||
$green_mask = 0x03e0;
|
||||
$blue_mask = 0x001f;
|
||||
break;
|
||||
case 24:
|
||||
case 32:
|
||||
$red_mask = 0x00ff0000;
|
||||
$green_mask = 0x0000ff00;
|
||||
$blue_mask = 0x000000ff;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
($width == 0) ||
|
||||
($height == 0) ||
|
||||
($planes != 1) ||
|
||||
(($alpha_mask & $red_mask) != 0) ||
|
||||
(($alpha_mask & $green_mask) != 0) ||
|
||||
(($alpha_mask & $blue_mask) != 0) ||
|
||||
(($red_mask & $green_mask) != 0) ||
|
||||
(($red_mask & $blue_mask) != 0) ||
|
||||
(($green_mask & $blue_mask) != 0)
|
||||
) {
|
||||
//不正な画像
|
||||
return false;
|
||||
}
|
||||
|
||||
//BI_JPEG と BI_PNG の場合は jpeg/png がそのまま入ってるだけなのでそのまま取り出してデコードする
|
||||
if ($compression == 4 || $compression == 5) {
|
||||
$buf = stream_get_contents($stream, $size_image);
|
||||
if ($buf === false) {
|
||||
return false;
|
||||
}
|
||||
return imagecreatefromstring($buf);
|
||||
}
|
||||
|
||||
//画像本体の読み出し
|
||||
//1行のバイト数
|
||||
$line_bytes = (($width * $bit_count + 31) >> 3) & ~3;
|
||||
//全体の行数
|
||||
$lines = abs($height);
|
||||
//y軸進行量(ボトムアップかトップダウンか)
|
||||
$y = $height > 0 ? $lines - 1 : 0;
|
||||
$line_step = $height > 0 ? -1 : 1;
|
||||
|
||||
//256色以下の画像か?
|
||||
if ($bit_count == 1 || $bit_count == 4 || $bit_count == 8) {
|
||||
$img = imagecreate($width, $lines);
|
||||
|
||||
//画像データの前にパレットデータがあるのでパレットを作成する
|
||||
$palette_size = $header_size == 12 ? 3 : 4; //OS/2形式の場合は x に相当する箇所のデータは最初から確保されていない
|
||||
$colors = $clr_used ? $clr_used : pow(2, $bit_count); //色数
|
||||
$palette = array();
|
||||
for ($i = 0; $i < $colors; ++$i) {
|
||||
$buf = fread($stream, $palette_size);
|
||||
if ($buf === false) {
|
||||
imagedestroy($img);
|
||||
return false;
|
||||
}
|
||||
extract(unpack("Cb/Cg/Cr/Cx", $buf . "\x00"));
|
||||
/**
|
||||
* @var integer $b
|
||||
* @var integer $g
|
||||
* @var integer $r
|
||||
* @var integer $x
|
||||
*/
|
||||
$palette[] = imagecolorallocate($img, $r, $g, $b);
|
||||
}
|
||||
|
||||
$shift_base = 8 - $bit_count;
|
||||
$mask = ((1 << $bit_count) - 1) << $shift_base;
|
||||
|
||||
//圧縮されている場合とされていない場合でデコード処理が大きく変わる
|
||||
if ($compression == 1 || $compression == 2) {
|
||||
$x = 0;
|
||||
$qrt_mod2 = $bit_count >> 2 & 1;
|
||||
for (; ;) {
|
||||
//もし描写先が範囲外になっている場合デコード処理がおかしくなっているので抜ける
|
||||
//変なデータが渡されたとしても最悪なケースで255回程度の無駄なので目を瞑る
|
||||
if ($x < -1 || $x > $width || $y < -1 || $y > $height) {
|
||||
imagedestroy($img);
|
||||
return false;
|
||||
}
|
||||
$buf = fread($stream, 1);
|
||||
if ($buf === false) {
|
||||
imagedestroy($img);
|
||||
return false;
|
||||
}
|
||||
switch ($buf) {
|
||||
case "\x00":
|
||||
$buf = fread($stream, 1);
|
||||
if ($buf === false) {
|
||||
imagedestroy($img);
|
||||
return false;
|
||||
}
|
||||
switch ($buf) {
|
||||
case "\x00": //EOL
|
||||
$y += $line_step;
|
||||
$x = 0;
|
||||
break;
|
||||
case "\x01": //EOB
|
||||
$y = 0;
|
||||
$x = 0;
|
||||
break 3;
|
||||
case "\x02": //MOV
|
||||
$buf = fread($stream, 2);
|
||||
if ($buf === false) {
|
||||
imagedestroy($img);
|
||||
return false;
|
||||
}
|
||||
list(, $xx, $yy) = unpack("C2", $buf);
|
||||
$x += $xx;
|
||||
$y += $yy * $line_step;
|
||||
break;
|
||||
default: //ABS
|
||||
list(, $pixels) = unpack("C", $buf);
|
||||
$bytes = ($pixels >> $qrt_mod2) + ($pixels & $qrt_mod2);
|
||||
$buf = fread($stream, ($bytes + 1) & ~1);
|
||||
if ($buf === false) {
|
||||
imagedestroy($img);
|
||||
return false;
|
||||
}
|
||||
for ($i = 0, $pos = 0; $i < $pixels; ++$i, ++$x, $pos += $bit_count) {
|
||||
list(, $c) = unpack("C", $buf[$pos >> 3]);
|
||||
$b = $pos & 0x07;
|
||||
imagesetpixel($img, $x, $y, $palette[($c & ($mask >> $b)) >> ($shift_base - $b)]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
$buf2 = fread($stream, 1);
|
||||
if ($buf2 === false) {
|
||||
imagedestroy($img);
|
||||
return false;
|
||||
}
|
||||
list(, $size, $c) = unpack("C2", $buf . $buf2);
|
||||
for ($i = 0, $pos = 0; $i < $size; ++$i, ++$x, $pos += $bit_count) {
|
||||
$b = $pos & 0x07;
|
||||
imagesetpixel($img, $x, $y, $palette[($c & ($mask >> $b)) >> ($shift_base - $b)]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for ($line = 0; $line < $lines; ++$line, $y += $line_step) {
|
||||
$buf = fread($stream, $line_bytes);
|
||||
if ($buf === false) {
|
||||
imagedestroy($img);
|
||||
return false;
|
||||
}
|
||||
|
||||
$pos = 0;
|
||||
for ($x = 0; $x < $width; ++$x, $pos += $bit_count) {
|
||||
list(, $c) = unpack("C", $buf[$pos >> 3]);
|
||||
$b = $pos & 0x7;
|
||||
imagesetpixel($img, $x, $y, $palette[($c & ($mask >> $b)) >> ($shift_base - $b)]);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$img = imagecreatetruecolor($width, $lines);
|
||||
imagealphablending($img, false);
|
||||
if ($alpha_mask) {
|
||||
//αデータがあるので透過情報も保存できるように
|
||||
imagesavealpha($img, true);
|
||||
}
|
||||
|
||||
//x軸進行量
|
||||
$pixel_step = $bit_count >> 3;
|
||||
$alpha_max = $alpha_mask ? 0x7f : 0x00;
|
||||
$alpha_mask_r = $alpha_mask ? 1 / $alpha_mask : 1;
|
||||
$red_mask_r = $red_mask ? 1 / $red_mask : 1;
|
||||
$green_mask_r = $green_mask ? 1 / $green_mask : 1;
|
||||
$blue_mask_r = $blue_mask ? 1 / $blue_mask : 1;
|
||||
|
||||
for ($line = 0; $line < $lines; ++$line, $y += $line_step) {
|
||||
$buf = fread($stream, $line_bytes);
|
||||
if ($buf === false) {
|
||||
imagedestroy($img);
|
||||
return false;
|
||||
}
|
||||
|
||||
$pos = 0;
|
||||
for ($x = 0; $x < $width; ++$x, $pos += $pixel_step) {
|
||||
list(, $c) = unpack("V", substr($buf, $pos, $pixel_step) . "\x00\x00");
|
||||
$a_masked = $c & $alpha_mask;
|
||||
$r_masked = $c & $red_mask;
|
||||
$g_masked = $c & $green_mask;
|
||||
$b_masked = $c & $blue_mask;
|
||||
$a = $alpha_max - ((($a_masked << 7) - $a_masked) * $alpha_mask_r);
|
||||
$r = (($r_masked << 8) - $r_masked) * $red_mask_r;
|
||||
$g = (($g_masked << 8) - $g_masked) * $green_mask_r;
|
||||
$b = (($b_masked << 8) - $b_masked) * $blue_mask_r;
|
||||
imagesetpixel($img, $x, $y, ($a << 24) | ($r << 16) | ($g << 8) | $b);
|
||||
}
|
||||
}
|
||||
imagealphablending($img, true); //デフォルト値に戻しておく
|
||||
}
|
||||
return $img;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,782 @@
|
||||
# This file maps Internet media types to unique file extension(s).
|
||||
# Although created for httpd, this file is used by many software systems
|
||||
# and has been placed in the public domain for unlimited redisribution.
|
||||
#
|
||||
# The table below contains both registered and (common) unregistered types.
|
||||
# A type that has no unique extension can be ignored -- they are listed
|
||||
# here to guide configurations toward known types and to make it easier to
|
||||
# identify "new" types. File extensions are also commonly used to indicate
|
||||
# content languages and encodings, so choose them carefully.
|
||||
#
|
||||
# Internet media types should be registered as described in RFC 4288.
|
||||
# The registry is at <http://www.iana.org/assignments/media-types/>.
|
||||
#
|
||||
# MIME type (lowercased) Extensions
|
||||
application/andrew-inset ez
|
||||
application/applixware aw
|
||||
application/atom+xml atom
|
||||
application/atomcat+xml atomcat
|
||||
application/atomsvc+xml atomsvc
|
||||
application/ccxml+xml ccxml
|
||||
application/cdmi-capability cdmia
|
||||
application/cdmi-container cdmic
|
||||
application/cdmi-domain cdmid
|
||||
application/cdmi-object cdmio
|
||||
application/cdmi-queue cdmiq
|
||||
application/cu-seeme cu
|
||||
application/davmount+xml davmount
|
||||
application/docbook+xml dbk
|
||||
application/dssc+der dssc
|
||||
application/dssc+xml xdssc
|
||||
application/ecmascript ecma
|
||||
application/emma+xml emma
|
||||
application/epub+zip epub
|
||||
application/exi exi
|
||||
application/font-tdpfr pfr
|
||||
application/gml+xml gml
|
||||
application/gpx+xml gpx
|
||||
application/gxf gxf
|
||||
application/hyperstudio stk
|
||||
application/inkml+xml ink inkml
|
||||
application/ipfix ipfix
|
||||
application/java-archive jar
|
||||
application/java-serialized-object ser
|
||||
application/java-vm class
|
||||
application/javascript js
|
||||
application/json json
|
||||
application/jsonml+json jsonml
|
||||
application/lost+xml lostxml
|
||||
application/mac-binhex40 hqx
|
||||
application/mac-compactpro cpt
|
||||
application/mads+xml mads
|
||||
application/marc mrc
|
||||
application/marcxml+xml mrcx
|
||||
application/mathematica ma nb mb
|
||||
application/mathml+xml mathml
|
||||
application/mbox mbox
|
||||
application/mediaservercontrol+xml mscml
|
||||
application/metalink+xml metalink
|
||||
application/metalink4+xml meta4
|
||||
application/mets+xml mets
|
||||
application/mods+xml mods
|
||||
application/mp21 m21 mp21
|
||||
application/mp4 mp4s
|
||||
application/msword doc dot
|
||||
application/mxf mxf
|
||||
application/octet-stream bin dms lrf mar so dist distz pkg bpk dump elc deploy
|
||||
application/oda oda
|
||||
application/oebps-package+xml opf
|
||||
application/ogg ogx
|
||||
application/omdoc+xml omdoc
|
||||
application/onenote onetoc onetoc2 onetmp onepkg
|
||||
application/oxps oxps
|
||||
application/patch-ops-error+xml xer
|
||||
application/pdf pdf
|
||||
application/pgp-encrypted pgp
|
||||
application/pgp-signature asc sig
|
||||
application/pics-rules prf
|
||||
application/pkcs10 p10
|
||||
application/pkcs7-mime p7m p7c
|
||||
application/pkcs7-signature p7s
|
||||
application/pkcs8 p8
|
||||
application/pkix-attr-cert ac
|
||||
application/pkix-cert cer
|
||||
application/pkix-crl crl
|
||||
application/pkix-pkipath pkipath
|
||||
application/pkixcmp pki
|
||||
application/pls+xml pls
|
||||
application/postscript ai eps ps
|
||||
application/prs.cww cww
|
||||
application/pskc+xml pskcxml
|
||||
application/rdf+xml rdf
|
||||
application/reginfo+xml rif
|
||||
application/relax-ng-compact-syntax rnc
|
||||
application/resource-lists+xml rl
|
||||
application/resource-lists-diff+xml rld
|
||||
application/rls-services+xml rs
|
||||
application/rpki-ghostbusters gbr
|
||||
application/rpki-manifest mft
|
||||
application/rpki-roa roa
|
||||
application/rsd+xml rsd
|
||||
application/rss+xml rss
|
||||
application/rtf rtf
|
||||
application/sbml+xml sbml
|
||||
application/scvp-cv-request scq
|
||||
application/scvp-cv-response scs
|
||||
application/scvp-vp-request spq
|
||||
application/scvp-vp-response spp
|
||||
application/sdp sdp
|
||||
application/set-payment-initiation setpay
|
||||
application/set-registration-initiation setreg
|
||||
application/shf+xml shf
|
||||
application/smil+xml smi smil
|
||||
application/sparql-query rq
|
||||
application/sparql-results+xml srx
|
||||
application/srgs gram
|
||||
application/srgs+xml grxml
|
||||
application/sru+xml sru
|
||||
application/ssdl+xml ssdl
|
||||
application/ssml+xml ssml
|
||||
application/tei+xml tei teicorpus
|
||||
application/thraud+xml tfi
|
||||
application/timestamped-data tsd
|
||||
application/vnd.3gpp.pic-bw-large plb
|
||||
application/vnd.3gpp.pic-bw-small psb
|
||||
application/vnd.3gpp.pic-bw-var pvb
|
||||
application/vnd.3gpp2.tcap tcap
|
||||
application/vnd.3m.post-it-notes pwn
|
||||
application/vnd.accpac.simply.aso aso
|
||||
application/vnd.accpac.simply.imp imp
|
||||
application/vnd.acucobol acu
|
||||
application/vnd.acucorp atc acutc
|
||||
application/vnd.adobe.air-application-installer-package+zip air
|
||||
application/vnd.adobe.formscentral.fcdt fcdt
|
||||
application/vnd.adobe.fxp fxp fxpl
|
||||
application/vnd.adobe.xdp+xml xdp
|
||||
application/vnd.adobe.xfdf xfdf
|
||||
application/vnd.ahead.space ahead
|
||||
application/vnd.airzip.filesecure.azf azf
|
||||
application/vnd.airzip.filesecure.azs azs
|
||||
application/vnd.amazon.ebook azw
|
||||
application/vnd.americandynamics.acc acc
|
||||
application/vnd.amiga.ami ami
|
||||
application/vnd.android.package-archive apk
|
||||
application/vnd.anser-web-certificate-issue-initiation cii
|
||||
application/vnd.anser-web-funds-transfer-initiation fti
|
||||
application/vnd.antix.game-component atx
|
||||
application/vnd.apple.installer+xml mpkg
|
||||
application/vnd.apple.mpegurl m3u8
|
||||
application/vnd.aristanetworks.swi swi
|
||||
application/vnd.astraea-software.iota iota
|
||||
application/vnd.audiograph aep
|
||||
application/vnd.blueice.multipass mpm
|
||||
application/vnd.bmi bmi
|
||||
application/vnd.businessobjects rep
|
||||
application/vnd.chemdraw+xml cdxml
|
||||
application/vnd.chipnuts.karaoke-mmd mmd
|
||||
application/vnd.cinderella cdy
|
||||
application/vnd.claymore cla
|
||||
application/vnd.cloanto.rp9 rp9
|
||||
application/vnd.clonk.c4group c4g c4d c4f c4p c4u
|
||||
application/vnd.cluetrust.cartomobile-config c11amc
|
||||
application/vnd.cluetrust.cartomobile-config-pkg c11amz
|
||||
application/vnd.commonspace csp
|
||||
application/vnd.contact.cmsg cdbcmsg
|
||||
application/vnd.cosmocaller cmc
|
||||
application/vnd.crick.clicker clkx
|
||||
application/vnd.crick.clicker.keyboard clkk
|
||||
application/vnd.crick.clicker.palette clkp
|
||||
application/vnd.crick.clicker.template clkt
|
||||
application/vnd.crick.clicker.wordbank clkw
|
||||
application/vnd.criticaltools.wbs+xml wbs
|
||||
application/vnd.ctc-posml pml
|
||||
application/vnd.cups-ppd ppd
|
||||
application/vnd.curl.car car
|
||||
application/vnd.curl.pcurl pcurl
|
||||
application/vnd.dart dart
|
||||
application/vnd.data-vision.rdz rdz
|
||||
application/vnd.dece.data uvf uvvf uvd uvvd
|
||||
application/vnd.dece.ttml+xml uvt uvvt
|
||||
application/vnd.dece.unspecified uvx uvvx
|
||||
application/vnd.dece.zip uvz uvvz
|
||||
application/vnd.denovo.fcselayout-link fe_launch
|
||||
application/vnd.dna dna
|
||||
application/vnd.dolby.mlp mlp
|
||||
application/vnd.dpgraph dpg
|
||||
application/vnd.dreamfactory dfac
|
||||
application/vnd.ds-keypoint kpxx
|
||||
application/vnd.dvb.ait ait
|
||||
application/vnd.dvb.service svc
|
||||
application/vnd.dynageo geo
|
||||
application/vnd.ecowin.chart mag
|
||||
application/vnd.enliven nml
|
||||
application/vnd.epson.esf esf
|
||||
application/vnd.epson.msf msf
|
||||
application/vnd.epson.quickanime qam
|
||||
application/vnd.epson.salt slt
|
||||
application/vnd.epson.ssf ssf
|
||||
application/vnd.eszigno3+xml es3 et3
|
||||
application/vnd.ezpix-album ez2
|
||||
application/vnd.ezpix-package ez3
|
||||
application/vnd.fdf fdf
|
||||
application/vnd.fdsn.mseed mseed
|
||||
application/vnd.fdsn.seed seed dataless
|
||||
application/vnd.flographit gph
|
||||
application/vnd.fluxtime.clip ftc
|
||||
application/vnd.framemaker fm frame maker book
|
||||
application/vnd.frogans.fnc fnc
|
||||
application/vnd.frogans.ltf ltf
|
||||
application/vnd.fsc.weblaunch fsc
|
||||
application/vnd.fujitsu.oasys oas
|
||||
application/vnd.fujitsu.oasys2 oa2
|
||||
application/vnd.fujitsu.oasys3 oa3
|
||||
application/vnd.fujitsu.oasysgp fg5
|
||||
application/vnd.fujitsu.oasysprs bh2
|
||||
application/vnd.fujixerox.ddd ddd
|
||||
application/vnd.fujixerox.docuworks xdw
|
||||
application/vnd.fujixerox.docuworks.binder xbd
|
||||
application/vnd.fuzzysheet fzs
|
||||
application/vnd.genomatix.tuxedo txd
|
||||
application/vnd.geogebra.file ggb
|
||||
application/vnd.geogebra.tool ggt
|
||||
application/vnd.geometry-explorer gex gre
|
||||
application/vnd.geonext gxt
|
||||
application/vnd.geoplan g2w
|
||||
application/vnd.geospace g3w
|
||||
application/vnd.gmx gmx
|
||||
application/vnd.google-earth.kml+xml kml
|
||||
application/vnd.google-earth.kmz kmz
|
||||
application/vnd.grafeq gqf gqs
|
||||
application/vnd.groove-account gac
|
||||
application/vnd.groove-help ghf
|
||||
application/vnd.groove-identity-message gim
|
||||
application/vnd.groove-injector grv
|
||||
application/vnd.groove-tool-message gtm
|
||||
application/vnd.groove-tool-template tpl
|
||||
application/vnd.groove-vcard vcg
|
||||
application/vnd.hal+xml hal
|
||||
application/vnd.handheld-entertainment+xml zmm
|
||||
application/vnd.hbci hbci
|
||||
application/vnd.hhe.lesson-player les
|
||||
application/vnd.hp-hpgl hpgl
|
||||
application/vnd.hp-hpid hpid
|
||||
application/vnd.hp-hps hps
|
||||
application/vnd.hp-jlyt jlt
|
||||
application/vnd.hp-pcl pcl
|
||||
application/vnd.hp-pclxl pclxl
|
||||
application/vnd.hydrostatix.sof-data sfd-hdstx
|
||||
application/vnd.ibm.minipay mpy
|
||||
application/vnd.ibm.modcap afp listafp list3820
|
||||
application/vnd.ibm.rights-management irm
|
||||
application/vnd.ibm.secure-container sc
|
||||
application/vnd.iccprofile icc icm
|
||||
application/vnd.igloader igl
|
||||
application/vnd.immervision-ivp ivp
|
||||
application/vnd.immervision-ivu ivu
|
||||
application/vnd.insors.igm igm
|
||||
application/vnd.intercon.formnet xpw xpx
|
||||
application/vnd.intergeo i2g
|
||||
application/vnd.intu.qbo qbo
|
||||
application/vnd.intu.qfx qfx
|
||||
application/vnd.ipunplugged.rcprofile rcprofile
|
||||
application/vnd.irepository.package+xml irp
|
||||
application/vnd.is-xpr xpr
|
||||
application/vnd.isac.fcs fcs
|
||||
application/vnd.jam jam
|
||||
application/vnd.jcp.javame.midlet-rms rms
|
||||
application/vnd.jisp jisp
|
||||
application/vnd.joost.joda-archive joda
|
||||
application/vnd.kahootz ktz ktr
|
||||
application/vnd.kde.karbon karbon
|
||||
application/vnd.kde.kchart chrt
|
||||
application/vnd.kde.kformula kfo
|
||||
application/vnd.kde.kivio flw
|
||||
application/vnd.kde.kontour kon
|
||||
application/vnd.kde.kpresenter kpr kpt
|
||||
application/vnd.kde.kspread ksp
|
||||
application/vnd.kde.kword kwd kwt
|
||||
application/vnd.kenameaapp htke
|
||||
application/vnd.kidspiration kia
|
||||
application/vnd.kinar kne knp
|
||||
application/vnd.koan skp skd skt skm
|
||||
application/vnd.kodak-descriptor sse
|
||||
application/vnd.las.las+xml lasxml
|
||||
application/vnd.llamagraphics.life-balance.desktop lbd
|
||||
application/vnd.llamagraphics.life-balance.exchange+xml lbe
|
||||
application/vnd.lotus-1-2-3 123
|
||||
application/vnd.lotus-approach apr
|
||||
application/vnd.lotus-freelance pre
|
||||
application/vnd.lotus-notes nsf
|
||||
application/vnd.lotus-organizer org
|
||||
application/vnd.lotus-screencam scm
|
||||
application/vnd.lotus-wordpro lwp
|
||||
application/vnd.macports.portpkg portpkg
|
||||
application/vnd.mcd mcd
|
||||
application/vnd.medcalcdata mc1
|
||||
application/vnd.mediastation.cdkey cdkey
|
||||
application/vnd.mfer mwf
|
||||
application/vnd.mfmp mfm
|
||||
application/vnd.micrografx.flo flo
|
||||
application/vnd.micrografx.igx igx
|
||||
application/vnd.mif mif
|
||||
application/vnd.mobius.daf daf
|
||||
application/vnd.mobius.dis dis
|
||||
application/vnd.mobius.mbk mbk
|
||||
application/vnd.mobius.mqy mqy
|
||||
application/vnd.mobius.msl msl
|
||||
application/vnd.mobius.plc plc
|
||||
application/vnd.mobius.txf txf
|
||||
application/vnd.mophun.application mpn
|
||||
application/vnd.mophun.certificate mpc
|
||||
application/vnd.mozilla.xul+xml xul
|
||||
application/vnd.ms-artgalry cil
|
||||
application/vnd.ms-cab-compressed cab
|
||||
application/vnd.ms-excel xls xlm xla xlc xlt xlw
|
||||
application/vnd.ms-excel.addin.macroenabled.12 xlam
|
||||
application/vnd.ms-excel.sheet.binary.macroenabled.12 xlsb
|
||||
application/vnd.ms-excel.sheet.macroenabled.12 xlsm
|
||||
application/vnd.ms-excel.template.macroenabled.12 xltm
|
||||
application/vnd.ms-fontobject eot
|
||||
application/vnd.ms-htmlhelp chm
|
||||
application/vnd.ms-ims ims
|
||||
application/vnd.ms-lrm lrm
|
||||
application/vnd.ms-officetheme thmx
|
||||
application/vnd.ms-outlook msg
|
||||
application/vnd.ms-pki.seccat cat
|
||||
application/vnd.ms-pki.stl stl
|
||||
application/vnd.ms-powerpoint ppt pps pot
|
||||
application/vnd.ms-powerpoint.addin.macroenabled.12 ppam
|
||||
application/vnd.ms-powerpoint.presentation.macroenabled.12 pptm
|
||||
application/vnd.ms-powerpoint.slide.macroenabled.12 sldm
|
||||
application/vnd.ms-powerpoint.slideshow.macroenabled.12 ppsm
|
||||
application/vnd.ms-powerpoint.template.macroenabled.12 potm
|
||||
application/vnd.ms-project mpp mpt
|
||||
application/vnd.ms-word.document.macroenabled.12 docm
|
||||
application/vnd.ms-word.template.macroenabled.12 dotm
|
||||
application/vnd.ms-works wps wks wcm wdb
|
||||
application/vnd.ms-wpl wpl
|
||||
application/vnd.ms-xpsdocument xps
|
||||
application/vnd.mseq mseq
|
||||
application/vnd.musician mus
|
||||
application/vnd.muvee.style msty
|
||||
application/vnd.mynfc taglet
|
||||
application/vnd.neurolanguage.nlu nlu
|
||||
application/vnd.nitf ntf nitf
|
||||
application/vnd.noblenet-directory nnd
|
||||
application/vnd.noblenet-sealer nns
|
||||
application/vnd.noblenet-web nnw
|
||||
application/vnd.nokia.n-gage.data ngdat
|
||||
application/vnd.nokia.n-gage.symbian.install n-gage
|
||||
application/vnd.nokia.radio-preset rpst
|
||||
application/vnd.nokia.radio-presets rpss
|
||||
application/vnd.novadigm.edm edm
|
||||
application/vnd.novadigm.edx edx
|
||||
application/vnd.novadigm.ext ext
|
||||
application/vnd.oasis.opendocument.chart odc
|
||||
application/vnd.oasis.opendocument.chart-template otc
|
||||
application/vnd.oasis.opendocument.database odb
|
||||
application/vnd.oasis.opendocument.formula odf
|
||||
application/vnd.oasis.opendocument.formula-template odft
|
||||
application/vnd.oasis.opendocument.graphics odg
|
||||
application/vnd.oasis.opendocument.graphics-template otg
|
||||
application/vnd.oasis.opendocument.image odi
|
||||
application/vnd.oasis.opendocument.image-template oti
|
||||
application/vnd.oasis.opendocument.presentation odp
|
||||
application/vnd.oasis.opendocument.presentation-template otp
|
||||
application/vnd.oasis.opendocument.spreadsheet ods
|
||||
application/vnd.oasis.opendocument.spreadsheet-template ots
|
||||
application/vnd.oasis.opendocument.text odt
|
||||
application/vnd.oasis.opendocument.text-master odm
|
||||
application/vnd.oasis.opendocument.text-template ott
|
||||
application/vnd.oasis.opendocument.text-web oth
|
||||
application/vnd.olpc-sugar xo
|
||||
application/vnd.oma.dd2+xml dd2
|
||||
application/vnd.openofficeorg.extension oxt
|
||||
application/vnd.openxmlformats-officedocument.presentationml.presentation pptx
|
||||
application/vnd.openxmlformats-officedocument.presentationml.slide sldx
|
||||
application/vnd.openxmlformats-officedocument.presentationml.slideshow ppsx
|
||||
application/vnd.openxmlformats-officedocument.presentationml.template potx
|
||||
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx
|
||||
application/vnd.openxmlformats-officedocument.spreadsheetml.template xltx
|
||||
application/vnd.openxmlformats-officedocument.wordprocessingml.document docx
|
||||
application/vnd.openxmlformats-officedocument.wordprocessingml.template dotx
|
||||
application/vnd.osgeo.mapguide.package mgp
|
||||
application/vnd.osgi.dp dp
|
||||
application/vnd.osgi.subsystem esa
|
||||
application/vnd.palm pdb pqa oprc
|
||||
application/vnd.pawaafile paw
|
||||
application/vnd.pg.format str
|
||||
application/vnd.pg.osasli ei6
|
||||
application/vnd.picsel efif
|
||||
application/vnd.pmi.widget wg
|
||||
application/vnd.pocketlearn plf
|
||||
application/vnd.powerbuilder6 pbd
|
||||
application/vnd.previewsystems.box box
|
||||
application/vnd.proteus.magazine mgz
|
||||
application/vnd.publishare-delta-tree qps
|
||||
application/vnd.pvi.ptid1 ptid
|
||||
application/vnd.quark.quarkxpress qxd qxt qwd qwt qxl qxb
|
||||
application/vnd.realvnc.bed bed
|
||||
application/vnd.recordare.musicxml mxl
|
||||
application/vnd.recordare.musicxml+xml musicxml
|
||||
application/vnd.rig.cryptonote cryptonote
|
||||
application/vnd.rim.cod cod
|
||||
application/vnd.rn-realmedia rm
|
||||
application/vnd.rn-realmedia-vbr rmvb
|
||||
application/vnd.route66.link66+xml link66
|
||||
application/vnd.sailingtracker.track st
|
||||
application/vnd.seemail see
|
||||
application/vnd.sema sema
|
||||
application/vnd.semd semd
|
||||
application/vnd.semf semf
|
||||
application/vnd.shana.informed.formdata ifm
|
||||
application/vnd.shana.informed.formtemplate itp
|
||||
application/vnd.shana.informed.interchange iif
|
||||
application/vnd.shana.informed.package ipk
|
||||
application/vnd.simtech-mindmapper twd twds
|
||||
application/vnd.smaf mmf
|
||||
application/vnd.smart.teacher teacher
|
||||
application/vnd.solent.sdkm+xml sdkm sdkd
|
||||
application/vnd.spotfire.dxp dxp
|
||||
application/vnd.spotfire.sfs sfs
|
||||
application/vnd.stardivision.calc sdc
|
||||
application/vnd.stardivision.draw sda
|
||||
application/vnd.stardivision.impress sdd
|
||||
application/vnd.stardivision.math smf
|
||||
application/vnd.stardivision.writer sdw vor
|
||||
application/vnd.stardivision.writer-global sgl
|
||||
application/vnd.stepmania.package smzip
|
||||
application/vnd.stepmania.stepchart sm
|
||||
application/vnd.sun.xml.calc sxc
|
||||
application/vnd.sun.xml.calc.template stc
|
||||
application/vnd.sun.xml.draw sxd
|
||||
application/vnd.sun.xml.draw.template std
|
||||
application/vnd.sun.xml.impress sxi
|
||||
application/vnd.sun.xml.impress.template sti
|
||||
application/vnd.sun.xml.math sxm
|
||||
application/vnd.sun.xml.writer sxw
|
||||
application/vnd.sun.xml.writer.global sxg
|
||||
application/vnd.sun.xml.writer.template stw
|
||||
application/vnd.sus-calendar sus susp
|
||||
application/vnd.svd svd
|
||||
application/vnd.symbian.install sis sisx
|
||||
application/vnd.syncml+xml xsm
|
||||
application/vnd.syncml.dm+wbxml bdm
|
||||
application/vnd.syncml.dm+xml xdm
|
||||
application/vnd.tao.intent-module-archive tao
|
||||
application/vnd.tcpdump.pcap pcap cap dmp
|
||||
application/vnd.tmobile-livetv tmo
|
||||
application/vnd.trid.tpt tpt
|
||||
application/vnd.triscape.mxs mxs
|
||||
application/vnd.trueapp tra
|
||||
application/vnd.ufdl ufd ufdl
|
||||
application/vnd.uiq.theme utz
|
||||
application/vnd.umajin umj
|
||||
application/vnd.unity unityweb
|
||||
application/vnd.uoml+xml uoml
|
||||
application/vnd.vcx vcx
|
||||
application/vnd.visio vsd vst vss vsw
|
||||
application/vnd.visionary vis
|
||||
application/vnd.vsf vsf
|
||||
application/vnd.wap.wbxml wbxml
|
||||
application/vnd.wap.wmlc wmlc
|
||||
application/vnd.wap.wmlscriptc wmlsc
|
||||
application/vnd.webturbo wtb
|
||||
application/vnd.wolfram.player nbp
|
||||
application/vnd.wordperfect wpd
|
||||
application/vnd.wqd wqd
|
||||
application/vnd.wt.stf stf
|
||||
application/vnd.xara xar
|
||||
application/vnd.xfdl xfdl
|
||||
application/vnd.yamaha.hv-dic hvd
|
||||
application/vnd.yamaha.hv-script hvs
|
||||
application/vnd.yamaha.hv-voice hvp
|
||||
application/vnd.yamaha.openscoreformat osf
|
||||
application/vnd.yamaha.openscoreformat.osfpvg+xml osfpvg
|
||||
application/vnd.yamaha.smaf-audio saf
|
||||
application/vnd.yamaha.smaf-phrase spf
|
||||
application/vnd.yellowriver-custom-menu cmp
|
||||
application/vnd.zul zir zirz
|
||||
application/vnd.zzazz.deck+xml zaz
|
||||
application/voicexml+xml vxml
|
||||
application/widget wgt
|
||||
application/winhlp hlp
|
||||
application/wsdl+xml wsdl
|
||||
application/wspolicy+xml wspolicy
|
||||
application/x-7z-compressed 7z
|
||||
application/x-abiword abw
|
||||
application/x-ace-compressed ace
|
||||
application/x-apple-diskimage dmg
|
||||
application/x-authorware-bin aab x32 u32 vox
|
||||
application/x-authorware-map aam
|
||||
application/x-authorware-seg aas
|
||||
application/x-bcpio bcpio
|
||||
application/x-bittorrent torrent
|
||||
application/x-blorb blb blorb
|
||||
application/x-bzip bz
|
||||
application/x-bzip2 bz2 boz
|
||||
application/x-cbr cbr cba cbt cbz cb7
|
||||
application/x-cdlink vcd
|
||||
application/x-cfs-compressed cfs
|
||||
application/x-chat chat
|
||||
application/x-chess-pgn pgn
|
||||
application/x-conference nsc
|
||||
application/x-cpio cpio
|
||||
application/x-csh csh
|
||||
application/x-debian-package deb udeb
|
||||
application/x-dgc-compressed dgc
|
||||
application/x-director dir dcr dxr cst cct cxt w3d fgd swa
|
||||
application/x-doom wad
|
||||
application/x-dtbncx+xml ncx
|
||||
application/x-dtbook+xml dtb
|
||||
application/x-dtbresource+xml res
|
||||
application/x-dvi dvi
|
||||
application/x-envoy evy
|
||||
application/x-eva eva
|
||||
application/x-font-bdf bdf
|
||||
application/x-font-ghostscript gsf
|
||||
application/x-font-linux-psf psf
|
||||
application/x-font-pcf pcf
|
||||
application/x-font-snf snf
|
||||
application/x-font-type1 pfa pfb pfm afm
|
||||
application/x-freearc arc
|
||||
application/x-futuresplash spl
|
||||
application/x-gca-compressed gca
|
||||
application/x-glulx ulx
|
||||
application/x-gnumeric gnumeric
|
||||
application/x-gramps-xml gramps
|
||||
application/x-gtar gtar
|
||||
application/x-hdf hdf
|
||||
application/x-install-instructions install
|
||||
application/x-iso9660-image iso
|
||||
application/x-java-jnlp-file jnlp
|
||||
application/x-latex latex
|
||||
application/x-lzh-compressed lzh lha
|
||||
application/x-mie mie
|
||||
application/x-mobipocket-ebook prc mobi
|
||||
application/x-ms-application application
|
||||
application/x-ms-shortcut lnk
|
||||
application/x-ms-wmd wmd
|
||||
application/x-ms-wmz wmz
|
||||
application/x-ms-xbap xbap
|
||||
application/x-msaccess mdb
|
||||
application/x-msbinder obd
|
||||
application/x-mscardfile crd
|
||||
application/x-msclip clp
|
||||
application/x-msdownload exe dll com bat msi
|
||||
application/x-msmediaview mvb m13 m14
|
||||
application/x-msmetafile wmf wmz emf emz
|
||||
application/x-msmoney mny
|
||||
application/x-mspublisher pub
|
||||
application/x-msschedule scd
|
||||
application/x-msterminal trm
|
||||
application/x-mswrite wri
|
||||
application/x-netcdf nc cdf
|
||||
application/x-nzb nzb
|
||||
application/x-pkcs12 p12 pfx
|
||||
application/x-pkcs7-certificates p7b spc
|
||||
application/x-pkcs7-certreqresp p7r
|
||||
application/x-rar-compressed rar
|
||||
application/x-research-info-systems ris
|
||||
application/x-sh sh
|
||||
application/x-shar shar
|
||||
application/x-shockwave-flash swf
|
||||
application/x-silverlight-app xap
|
||||
application/x-sql sql
|
||||
application/x-stuffit sit
|
||||
application/x-stuffitx sitx
|
||||
application/x-subrip srt
|
||||
application/x-sv4cpio sv4cpio
|
||||
application/x-sv4crc sv4crc
|
||||
application/x-t3vm-image t3
|
||||
application/x-tads gam
|
||||
application/x-tar tar
|
||||
application/x-tcl tcl
|
||||
application/x-tex tex
|
||||
application/x-tex-tfm tfm
|
||||
application/x-texinfo texinfo texi
|
||||
application/x-tgif obj
|
||||
application/x-ustar ustar
|
||||
application/x-wais-source src
|
||||
application/x-x509-ca-cert der crt
|
||||
application/x-xfig fig
|
||||
application/x-xliff+xml xlf
|
||||
application/x-xpinstall xpi
|
||||
application/x-xz xz
|
||||
application/x-zmachine z1 z2 z3 z4 z5 z6 z7 z8
|
||||
application/xaml+xml xaml
|
||||
application/xcap-diff+xml xdf
|
||||
application/xenc+xml xenc
|
||||
application/xhtml+xml xhtml xht
|
||||
application/xml xml xsl
|
||||
application/xml-dtd dtd
|
||||
application/xop+xml xop
|
||||
application/xproc+xml xpl
|
||||
application/xslt+xml xslt
|
||||
application/xspf+xml xspf
|
||||
application/xv+xml mxml xhvml xvml xvm
|
||||
application/yang yang
|
||||
application/yin+xml yin
|
||||
application/zip zip
|
||||
audio/adpcm adp
|
||||
audio/basic au snd
|
||||
audio/midi mid midi kar rmi
|
||||
audio/mp4 m4a mp4a
|
||||
audio/mpeg mpga mp2 mp2a mp3 m2a m3a
|
||||
audio/ogg oga ogg spx
|
||||
audio/s3m s3m
|
||||
audio/silk sil
|
||||
audio/vnd.dece.audio uva uvva
|
||||
audio/vnd.digital-winds eol
|
||||
audio/vnd.dra dra
|
||||
audio/vnd.dts dts
|
||||
audio/vnd.dts.hd dtshd
|
||||
audio/vnd.lucent.voice lvp
|
||||
audio/vnd.ms-playready.media.pya pya
|
||||
audio/vnd.nuera.ecelp4800 ecelp4800
|
||||
audio/vnd.nuera.ecelp7470 ecelp7470
|
||||
audio/vnd.nuera.ecelp9600 ecelp9600
|
||||
audio/vnd.rip rip
|
||||
audio/webm weba
|
||||
audio/x-aac aac
|
||||
audio/x-aiff aif aiff aifc
|
||||
audio/x-caf caf
|
||||
audio/x-flac flac
|
||||
audio/x-matroska mka
|
||||
audio/x-mpegurl m3u
|
||||
audio/x-ms-wax wax
|
||||
audio/x-ms-wma wma
|
||||
audio/x-pn-realaudio ram ra
|
||||
audio/x-pn-realaudio-plugin rmp
|
||||
audio/x-wav wav
|
||||
audio/xm xm
|
||||
chemical/x-cdx cdx
|
||||
chemical/x-cif cif
|
||||
chemical/x-cmdf cmdf
|
||||
chemical/x-cml cml
|
||||
chemical/x-csml csml
|
||||
chemical/x-xyz xyz
|
||||
font/collection ttc
|
||||
font/otf otf
|
||||
font/ttf ttf
|
||||
font/woff woff
|
||||
font/woff2 woff2
|
||||
image/bmp bmp
|
||||
image/cgm cgm
|
||||
image/g3fax g3
|
||||
image/gif gif
|
||||
image/ief ief
|
||||
image/jpeg jpeg jpg jpe
|
||||
image/ktx ktx
|
||||
image/png png
|
||||
image/prs.btif btif
|
||||
image/sgi sgi
|
||||
image/svg+xml svg svgz
|
||||
image/tiff tiff tif
|
||||
image/vnd.adobe.photoshop psd
|
||||
image/vnd.dece.graphic uvi uvvi uvg uvvg
|
||||
image/vnd.djvu djvu djv
|
||||
image/vnd.dvb.subtitle sub
|
||||
image/vnd.dwg dwg
|
||||
image/vnd.dxf dxf
|
||||
image/vnd.fastbidsheet fbs
|
||||
image/vnd.fpx fpx
|
||||
image/vnd.fst fst
|
||||
image/vnd.fujixerox.edmics-mmr mmr
|
||||
image/vnd.fujixerox.edmics-rlc rlc
|
||||
image/vnd.ms-modi mdi
|
||||
image/vnd.ms-photo wdp
|
||||
image/vnd.net-fpx npx
|
||||
image/vnd.wap.wbmp wbmp
|
||||
image/vnd.xiff xif
|
||||
image/webp webp
|
||||
image/x-3ds 3ds
|
||||
image/x-cmu-raster ras
|
||||
image/x-cmx cmx
|
||||
image/x-freehand fh fhc fh4 fh5 fh7
|
||||
image/x-icon ico
|
||||
image/x-mrsid-image sid
|
||||
image/x-pcx pcx
|
||||
image/x-pict pic pct
|
||||
image/x-portable-anymap pnm
|
||||
image/x-portable-bitmap pbm
|
||||
image/x-portable-graymap pgm
|
||||
image/x-portable-pixmap ppm
|
||||
image/x-rgb rgb
|
||||
image/x-tga tga
|
||||
image/x-xbitmap xbm
|
||||
image/x-xpixmap xpm
|
||||
image/x-xwindowdump xwd
|
||||
message/rfc822 eml mime
|
||||
model/iges igs iges
|
||||
model/mesh msh mesh silo
|
||||
model/vnd.collada+xml dae
|
||||
model/vnd.dwf dwf
|
||||
model/vnd.gdl gdl
|
||||
model/vnd.gtw gtw
|
||||
model/vnd.mts mts
|
||||
model/vnd.vtu vtu
|
||||
model/vrml wrl vrml
|
||||
model/x3d+binary x3db x3dbz
|
||||
model/x3d+vrml x3dv x3dvz
|
||||
model/x3d+xml x3d x3dz
|
||||
text/cache-manifest appcache
|
||||
text/calendar ics ifb
|
||||
text/css css
|
||||
text/csv csv
|
||||
text/html html htm
|
||||
text/n3 n3
|
||||
text/plain txt text conf def list log in
|
||||
text/prs.lines.tag dsc
|
||||
text/richtext rtx
|
||||
text/sgml sgml sgm
|
||||
text/tab-separated-values tsv
|
||||
text/troff t tr roff man me ms
|
||||
text/turtle ttl
|
||||
text/uri-list uri uris urls
|
||||
text/vcard vcard
|
||||
text/vnd.curl curl
|
||||
text/vnd.curl.dcurl dcurl
|
||||
text/vnd.curl.mcurl mcurl
|
||||
text/vnd.curl.scurl scurl
|
||||
text/vnd.dvb.subtitle sub
|
||||
text/vnd.fly fly
|
||||
text/vnd.fmi.flexstor flx
|
||||
text/vnd.graphviz gv
|
||||
text/vnd.in3d.3dml 3dml
|
||||
text/vnd.in3d.spot spot
|
||||
text/vnd.sun.j2me.app-descriptor jad
|
||||
text/vnd.wap.wml wml
|
||||
text/vnd.wap.wmlscript wmls
|
||||
text/x-asm s asm
|
||||
text/x-c c cc cxx cpp h hh dic
|
||||
text/x-fortran f for f77 f90
|
||||
text/x-java-source java
|
||||
text/x-nfo nfo
|
||||
text/x-opml opml
|
||||
text/x-pascal p pas
|
||||
text/x-setext etx
|
||||
text/x-sfv sfv
|
||||
text/x-uuencode uu
|
||||
text/x-vcalendar vcs
|
||||
text/x-vcard vcf
|
||||
video/3gpp 3gp
|
||||
video/3gpp2 3g2
|
||||
video/h261 h261
|
||||
video/h263 h263
|
||||
video/h264 h264
|
||||
video/jpeg jpgv
|
||||
video/jpm jpm jpgm
|
||||
video/mj2 mj2 mjp2
|
||||
video/mp4 mp4 mp4v mpg4
|
||||
video/mpeg mpeg mpg mpe m1v m2v
|
||||
video/ogg ogv
|
||||
video/quicktime qt mov
|
||||
video/vnd.dece.hd uvh uvvh
|
||||
video/vnd.dece.mobile uvm uvvm
|
||||
video/vnd.dece.pd uvp uvvp
|
||||
video/vnd.dece.sd uvs uvvs
|
||||
video/vnd.dece.video uvv uvvv
|
||||
video/vnd.dvb.file dvb
|
||||
video/vnd.fvt fvt
|
||||
video/vnd.mpegurl mxu m4u
|
||||
video/vnd.ms-playready.media.pyv pyv
|
||||
video/vnd.uvvu.mp4 uvu uvvu
|
||||
video/vnd.vivo viv
|
||||
video/webm webm
|
||||
video/x-f4v f4v
|
||||
video/x-fli fli
|
||||
video/x-flv flv
|
||||
video/x-m4v m4v
|
||||
video/x-matroska mkv mk3d mks
|
||||
video/x-mng mng
|
||||
video/x-ms-asf asf asx
|
||||
video/x-ms-vob vob
|
||||
video/x-ms-wm wm
|
||||
video/x-ms-wmv wmv
|
||||
video/x-ms-wmx wmx
|
||||
video/x-ms-wvx wvx
|
||||
video/x-msvideo avi
|
||||
video/x-sgi-movie movie
|
||||
video/x-smv smv
|
||||
x-conference/x-cooltalk ice
|
||||
+151
@@ -0,0 +1,151 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* elFinder Plugin AutoResize
|
||||
* Auto resize on file upload.
|
||||
* ex. binding, configure on connector options
|
||||
* $opts = array(
|
||||
* 'bind' => array(
|
||||
* 'upload.presave' => array(
|
||||
* 'Plugin.AutoResize.onUpLoadPreSave'
|
||||
* )
|
||||
* ),
|
||||
* // global configure (optional)
|
||||
* 'plugin' => array(
|
||||
* 'AutoResize' => array(
|
||||
* 'enable' => true, // For control by volume driver
|
||||
* 'maxWidth' => 1024, // Path to Water mark image
|
||||
* 'maxHeight' => 1024, // Margin right pixel
|
||||
* 'quality' => 95, // JPEG image save quality
|
||||
* 'preserveExif' => false, // Preserve EXIF data (Imagick only)
|
||||
* 'forceEffect' => false, // For change quality or make progressive JPEG of small images
|
||||
* 'targetType' => IMG_GIF|IMG_JPG|IMG_PNG|IMG_WBMP, // Target image formats ( bit-field )
|
||||
* 'offDropWith' => null, // Enabled by default. To disable it if it is dropped with pressing the meta key
|
||||
* // Alt: 8, Ctrl: 4, Meta: 2, Shift: 1 - sum of each value
|
||||
* // In case of using any key, specify it as an array
|
||||
* 'onDropWith' => null // Disabled by default. To enable it if it is dropped with pressing the meta key
|
||||
* // Alt: 8, Ctrl: 4, Meta: 2, Shift: 1 - sum of each value
|
||||
* // In case of using any key, specify it as an array
|
||||
* )
|
||||
* ),
|
||||
* // each volume configure (optional)
|
||||
* 'roots' => array(
|
||||
* array(
|
||||
* 'driver' => 'LocalFileSystem',
|
||||
* 'path' => '/path/to/files/',
|
||||
* 'URL' => 'http://localhost/to/files/'
|
||||
* 'plugin' => array(
|
||||
* 'AutoResize' => array(
|
||||
* 'enable' => true, // For control by volume driver
|
||||
* 'maxWidth' => 1024, // Path to Water mark image
|
||||
* 'maxHeight' => 1024, // Margin right pixel
|
||||
* 'quality' => 95, // JPEG image save quality
|
||||
* 'preserveExif' => false, // Preserve EXIF data (Imagick only)
|
||||
* 'forceEffect' => false, // For change quality or make progressive JPEG of small images
|
||||
* 'targetType' => IMG_GIF|IMG_JPG|IMG_PNG|IMG_WBMP, // Target image formats ( bit-field )
|
||||
* 'offDropWith' => null, // Enabled by default. To disable it if it is dropped with pressing the meta key
|
||||
* // Alt: 8, Ctrl: 4, Meta: 2, Shift: 1 - sum of each value
|
||||
* // In case of using any key, specify it as an array
|
||||
* 'onDropWith' => null // Disabled by default. To enable it if it is dropped with pressing the meta key
|
||||
* // Alt: 8, Ctrl: 4, Meta: 2, Shift: 1 - sum of each value
|
||||
* // In case of using any key, specify it as an array
|
||||
* )
|
||||
* )
|
||||
* )
|
||||
* )
|
||||
* );
|
||||
*
|
||||
* @package elfinder
|
||||
* @author Naoki Sawada
|
||||
* @license New BSD
|
||||
*/
|
||||
class elFinderPluginAutoResize extends elFinderPlugin
|
||||
{
|
||||
|
||||
public function __construct($opts)
|
||||
{
|
||||
$defaults = array(
|
||||
'enable' => true, // For control by volume driver
|
||||
'maxWidth' => 1024, // Path to Water mark image
|
||||
'maxHeight' => 1024, // Margin right pixel
|
||||
'quality' => 95, // JPEG image save quality
|
||||
'preserveExif' => false, // Preserve EXIF data (Imagick only)
|
||||
'forceEffect' => false, // For change quality or make progressive JPEG of small images
|
||||
'targetType' => IMG_GIF | IMG_JPG | IMG_PNG | IMG_WBMP, // Target image formats ( bit-field )
|
||||
'offDropWith' => null, // To disable it if it is dropped with pressing the meta key
|
||||
// Alt: 8, Ctrl: 4, Meta: 2, Shift: 1 - sum of each value
|
||||
// In case of using any key, specify it as an array
|
||||
'disableWithContentSaveId' => true // Disable on URL upload with post data "contentSaveId"
|
||||
);
|
||||
|
||||
$this->opts = array_merge($defaults, $opts);
|
||||
|
||||
}
|
||||
|
||||
public function onUpLoadPreSave(&$thash, &$name, $src, $elfinder, $volume)
|
||||
{
|
||||
if (!$src) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$opts = $this->getCurrentOpts($volume);
|
||||
|
||||
if (!$this->iaEnabled($opts, $elfinder)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$imageType = null;
|
||||
$srcImgInfo = null;
|
||||
if (extension_loaded('fileinfo') && function_exists('mime_content_type')) {
|
||||
$mime = mime_content_type($src);
|
||||
if (substr($mime, 0, 5) !== 'image') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (extension_loaded('exif') && function_exists('exif_imagetype')) {
|
||||
$imageType = exif_imagetype($src);
|
||||
if ($imageType === false) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
$srcImgInfo = getimagesize($src);
|
||||
if ($srcImgInfo === false) {
|
||||
return false;
|
||||
}
|
||||
$imageType = $srcImgInfo[2];
|
||||
}
|
||||
|
||||
// check target image type
|
||||
$imgTypes = array(
|
||||
IMAGETYPE_GIF => IMG_GIF,
|
||||
IMAGETYPE_JPEG => IMG_JPEG,
|
||||
IMAGETYPE_PNG => IMG_PNG,
|
||||
IMAGETYPE_BMP => IMG_WBMP,
|
||||
IMAGETYPE_WBMP => IMG_WBMP
|
||||
);
|
||||
if (!isset($imgTypes[$imageType]) || !($opts['targetType'] & $imgTypes[$imageType])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$srcImgInfo) {
|
||||
$srcImgInfo = getimagesize($src);
|
||||
}
|
||||
|
||||
if ($opts['forceEffect'] || $srcImgInfo[0] > $opts['maxWidth'] || $srcImgInfo[1] > $opts['maxHeight']) {
|
||||
return $this->resize($volume, $src, $srcImgInfo, $opts['maxWidth'], $opts['maxHeight'], $opts['quality'], $opts['preserveExif']);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function resize($volume, $src, $srcImgInfo, $maxWidth, $maxHeight, $jpgQuality, $preserveExif)
|
||||
{
|
||||
$zoom = min(($maxWidth / $srcImgInfo[0]), ($maxHeight / $srcImgInfo[1]));
|
||||
$width = round($srcImgInfo[0] * $zoom);
|
||||
$height = round($srcImgInfo[1] * $zoom);
|
||||
$unenlarge = true;
|
||||
$checkAnimated = true;
|
||||
|
||||
return $volume->imageUtil('resize', $src, compact('width', 'height', 'jpgQuality', 'preserveExif', 'unenlarge', 'checkAnimated'));
|
||||
}
|
||||
}
|
||||
+148
@@ -0,0 +1,148 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* elFinder Plugin AutoRotate
|
||||
* Auto rotation on file upload of JPEG file by EXIF Orientation.
|
||||
* ex. binding, configure on connector options
|
||||
* $opts = array(
|
||||
* 'bind' => array(
|
||||
* 'upload.presave' => array(
|
||||
* 'Plugin.AutoRotate.onUpLoadPreSave'
|
||||
* )
|
||||
* ),
|
||||
* // global configure (optional)
|
||||
* 'plugin' => array(
|
||||
* 'AutoRotate' => array(
|
||||
* 'enable' => true, // For control by volume driver
|
||||
* 'quality' => 95, // JPEG image save quality
|
||||
* 'offDropWith' => null, // Enabled by default. To disable it if it is dropped with pressing the meta key
|
||||
* // Alt: 8, Ctrl: 4, Meta: 2, Shift: 1 - sum of each value
|
||||
* // In case of using any key, specify it as an array
|
||||
* 'onDropWith' => null // Disabled by default. To enable it if it is dropped with pressing the meta key
|
||||
* // Alt: 8, Ctrl: 4, Meta: 2, Shift: 1 - sum of each value
|
||||
* // In case of using any key, specify it as an array
|
||||
* )
|
||||
* ),
|
||||
* // each volume configure (optional)
|
||||
* 'roots' => array(
|
||||
* array(
|
||||
* 'driver' => 'LocalFileSystem',
|
||||
* 'path' => '/path/to/files/',
|
||||
* 'URL' => 'http://localhost/to/files/'
|
||||
* 'plugin' => array(
|
||||
* 'AutoRotate' => array(
|
||||
* 'enable' => true, // For control by volume driver
|
||||
* 'quality' => 95, // JPEG image save quality
|
||||
* 'offDropWith' => null, // Enabled by default. To disable it if it is dropped with pressing the meta key
|
||||
* // Alt: 8, Ctrl: 4, Meta: 2, Shift: 1 - sum of each value
|
||||
* // In case of using any key, specify it as an array
|
||||
* 'onDropWith' => null // Disabled by default. To enable it if it is dropped with pressing the meta key
|
||||
* // Alt: 8, Ctrl: 4, Meta: 2, Shift: 1 - sum of each value
|
||||
* // In case of using any key, specify it as an array
|
||||
* )
|
||||
* )
|
||||
* )
|
||||
* )
|
||||
* );
|
||||
*
|
||||
* @package elfinder
|
||||
* @author Naoki Sawada
|
||||
* @license New BSD
|
||||
*/
|
||||
class elFinderPluginAutoRotate extends elFinderPlugin
|
||||
{
|
||||
|
||||
public function __construct($opts)
|
||||
{
|
||||
$defaults = array(
|
||||
'enable' => true, // For control by volume driver
|
||||
'quality' => 95, // JPEG image save quality
|
||||
'offDropWith' => null, // To disable it if it is dropped with pressing the meta key
|
||||
// Alt: 8, Ctrl: 4, Meta: 2, Shift: 1 - sum of each value
|
||||
// In case of using any key, specify it as an array
|
||||
'disableWithContentSaveId' => true // Disable on URL upload with post data "contentSaveId"
|
||||
);
|
||||
|
||||
$this->opts = array_merge($defaults, $opts);
|
||||
|
||||
}
|
||||
|
||||
public function onUpLoadPreSave(&$thash, &$name, $src, $elfinder, $volume)
|
||||
{
|
||||
if (!$src) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$opts = $this->getCurrentOpts($volume);
|
||||
|
||||
if (!$this->iaEnabled($opts, $elfinder)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$imageType = null;
|
||||
$srcImgInfo = null;
|
||||
if (extension_loaded('fileinfo') && function_exists('mime_content_type')) {
|
||||
$mime = mime_content_type($src);
|
||||
if (substr($mime, 0, 5) !== 'image') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (extension_loaded('exif') && function_exists('exif_imagetype')) {
|
||||
$imageType = exif_imagetype($src);
|
||||
if ($imageType === false) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
$srcImgInfo = getimagesize($src);
|
||||
if ($srcImgInfo === false) {
|
||||
return false;
|
||||
}
|
||||
$imageType = $srcImgInfo[2];
|
||||
}
|
||||
|
||||
// check target image type
|
||||
if ($imageType !== IMAGETYPE_JPEG) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$srcImgInfo) {
|
||||
$srcImgInfo = getimagesize($src);
|
||||
}
|
||||
|
||||
return $this->rotate($volume, $src, $srcImgInfo, $opts['quality']);
|
||||
}
|
||||
|
||||
private function rotate($volume, $src, $srcImgInfo, $quality)
|
||||
{
|
||||
if (!function_exists('exif_read_data')) {
|
||||
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:
|
||||
$degree = 270;
|
||||
break;
|
||||
case 3:
|
||||
$degree = 180;
|
||||
break;
|
||||
case 6:
|
||||
$degree = 90;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!$degree) {
|
||||
return false;
|
||||
}
|
||||
$opts = array(
|
||||
'degree' => $degree,
|
||||
'jpgQuality' => $quality,
|
||||
'checkAnimated' => true
|
||||
);
|
||||
return $volume->imageUtil('rotate', $src, $opts);
|
||||
}
|
||||
}
|
||||
+204
@@ -0,0 +1,204 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* elFinder Plugin Normalizer
|
||||
* UTF-8 Normalizer of file-name and file-path etc.
|
||||
* nfc(NFC): Canonical Decomposition followed by Canonical Composition
|
||||
* nfkc(NFKC): Compatibility Decomposition followed by Canonical
|
||||
* This plugin require Class "Normalizer" (PHP 5 >= 5.3.0, PECL intl >= 1.0.0)
|
||||
* or PEAR package "I18N_UnicodeNormalizer"
|
||||
* ex. binding, configure on connector options
|
||||
* $opts = array(
|
||||
* 'bind' => array(
|
||||
* 'upload.pre mkdir.pre mkfile.pre rename.pre archive.pre ls.pre' => array(
|
||||
* 'Plugin.Normalizer.cmdPreprocess'
|
||||
* ),
|
||||
* 'upload.presave paste.copyfrom' => array(
|
||||
* 'Plugin.Normalizer.onUpLoadPreSave'
|
||||
* )
|
||||
* ),
|
||||
* // global configure (optional)
|
||||
* 'plugin' => array(
|
||||
* 'Normalizer' => array(
|
||||
* 'enable' => true,
|
||||
* 'nfc' => true,
|
||||
* 'nfkc' => true,
|
||||
* 'umlauts' => false,
|
||||
* 'lowercase' => false,
|
||||
* 'convmap' => array()
|
||||
* )
|
||||
* ),
|
||||
* // each volume configure (optional)
|
||||
* 'roots' => array(
|
||||
* array(
|
||||
* 'driver' => 'LocalFileSystem',
|
||||
* 'path' => '/path/to/files/',
|
||||
* 'URL' => 'http://localhost/to/files/'
|
||||
* 'plugin' => array(
|
||||
* 'Normalizer' => array(
|
||||
* 'enable' => true,
|
||||
* 'nfc' => true,
|
||||
* 'nfkc' => true,
|
||||
* 'umlauts' => false,
|
||||
* 'lowercase' => false,
|
||||
* 'convmap' => array()
|
||||
* )
|
||||
* )
|
||||
* )
|
||||
* )
|
||||
* );
|
||||
*
|
||||
* @package elfinder
|
||||
* @author Naoki Sawada
|
||||
* @license New BSD
|
||||
*/
|
||||
class elFinderPluginNormalizer extends elFinderPlugin
|
||||
{
|
||||
private $replaced = array();
|
||||
private $keyMap = array(
|
||||
'ls' => 'intersect',
|
||||
'upload' => 'renames',
|
||||
'mkdir' => array('name', 'dirs')
|
||||
);
|
||||
|
||||
public function __construct($opts)
|
||||
{
|
||||
$defaults = array(
|
||||
'enable' => true, // For control by volume driver
|
||||
'nfc' => true, // Canonical Decomposition followed by Canonical Composition
|
||||
'nfkc' => true, // Compatibility Decomposition followed by Canonical
|
||||
'umlauts' => false, // Convert umlauts with their closest 7 bit ascii equivalent
|
||||
'lowercase' => false, // Make chars lowercase
|
||||
'convmap' => array()// Convert map ('FROM' => 'TO') array
|
||||
);
|
||||
|
||||
$this->opts = array_merge($defaults, $opts);
|
||||
}
|
||||
|
||||
public function cmdPreprocess($cmd, &$args, $elfinder, $volume)
|
||||
{
|
||||
$opts = $this->getCurrentOpts($volume);
|
||||
if (!$opts['enable']) {
|
||||
return false;
|
||||
}
|
||||
$this->replaced[$cmd] = array();
|
||||
$key = (isset($this->keyMap[$cmd])) ? $this->keyMap[$cmd] : 'name';
|
||||
|
||||
if (is_array($key)) {
|
||||
$keys = $key;
|
||||
} else {
|
||||
$keys = array($key);
|
||||
}
|
||||
foreach ($keys as $key) {
|
||||
if (isset($args[$key])) {
|
||||
if (is_array($args[$key])) {
|
||||
foreach ($args[$key] as $i => $name) {
|
||||
if ($cmd === 'mkdir' && $key === 'dirs') {
|
||||
// $name need '/' as prefix see #2607
|
||||
$name = '/' . ltrim($name, '/');
|
||||
$_names = explode('/', $name);
|
||||
$_res = array();
|
||||
foreach ($_names as $_name) {
|
||||
$_res[] = $this->normalize($_name, $opts);
|
||||
}
|
||||
$this->replaced[$cmd][$name] = $args[$key][$i] = join('/', $_res);
|
||||
} else {
|
||||
$this->replaced[$cmd][$name] = $args[$key][$i] = $this->normalize($name, $opts);
|
||||
}
|
||||
}
|
||||
} else if ($args[$key] !== '') {
|
||||
$name = $args[$key];
|
||||
$this->replaced[$cmd][$name] = $args[$key] = $this->normalize($name, $opts);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($cmd === 'ls' || $cmd === 'mkdir') {
|
||||
if (!empty($this->replaced[$cmd])) {
|
||||
// un-regist for legacy settings
|
||||
$elfinder->unbind($cmd, array($this, 'cmdPostprocess'));
|
||||
$elfinder->bind($cmd, array($this, 'cmdPostprocess'));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function cmdPostprocess($cmd, &$result, $args, $elfinder, $volume)
|
||||
{
|
||||
if ($cmd === 'ls') {
|
||||
if (!empty($result['list']) && !empty($this->replaced['ls'])) {
|
||||
foreach ($result['list'] as $hash => $name) {
|
||||
if ($keys = array_keys($this->replaced['ls'], $name)) {
|
||||
if (count($keys) === 1) {
|
||||
$result['list'][$hash] = $keys[0];
|
||||
} else {
|
||||
$result['list'][$hash] = $keys;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if ($cmd === 'mkdir') {
|
||||
if (!empty($result['hashes']) && !empty($this->replaced['mkdir'])) {
|
||||
foreach ($result['hashes'] as $name => $hash) {
|
||||
if ($keys = array_keys($this->replaced['mkdir'], $name)) {
|
||||
$result['hashes'][$keys[0]] = $hash;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: $thash is directory hash so it unneed to process at here
|
||||
public function onUpLoadPreSave(&$thash, &$name, $src, $elfinder, $volume)
|
||||
{
|
||||
$opts = $this->getCurrentOpts($volume);
|
||||
if (!$opts['enable']) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$name = $this->normalize($name, $opts);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function normalize($str, $opts)
|
||||
{
|
||||
if ($opts['nfc'] || $opts['nfkc']) {
|
||||
if (class_exists('Normalizer', false)) {
|
||||
if ($opts['nfc'] && !Normalizer::isNormalized($str, Normalizer::FORM_C))
|
||||
$str = Normalizer::normalize($str, Normalizer::FORM_C);
|
||||
if ($opts['nfkc'] && !Normalizer::isNormalized($str, Normalizer::FORM_KC))
|
||||
$str = Normalizer::normalize($str, Normalizer::FORM_KC);
|
||||
} else {
|
||||
if (!class_exists('I18N_UnicodeNormalizer', false)) {
|
||||
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();
|
||||
if ($opts['nfc'])
|
||||
$str = $normalizer->normalize($str, 'NFC');
|
||||
if ($opts['nfkc'])
|
||||
$str = $normalizer->normalize($str, 'NFKC');
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($opts['umlauts']) {
|
||||
if (strpos($str = htmlentities($str, ENT_QUOTES, 'UTF-8'), '&') !== false) {
|
||||
$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'])) {
|
||||
$str = strtr($str, $opts['convmap']);
|
||||
}
|
||||
if ($opts['lowercase']) {
|
||||
if (function_exists('mb_strtolower')) {
|
||||
$str = mb_strtolower($str, 'UTF-8');
|
||||
} else {
|
||||
$str = strtolower($str);
|
||||
}
|
||||
}
|
||||
return $str;
|
||||
}
|
||||
}
|
||||
+157
@@ -0,0 +1,157 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* elFinder Plugin Sanitizer
|
||||
* Sanitizer of file-name and file-path etc.
|
||||
* ex. binding, configure on connector options
|
||||
* $opts = array(
|
||||
* 'bind' => array(
|
||||
* 'upload.pre mkdir.pre mkfile.pre rename.pre archive.pre ls.pre' => array(
|
||||
* 'Plugin.Sanitizer.cmdPreprocess'
|
||||
* ),
|
||||
* 'upload.presave paste.copyfrom' => array(
|
||||
* 'Plugin.Sanitizer.onUpLoadPreSave'
|
||||
* )
|
||||
* ),
|
||||
* // global configure (optional)
|
||||
* 'plugin' => array(
|
||||
* 'Sanitizer' => array(
|
||||
* 'enable' => true,
|
||||
* 'targets' => array('\\','/',':','*','?','"','<','>','|'), // target chars
|
||||
* 'replace' => '_', // replace to this
|
||||
* 'callBack' => null // Or @callable sanitize function
|
||||
* )
|
||||
* ),
|
||||
* // each volume configure (optional)
|
||||
* 'roots' => array(
|
||||
* array(
|
||||
* 'driver' => 'LocalFileSystem',
|
||||
* 'path' => '/path/to/files/',
|
||||
* 'URL' => 'http://localhost/to/files/'
|
||||
* 'plugin' => array(
|
||||
* 'Sanitizer' => array(
|
||||
* 'enable' => true,
|
||||
* 'targets' => array('\\','/',':','*','?','"','<','>','|'), // target chars
|
||||
* 'replace' => '_', // replace to this
|
||||
* 'callBack' => null // Or @callable sanitize function
|
||||
* )
|
||||
* )
|
||||
* )
|
||||
* )
|
||||
* );
|
||||
*
|
||||
* @package elfinder
|
||||
* @author Naoki Sawada
|
||||
* @license New BSD
|
||||
*/
|
||||
class elFinderPluginSanitizer extends elFinderPlugin
|
||||
{
|
||||
private $replaced = array();
|
||||
private $keyMap = array(
|
||||
'ls' => 'intersect',
|
||||
'upload' => 'renames',
|
||||
'mkdir' => array('name', 'dirs')
|
||||
);
|
||||
|
||||
public function __construct($opts)
|
||||
{
|
||||
$defaults = array(
|
||||
'enable' => true, // For control by volume driver
|
||||
'targets' => array('\\', '/', ':', '*', '?', '"', '<', '>', '|'), // target chars
|
||||
'replace' => '_', // replace to this
|
||||
'callBack' => null // Or callable sanitize function
|
||||
);
|
||||
$this->opts = array_merge($defaults, $opts);
|
||||
}
|
||||
|
||||
public function cmdPreprocess($cmd, &$args, $elfinder, $volume)
|
||||
{
|
||||
$opts = $this->getCurrentOpts($volume);
|
||||
if (!$opts['enable']) {
|
||||
return false;
|
||||
}
|
||||
$this->replaced[$cmd] = array();
|
||||
$key = (isset($this->keyMap[$cmd])) ? $this->keyMap[$cmd] : 'name';
|
||||
|
||||
if (is_array($key)) {
|
||||
$keys = $key;
|
||||
} else {
|
||||
$keys = array($key);
|
||||
}
|
||||
foreach ($keys as $key) {
|
||||
if (isset($args[$key])) {
|
||||
if (is_array($args[$key])) {
|
||||
foreach ($args[$key] as $i => $name) {
|
||||
if ($cmd === 'mkdir' && $key === 'dirs') {
|
||||
// $name need '/' as prefix see #2607
|
||||
$name = '/' . ltrim($name, '/');
|
||||
$_names = explode('/', $name);
|
||||
$_res = array();
|
||||
foreach ($_names as $_name) {
|
||||
$_res[] = $this->sanitizeFileName($_name, $opts);
|
||||
}
|
||||
$this->replaced[$cmd][$name] = $args[$key][$i] = join('/', $_res);
|
||||
} else {
|
||||
$this->replaced[$cmd][$name] = $args[$key][$i] = $this->sanitizeFileName($name, $opts);
|
||||
}
|
||||
}
|
||||
} else if ($args[$key] !== '') {
|
||||
$name = $args[$key];
|
||||
$this->replaced[$cmd][$name] = $args[$key] = $this->sanitizeFileName($name, $opts);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($cmd === 'ls' || $cmd === 'mkdir') {
|
||||
if (!empty($this->replaced[$cmd])) {
|
||||
// un-regist for legacy settings
|
||||
$elfinder->unbind($cmd, array($this, 'cmdPostprocess'));
|
||||
$elfinder->bind($cmd, array($this, 'cmdPostprocess'));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function cmdPostprocess($cmd, &$result, $args, $elfinder, $volume)
|
||||
{
|
||||
if ($cmd === 'ls') {
|
||||
if (!empty($result['list']) && !empty($this->replaced['ls'])) {
|
||||
foreach ($result['list'] as $hash => $name) {
|
||||
if ($keys = array_keys($this->replaced['ls'], $name)) {
|
||||
if (count($keys) === 1) {
|
||||
$result['list'][$hash] = $keys[0];
|
||||
} else {
|
||||
$result['list'][$hash] = $keys;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if ($cmd === 'mkdir') {
|
||||
if (!empty($result['hashes']) && !empty($this->replaced['mkdir'])) {
|
||||
foreach ($result['hashes'] as $name => $hash) {
|
||||
if ($keys = array_keys($this->replaced['mkdir'], $name)) {
|
||||
$result['hashes'][$keys[0]] = $hash;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: $thash is directory hash so it unneed to process at here
|
||||
public function onUpLoadPreSave(&$thash, &$name, $src, $elfinder, $volume)
|
||||
{
|
||||
$opts = $this->getCurrentOpts($volume);
|
||||
if (!$opts['enable']) {
|
||||
return false;
|
||||
}
|
||||
$name = $this->sanitizeFileName($name, $opts);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function sanitizeFileName($filename, $opts)
|
||||
{
|
||||
if (!empty($opts['callBack']) && is_callable($opts['callBack'])) {
|
||||
return call_user_func_array($opts['callBack'], array($filename, $opts));
|
||||
}
|
||||
return str_replace($opts['targets'], $opts['replace'], $filename);
|
||||
}
|
||||
}
|
||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 8.7 KiB |
+432
@@ -0,0 +1,432 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* elFinder Plugin Watermark
|
||||
* Print watermark on file upload.
|
||||
* ex. binding, configure on connector options
|
||||
* $opts = array(
|
||||
* 'bind' => array(
|
||||
* 'upload.presave' => array(
|
||||
* 'Plugin.Watermark.onUpLoadPreSave'
|
||||
* )
|
||||
* ),
|
||||
* // global configure (optional)
|
||||
* 'plugin' => array(
|
||||
* 'Watermark' => array(
|
||||
* 'enable' => true, // For control by volume driver
|
||||
* 'source' => 'logo.png', // Path to Water mark image
|
||||
* 'ratio' => 0.2, // Ratio to original image (ratio > 0 and ratio <= 1)
|
||||
* 'position' => 'RB', // Position L(eft)/C(enter)/R(ight) and T(op)/M(edium)/B(ottom)
|
||||
* 'marginX' => 5, // Margin horizontal pixel
|
||||
* 'marginY' => 5, // Margin vertical pixel
|
||||
* 'quality' => 95, // JPEG image save quality
|
||||
* 'transparency' => 70, // Water mark image transparency ( other than PNG )
|
||||
* 'targetType' => IMG_GIF|IMG_JPG|IMG_PNG|IMG_WBMP, // Target image formats ( bit-field )
|
||||
* 'targetMinPixel' => 200, // Target image minimum pixel size
|
||||
* 'interlace' => IMG_GIF|IMG_JPG, // Set interlacebit image formats ( bit-field )
|
||||
* 'offDropWith' => null, // Enabled by default. To disable it if it is dropped with pressing the meta key
|
||||
* // Alt: 8, Ctrl: 4, Meta: 2, Shift: 1 - sum of each value
|
||||
* // In case of using any key, specify it as an array
|
||||
* 'onDropWith' => null // Disabled by default. To enable it if it is dropped with pressing the meta key
|
||||
* // Alt: 8, Ctrl: 4, Meta: 2, Shift: 1 - sum of each value
|
||||
* // In case of using any key, specify it as an array
|
||||
* )
|
||||
* ),
|
||||
* // each volume configure (optional)
|
||||
* 'roots' => array(
|
||||
* array(
|
||||
* 'driver' => 'LocalFileSystem',
|
||||
* 'path' => '/path/to/files/',
|
||||
* 'URL' => 'http://localhost/to/files/'
|
||||
* 'plugin' => array(
|
||||
* 'Watermark' => array(
|
||||
* 'enable' => true, // For control by volume driver
|
||||
* 'source' => 'logo.png', // Path to Water mark image
|
||||
* 'ratio' => 0.2, // Ratio to original image (ratio > 0 and ratio <= 1)
|
||||
* 'position' => 'RB', // Position L(eft)/C(enter)/R(ight) and T(op)/M(edium)/B(ottom)
|
||||
* 'marginX' => 5, // Margin horizontal pixel
|
||||
* 'marginY' => 5, // Margin vertical pixel
|
||||
* 'quality' => 95, // JPEG image save quality
|
||||
* 'transparency' => 70, // Water mark image transparency ( other than PNG )
|
||||
* 'targetType' => IMG_GIF|IMG_JPG|IMG_PNG|IMG_WBMP, // Target image formats ( bit-field )
|
||||
* 'targetMinPixel' => 200, // Target image minimum pixel size
|
||||
* 'interlace' => IMG_GIF|IMG_JPG, // Set interlacebit image formats ( bit-field )
|
||||
* 'offDropWith' => null, // Enabled by default. To disable it if it is dropped with pressing the meta key
|
||||
* // Alt: 8, Ctrl: 4, Meta: 2, Shift: 1 - sum of each value
|
||||
* // In case of using any key, specify it as an array
|
||||
* 'onDropWith' => null // Disabled by default. To enable it if it is dropped with pressing the meta key
|
||||
* // Alt: 8, Ctrl: 4, Meta: 2, Shift: 1 - sum of each value
|
||||
* // In case of using any key, specify it as an array
|
||||
* )
|
||||
* )
|
||||
* )
|
||||
* )
|
||||
* );
|
||||
*
|
||||
* @package elfinder
|
||||
* @author Naoki Sawada
|
||||
* @license New BSD
|
||||
*/
|
||||
class elFinderPluginWatermark extends elFinderPlugin
|
||||
{
|
||||
|
||||
private $watermarkImgInfo = null;
|
||||
|
||||
public function __construct($opts)
|
||||
{
|
||||
$defaults = array(
|
||||
'enable' => true, // For control by volume driver
|
||||
'source' => 'logo.png', // Path to Water mark image
|
||||
'ratio' => 0.2, // Ratio to original image (ratio > 0 and ratio <= 1)
|
||||
'position' => 'RB', // Position L(eft)/C(enter)/R(ight) and T(op)/M(edium)/B(ottom)
|
||||
'marginX' => 5, // Margin horizontal pixel
|
||||
'marginY' => 5, // Margin vertical pixel
|
||||
'quality' => 95, // JPEG image save quality
|
||||
'transparency' => 70, // Water mark image transparency ( other than PNG )
|
||||
'targetType' => IMG_GIF | IMG_JPG | IMG_PNG | IMG_WBMP, // Target image formats ( bit-field )
|
||||
'targetMinPixel' => 200, // Target image minimum pixel size
|
||||
'interlace' => IMG_GIF | IMG_JPG, // Set interlacebit image formats ( bit-field )
|
||||
'offDropWith' => null, // To disable it if it is dropped with pressing the meta key
|
||||
// Alt: 8, Ctrl: 4, Meta: 2, Shift: 1 - sum of each value
|
||||
// In case of using any key, specify it as an array
|
||||
'marginRight' => 0, // Deprecated - marginX should be used
|
||||
'marginBottom' => 0, // Deprecated - marginY should be used
|
||||
'disableWithContentSaveId' => true // Disable on URL upload with post data "contentSaveId"
|
||||
);
|
||||
|
||||
$this->opts = array_merge($defaults, $opts);
|
||||
|
||||
}
|
||||
|
||||
public function onUpLoadPreSave(&$thash, &$name, $src, $elfinder, $volume)
|
||||
{
|
||||
if (!$src) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$opts = $this->getCurrentOpts($volume);
|
||||
|
||||
if (!$this->iaEnabled($opts, $elfinder)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$imageType = null;
|
||||
$srcImgInfo = null;
|
||||
if (extension_loaded('fileinfo') && function_exists('mime_content_type')) {
|
||||
$mime = mime_content_type($src);
|
||||
if (substr($mime, 0, 5) !== 'image') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (extension_loaded('exif') && function_exists('exif_imagetype')) {
|
||||
$imageType = exif_imagetype($src);
|
||||
if ($imageType === false) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
$srcImgInfo = getimagesize($src);
|
||||
if ($srcImgInfo === false) {
|
||||
return false;
|
||||
}
|
||||
$imageType = $srcImgInfo[2];
|
||||
}
|
||||
|
||||
// check target image type
|
||||
$imgTypes = array(
|
||||
IMAGETYPE_GIF => IMG_GIF,
|
||||
IMAGETYPE_JPEG => IMG_JPEG,
|
||||
IMAGETYPE_PNG => IMG_PNG,
|
||||
IMAGETYPE_BMP => IMG_WBMP,
|
||||
IMAGETYPE_WBMP => IMG_WBMP
|
||||
);
|
||||
if (!isset($imgTypes[$imageType]) || !($opts['targetType'] & $imgTypes[$imageType])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// check Animation Gif
|
||||
if ($imageType === IMAGETYPE_GIF && elFinder::isAnimationGif($src)) {
|
||||
return false;
|
||||
}
|
||||
// check Animation Png
|
||||
if ($imageType === IMAGETYPE_PNG && elFinder::isAnimationPng($src)) {
|
||||
return false;
|
||||
}
|
||||
// check water mark image
|
||||
if (!file_exists($opts['source'])) {
|
||||
$opts['source'] = dirname(__FILE__) . "/" . $opts['source'];
|
||||
}
|
||||
if (is_readable($opts['source'])) {
|
||||
$watermarkImgInfo = getimagesize($opts['source']);
|
||||
if (!$watermarkImgInfo) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$srcImgInfo) {
|
||||
$srcImgInfo = getimagesize($src);
|
||||
}
|
||||
|
||||
$watermark = $opts['source'];
|
||||
$quality = $opts['quality'];
|
||||
$transparency = $opts['transparency'];
|
||||
|
||||
// check target image size
|
||||
if ($opts['targetMinPixel'] > 0 && $opts['targetMinPixel'] > min($srcImgInfo[0], $srcImgInfo[1])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$watermark_width = $watermarkImgInfo[0];
|
||||
$watermark_height = $watermarkImgInfo[1];
|
||||
|
||||
// Specified as a ratio to the image size
|
||||
if ($opts['ratio'] && $opts['ratio'] > 0 && $opts['ratio'] <= 1) {
|
||||
$maxW = $srcImgInfo[0] * $opts['ratio'] - ($opts['marginX'] * 2);
|
||||
$maxH = $srcImgInfo[1] * $opts['ratio'] - ($opts['marginY'] * 2);
|
||||
$dx = $dy = 0;
|
||||
if (($maxW >= $watermarkImgInfo[0] && $maxH >= $watermarkImgInfo[0]) || ($maxW <= $watermarkImgInfo[0] && $maxH <= $watermarkImgInfo[0])) {
|
||||
$dx = abs($srcImgInfo[0] - $watermarkImgInfo[0]);
|
||||
$dy = abs($srcImgInfo[1] - $watermarkImgInfo[1]);
|
||||
} else if ($maxW < $watermarkImgInfo[0]) {
|
||||
$dx = -1;
|
||||
} else {
|
||||
$dy = -1;
|
||||
}
|
||||
if ($dx < $dy) {
|
||||
$ww = $maxW;
|
||||
$wh = $watermarkImgInfo[1] * ($ww / $watermarkImgInfo[0]);
|
||||
} else {
|
||||
$wh = $maxH;
|
||||
$ww = $watermarkImgInfo[0] * ($wh / $watermarkImgInfo[1]);
|
||||
}
|
||||
$watermarkImgInfo[0] = $ww;
|
||||
$watermarkImgInfo[1] = $wh;
|
||||
} else {
|
||||
$opts['ratio'] = null;
|
||||
}
|
||||
|
||||
$opts['position'] = strtoupper($opts['position']);
|
||||
|
||||
// Set vertical position
|
||||
if (strpos($opts['position'], 'T') !== false) {
|
||||
// Top
|
||||
$dest_x = $opts['marginX'];
|
||||
} else if (strpos($opts['position'], 'M') !== false) {
|
||||
// Middle
|
||||
$dest_x = ($srcImgInfo[0] - $watermarkImgInfo[0]) / 2;
|
||||
} else {
|
||||
// Bottom
|
||||
$dest_x = $srcImgInfo[0] - $watermarkImgInfo[0] - max($opts['marginBottom'], $opts['marginX']);
|
||||
}
|
||||
|
||||
// Set horizontal position
|
||||
if (strpos($opts['position'], 'L') !== false) {
|
||||
// Left
|
||||
$dest_y = $opts['marginY'];
|
||||
} else if (strpos($opts['position'], 'C') !== false) {
|
||||
// Middle
|
||||
$dest_y = ($srcImgInfo[1] - $watermarkImgInfo[1]) / 2;
|
||||
} else {
|
||||
// Right
|
||||
$dest_y = $srcImgInfo[1] - $watermarkImgInfo[1] - max($opts['marginRight'], $opts['marginY']);
|
||||
}
|
||||
|
||||
|
||||
// check interlace
|
||||
$opts['interlace'] = ($opts['interlace'] & $imgTypes[$imageType]);
|
||||
|
||||
// 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, $watermarkSrc, $dest_x, $dest_y, $quality, $transparency, $watermarkImgInfo, $opts)
|
||||
{
|
||||
|
||||
try {
|
||||
|
||||
// Open the original image
|
||||
$img = new Imagick($src);
|
||||
|
||||
// Open the watermark
|
||||
$watermark = new Imagick($watermarkSrc);
|
||||
|
||||
// zoom
|
||||
if ($opts['ratio']) {
|
||||
$watermark->scaleImage($watermarkImgInfo[0], $watermarkImgInfo[1]);
|
||||
}
|
||||
|
||||
// Set transparency
|
||||
if (strtoupper($watermark->getImageFormat()) !== 'PNG') {
|
||||
$watermark->setImageOpacity($transparency / 100);
|
||||
}
|
||||
|
||||
// Overlay the watermark on the original image
|
||||
$img->compositeImage($watermark, imagick::COMPOSITE_OVER, $dest_x, $dest_y);
|
||||
|
||||
// Set quality
|
||||
if (strtoupper($img->getImageFormat()) === 'JPEG') {
|
||||
$img->setImageCompression(imagick::COMPRESSION_JPEG);
|
||||
$img->setCompressionQuality($quality);
|
||||
}
|
||||
|
||||
// set interlace
|
||||
$opts['interlace'] && $img->setInterlaceScheme(Imagick::INTERLACE_PLANE);
|
||||
|
||||
$result = $img->writeImage($src);
|
||||
|
||||
$img->clear();
|
||||
$img->destroy();
|
||||
$watermark->clear();
|
||||
$watermark->destroy();
|
||||
|
||||
return $result ? true : false;
|
||||
} catch (Exception $e) {
|
||||
$ermsg = $e->getMessage();
|
||||
$ermsg && trigger_error($ermsg);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private function watermarkPrint_gd($src, $watermark, $dest_x, $dest_y, $quality, $transparency, $watermarkImgInfo, $srcImgInfo, $opts)
|
||||
{
|
||||
|
||||
$watermark_width = $watermarkImgInfo[0];
|
||||
$watermark_height = $watermarkImgInfo[1];
|
||||
|
||||
$ermsg = '';
|
||||
switch ($watermarkImgInfo['mime']) {
|
||||
case 'image/gif':
|
||||
if (imagetypes() & IMG_GIF) {
|
||||
$oWatermarkImg = imagecreatefromgif($watermark);
|
||||
} else {
|
||||
$ermsg = 'GIF images are not supported as watermark image';
|
||||
}
|
||||
break;
|
||||
case 'image/jpeg':
|
||||
if (imagetypes() & IMG_JPG) {
|
||||
$oWatermarkImg = imagecreatefromjpeg($watermark);
|
||||
} else {
|
||||
$ermsg = 'JPEG images are not supported as watermark image';
|
||||
}
|
||||
break;
|
||||
case 'image/png':
|
||||
if (imagetypes() & IMG_PNG) {
|
||||
$oWatermarkImg = imagecreatefrompng($watermark);
|
||||
} else {
|
||||
$ermsg = 'PNG images are not supported as watermark image';
|
||||
}
|
||||
break;
|
||||
case 'image/wbmp':
|
||||
if (imagetypes() & IMG_WBMP) {
|
||||
$oWatermarkImg = imagecreatefromwbmp($watermark);
|
||||
} else {
|
||||
$ermsg = 'WBMP images are not supported as watermark image';
|
||||
}
|
||||
break;
|
||||
default:
|
||||
$oWatermarkImg = false;
|
||||
$ermsg = $watermarkImgInfo['mime'] . ' images are not supported as watermark image';
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (!$ermsg) {
|
||||
// zoom
|
||||
if ($opts['ratio']) {
|
||||
$tmpImg = imagecreatetruecolor($watermarkImgInfo[0], $watermarkImgInfo[1]);
|
||||
imagealphablending($tmpImg, false);
|
||||
imagesavealpha($tmpImg, true);
|
||||
imagecopyresampled($tmpImg, $oWatermarkImg, 0, 0, 0, 0, $watermarkImgInfo[0], $watermarkImgInfo[1], imagesx($oWatermarkImg), imagesy($oWatermarkImg));
|
||||
imageDestroy($oWatermarkImg);
|
||||
$oWatermarkImg = $tmpImg;
|
||||
$tmpImg = null;
|
||||
}
|
||||
|
||||
switch ($srcImgInfo['mime']) {
|
||||
case 'image/gif':
|
||||
if (imagetypes() & IMG_GIF) {
|
||||
$oSrcImg = imagecreatefromgif($src);
|
||||
} else {
|
||||
$ermsg = 'GIF images are not supported as source image';
|
||||
}
|
||||
break;
|
||||
case 'image/jpeg':
|
||||
if (imagetypes() & IMG_JPG) {
|
||||
$oSrcImg = imagecreatefromjpeg($src);
|
||||
} else {
|
||||
$ermsg = 'JPEG images are not supported as source image';
|
||||
}
|
||||
break;
|
||||
case 'image/png':
|
||||
if (imagetypes() & IMG_PNG) {
|
||||
$oSrcImg = imagecreatefrompng($src);
|
||||
} else {
|
||||
$ermsg = 'PNG images are not supported as source image';
|
||||
}
|
||||
break;
|
||||
case 'image/wbmp':
|
||||
if (imagetypes() & IMG_WBMP) {
|
||||
$oSrcImg = imagecreatefromwbmp($src);
|
||||
} else {
|
||||
$ermsg = 'WBMP images are not supported as source image';
|
||||
}
|
||||
break;
|
||||
default:
|
||||
$oSrcImg = false;
|
||||
$ermsg = $srcImgInfo['mime'] . ' images are not supported as source image';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($ermsg || false === $oSrcImg || false === $oWatermarkImg) {
|
||||
$ermsg && trigger_error($ermsg);
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($srcImgInfo['mime'] === 'image/png') {
|
||||
if (function_exists('imagecolorallocatealpha')) {
|
||||
$bg = imagecolorallocatealpha($oSrcImg, 255, 255, 255, 127);
|
||||
imagefill($oSrcImg, 0, 0, $bg);
|
||||
}
|
||||
}
|
||||
|
||||
if ($watermarkImgInfo['mime'] === 'image/png') {
|
||||
imagecopy($oSrcImg, $oWatermarkImg, $dest_x, $dest_y, 0, 0, $watermark_width, $watermark_height);
|
||||
} else {
|
||||
imagecopymerge($oSrcImg, $oWatermarkImg, $dest_x, $dest_y, 0, 0, $watermark_width, $watermark_height, $transparency);
|
||||
}
|
||||
|
||||
// set interlace
|
||||
$opts['interlace'] && imageinterlace($oSrcImg, true);
|
||||
|
||||
switch ($srcImgInfo['mime']) {
|
||||
case 'image/gif':
|
||||
imagegif($oSrcImg, $src);
|
||||
break;
|
||||
case 'image/jpeg':
|
||||
imagejpeg($oSrcImg, $src, $quality);
|
||||
break;
|
||||
case 'image/png':
|
||||
if (function_exists('imagesavealpha') && function_exists('imagealphablending')) {
|
||||
imagealphablending($oSrcImg, false);
|
||||
imagesavealpha($oSrcImg, true);
|
||||
}
|
||||
imagepng($oSrcImg, $src);
|
||||
break;
|
||||
case 'image/wbmp':
|
||||
imagewbmp($oSrcImg, $src);
|
||||
break;
|
||||
}
|
||||
|
||||
imageDestroy($oSrcImg);
|
||||
imageDestroy($oWatermarkImg);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
/**
|
||||
* This class describes elFinder plugin window remove tail dots.
|
||||
* This plugin is automatically loaded on the Windows server
|
||||
* and enabled in the LocalFileSystem driver.
|
||||
*/
|
||||
class elFinderPluginWinRemoveTailDots extends elFinderPlugin
|
||||
{
|
||||
private $replaced = array();
|
||||
private $keyMap = array(
|
||||
'ls' => 'intersect',
|
||||
'upload' => 'renames',
|
||||
'mkdir' => array('name', 'dirs')
|
||||
);
|
||||
|
||||
public function __construct($opts)
|
||||
{
|
||||
$defaults = array(
|
||||
'enable' => false, // For control by volume driver
|
||||
);
|
||||
|
||||
$this->opts = array_merge($defaults, $opts);
|
||||
}
|
||||
|
||||
public function cmdPreprocess($cmd, &$args, $elfinder, $volume)
|
||||
{
|
||||
$opts = $this->getCurrentOpts($volume);
|
||||
if (!$opts['enable']) {
|
||||
return false;
|
||||
}
|
||||
$this->replaced[$cmd] = array();
|
||||
$key = (isset($this->keyMap[$cmd])) ? $this->keyMap[$cmd] : 'name';
|
||||
|
||||
if (is_array($key)) {
|
||||
$keys = $key;
|
||||
} else {
|
||||
$keys = array($key);
|
||||
}
|
||||
foreach ($keys as $key) {
|
||||
if (isset($args[$key])) {
|
||||
if (is_array($args[$key])) {
|
||||
foreach ($args[$key] as $i => $name) {
|
||||
if ($cmd === 'mkdir' && $key === 'dirs') {
|
||||
// $name need '/' as prefix see #2607
|
||||
$name = '/' . ltrim($name, '/');
|
||||
$_names = explode('/', $name);
|
||||
$_res = array();
|
||||
foreach ($_names as $_name) {
|
||||
$_res[] = $this->normalize($_name, $opts);
|
||||
}
|
||||
$this->replaced[$cmd][$name] = $args[$key][$i] = join('/', $_res);
|
||||
} else {
|
||||
$this->replaced[$cmd][$name] = $args[$key][$i] = $this->normalize($name, $opts);
|
||||
}
|
||||
}
|
||||
} else if ($args[$key] !== '') {
|
||||
$name = $args[$key];
|
||||
$this->replaced[$cmd][$name] = $args[$key] = $this->normalize($name, $opts);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($cmd === 'ls' || $cmd === 'mkdir') {
|
||||
if (!empty($this->replaced[$cmd])) {
|
||||
// un-regist for legacy settings
|
||||
$elfinder->unbind($cmd, array($this, 'cmdPostprocess'));
|
||||
$elfinder->bind($cmd, array($this, 'cmdPostprocess'));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function cmdPostprocess($cmd, &$result, $args, $elfinder, $volume)
|
||||
{
|
||||
if ($cmd === 'ls') {
|
||||
if (!empty($result['list']) && !empty($this->replaced['ls'])) {
|
||||
foreach ($result['list'] as $hash => $name) {
|
||||
if ($keys = array_keys($this->replaced['ls'], $name)) {
|
||||
if (count($keys) === 1) {
|
||||
$result['list'][$hash] = $keys[0];
|
||||
} else {
|
||||
$result['list'][$hash] = $keys;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if ($cmd === 'mkdir') {
|
||||
if (!empty($result['hashes']) && !empty($this->replaced['mkdir'])) {
|
||||
foreach ($result['hashes'] as $name => $hash) {
|
||||
if ($keys = array_keys($this->replaced['mkdir'], $name)) {
|
||||
$result['hashes'][$keys[0]] = $hash;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: $thash is directory hash so it unneed to process at here
|
||||
public function onUpLoadPreSave(&$thash, &$name, $src, $elfinder, $volume)
|
||||
{
|
||||
$opts = $this->getCurrentOpts($volume);
|
||||
if (!$opts['enable']) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$name = $this->normalize($name, $opts);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function normalize($str, $opts)
|
||||
{
|
||||
$str = rtrim($str, '.');
|
||||
return $str;
|
||||
}
|
||||
} // END class elFinderPluginWinRemoveTailDots
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.5 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.2 KiB |
Reference in New Issue
Block a user