<?php
/**
* elFinder - file manager for web.
* Core class.
*
* @package elfinder
* @author Dmitry (dio) Levashov
* @author Troex Nevelin
* @author Alexey Sukhotin
**/
class elFinder
{
/**
* API version number
*
* @var float
**/
protected static $ApiVersion = 2.1;
/**
* API version number
*
* @deprecated
* @var string
**/
protected $version;
/**
* API revision that this connector supports all functions
*
* @var integer
*/
protected static $ApiRevision = 60;
/**
* Storages (root dirs)
*
* @var array
**/
protected $volumes = array();
/**
* elFinder instance
*
* @var object
*/
public static $instance = null;
/**
* Current request args
*
* @var array
*/
public static $currentArgs = array();
/**
* Network mount drivers
*
* @var array
*/
public static $netDrivers = array();
/**
* elFinder global locale
*
* @var string
*/
public static $locale = '';
/**
* elFinderVolumeDriver default mime.type file path
*
* @var string
*/
public static $defaultMimefile = '';
/**
* A file save destination path when a temporary content URL is required
* on a network volume or the like
* It can be overwritten by volume route setting
*
* @var string
*/
public static $tmpLinkPath = '';
/**
* A file save destination URL when a temporary content URL is required
* on a network volume or the like
* It can be overwritten by volume route setting
*
* @var string
*/
public static $tmpLinkUrl = '';
/**
* Temporary content URL lifetime (seconds)
*
* @var integer
*/
public static $tmpLinkLifeTime = 3600;
/**
* MIME type list handled as a text file
*
* @var array
*/
public static $textMimes = array(
'application/dash+xml',
'application/docbook+xml',
'application/javascript',
'application/json',
'application/plt',
'application/sat',
'application/sql',
'application/step',
'application/vnd.hp-hpgl',
'application/x-awk',
'application/x-config',
'application/x-csh',
'application/x-empty',
'application/x-mpegurl',
'application/x-perl',
'application/x-php',
'application/x-web-config',
'application/xhtml+xml',
'application/xml',
'audio/x-mp3-playlist',
'image/cgm',
'image/svg+xml',
'image/vnd.dxf',
'model/iges'
);
/**
* Maximum memory size to be extended during GD processing
* (0: not expanded, -1: unlimited or memory size notation)
*
* @var integer|string
*/
public static $memoryLimitGD = 0;
/**
* Path of current request flag file for abort check
*
* @var string
*/
protected static $abortCheckFile = null;
/**
* elFinder session wrapper object
*
* @var elFinderSessionInterface
*/
protected $session;
/**
* elFinder global sessionCacheKey
*
* @deprecated
* @var string
*/
public static $sessionCacheKey = '';
/**
* Is session closed
*
* @deprecated
* @var bool
*/
private static $sessionClosed = false;
/**
* elFinder base64encodeSessionData
* elFinder save session data as `UTF-8`
* If the session storage mechanism of the system does not allow `UTF-8`
* And it must be `true` option 'base64encodeSessionData' of elFinder
* WARNING: When enabling this option, if saving the data passed from the user directly to the session variable,
* it make vulnerable to the object injection attack, so use it carefully.
* see https://github.com/Studio-42/elFinder/issues/2345
*
* @var bool
*/
protected static $base64encodeSessionData = false;
/**
* elFinder common tempraly path
*
* @var string
* @default "./.tmp" or sys_get_temp_dir()
**/
protected static $commonTempPath = '';
/**
* Callable function for URL upload filter
* The first argument is a URL and the second argument is an instance of the elFinder class
* A filter should be return true (to allow) / false (to disallow)
*
* @var callable
* @default null
*/
protected $urlUploadFilter = null;
/**
* Connection flag files path that connection check of current request
*
* @var string
* @default value of $commonTempPath
*/
protected static $connectionFlagsPath = '';
/**
* Additional volume root options for network mounting volume
*
* @var array
*/
protected $optionsNetVolumes = array();
/**
* Session key of net mount volumes
*
* @deprecated
* @var string
*/
protected $netVolumesSessionKey = '';
/**
* Mounted volumes count
* Required to create unique volume id
*
* @var int
**/
public static $volumesCnt = 1;
/**
* Default root (storage)
*
* @var elFinderVolumeDriver
**/
protected $default = null;
/**
* Commands and required arguments list
*
* @var array
**/
protected $commands = array(
'abort' => array('id' => true),
'archive' => array('targets' => true, 'type' => true, 'mimes' => false, 'name' => false),
'callback' => array('node' => true, 'json' => false, 'bind' => false, 'done' => false),
'chmod' => array('targets' => true, 'mode' => true),
'dim' => array('target' => true, 'substitute' => false),
'duplicate' => array('targets' => true, 'suffix' => false),
'editor' => array('name' => true, 'method' => true, 'args' => false),
'extract' => array('target' => true, 'mimes' => false, 'makedir' => false),
'file' => array('target' => true, 'download' => false, 'cpath' => false, 'onetime' => false),
'get' => array('target' => true, 'conv' => false),
'info' => array('targets' => true, 'compare' => false),
'ls' => array('target' => true, 'mimes' => false, 'intersect' => false),
'mkdir' => array('target' => true, 'name' => false, 'dirs' => false),
'mkfile' => array('target' => true, 'name' => true, 'mimes' => false),
'netmount' => array('protocol' => true, 'host' => true, 'path' => false, 'port' => false, 'user' => false, 'pass' => false, 'alias' => false, 'options' => false),
'open' => array('target' => false, 'tree' => false, 'init' => false, 'mimes' => false, 'compare' => false),
'parents' => array('target' => true, 'until' => false),
'paste' => array('dst' => true, 'targets' => true, 'cut' => false, 'mimes' => false, 'renames' => false, 'hashes' => false, 'suffix' => false),
'put' => array('target' => true, 'content' => '', 'mimes' => false, 'encoding' => false),
'rename' => array('target' => true, 'name' => true, 'mimes' => false, 'targets' => false, 'q' => false),
'resize' => array('target' => true, 'width' => false, 'height' => false, 'mode' => false, 'x' => false, 'y' => false, 'degree' => false, 'quality' => false, 'bg' => false),
'rm' => array('targets' => true),
'search' => array('q' => true, 'mimes' => false, 'target' => false, 'type' => false),
'size' => array('targets' => true),
'subdirs' => array('targets' => true),
'tmb' => array('targets' => true),
'tree' => array('target' => true),
'upload' => array('target' => true, 'FILES' => true, 'mimes' => false, 'html' => false, 'upload' => false, 'name' => false, 'upload_path' => false, 'chunk' => false, 'cid' => false, 'node' => false, 'renames' => false, 'hashes' => false, 'suffix' => false, 'mtime' => false, 'overwrite' => false, 'contentSaveId' => false),
'url' => array('target' => true, 'options' => false),
'zipdl' => array('targets' => true, 'download' => false)
);
/**
* Plugins instance
*
* @var array
**/
protected $plugins = array();
/**
* Commands listeners
*
* @var array
**/
protected $listeners = array();
/**
* script work time for debug
*
* @var string
**/
protected $time = 0;
/**
* Is elFinder init correctly?
*
* @var bool
**/
protected $loaded = false;
/**
* Send debug to client?
*
* @var string
**/
protected $debug = false;
/**
* Call `session_write_close()` before exec command?
*
* @var bool
*/
protected $sessionCloseEarlier = true;
/**
* SESSION use commands @see __construct()
*
* @var array
*/
protected $sessionUseCmds = array();
/**
* session expires timeout
*
* @var int
**/
protected $timeout = 0;
/**
* Temp dir path for Upload
*
* @var string
*/
protected $uploadTempPath = '';
/**
* Max allowed archive files size (0 - no limit)
*
* @var integer
*/
protected $maxArcFilesSize = 0;
/**
* undocumented class variable
*
* @var string
**/
protected $uploadDebug = '';
/**
* Max allowed numbar of targets (0 - no limit)
*
* @var integer
*/
public $maxTargets = 1000;
/**
* Errors from PHP
*
* @var array
**/
public static $phpErrors = array();
/**
* Errors from not mounted volumes
*
* @var array
**/
public $mountErrors = array();
/**
* Archivers cache
*
* @var array
*/
public static $archivers = array();
/**
* URL for callback output window for CORS
* redirect to this URL when callback output
*
* @var string URL
*/
protected $callbackWindowURL = '';
/**
* hash of items to unlock on command completion
*
* @var array hashes
*/
protected $autoUnlocks = array();
/**
* Item locking expiration (seconds)
* Default: 3600 secs
*
* @var integer
*/
protected $itemLockExpire = 3600;
/**
* Additional request querys
*
* @var array|null
*/
protected $customData = null;
/**
* Ids to remove of session var "urlContentSaveIds" for contents uploading by URL
*
* @var array
*/
protected $removeContentSaveIds = array();
/**
* LAN class allowed when uploading via URL
*
* Array keys are 'local', 'private_a', 'private_b', 'private_c' and 'link'
*
* local: 127.0.0.0/8
* private_a: 10.0.0.0/8
* private_b: 172.16.0.0/12
* private_c: 192.168.0.0/16
* link: 169.254.0.0/16
*
* @var array
*/
protected $uploadAllowedLanIpClasses = array();
/**
* Flag of throw Error on exec()
*
* @var boolean
*/
protected $throwErrorOnExec = false;
/**
* Default params of toastParams
*
* @var array
*/
protected $toastParamsDefault = array(
'mode' => 'warning',
'prefix' => ''
);
/**
* Toast params of runtime notification
*
* @var array
*/
private $toastParams = array();
/**
* Toast messages of runtime notification
*
* @var array
*/
private $toastMessages = array();
/**
* Optional UTF-8 encoder
*
* @var callable || null
*/
private $utf8Encoder = null;
/**
* Seekable URL file pointer ids - for getStreamByUrl()
*
* @var array
*/
private static $seekableUrlFps = array();
// Errors messages
const ERROR_ACCESS_DENIED = 'errAccess';
const ERROR_ARC_MAXSIZE = 'errArcMaxSize';
const ERROR_ARC_SYMLINKS = 'errArcSymlinks';
const ERROR_ARCHIVE = 'errArchive';
const ERROR_ARCHIVE_EXEC = 'errArchiveExec';
const ERROR_ARCHIVE_TYPE = 'errArcType';
const ERROR_CONF = 'errConf';
const ERROR_CONF_NO_JSON = 'errJSON';
const ERROR_CONF_NO_VOL = 'errNoVolumes';
const ERROR_CONV_UTF8 = 'errConvUTF8';
const ERROR_COPY = 'errCopy';
const ERROR_COPY_FROM = 'errCopyFrom';
const ERROR_COPY_ITSELF = 'errCopyInItself';
const ERROR_COPY_TO = 'errCopyTo';
const ERROR_CREATING_TEMP_DIR = 'errCreatingTempDir';
const ERROR_DIR_NOT_FOUND = 'errFolderNotFound';
const ERROR_EXISTS = 'errExists'; // 'File named "$1" already exists.'
const ERROR_EXTRACT = 'errExtract';
const ERROR_EXTRACT_EXEC = 'errExtractExec';
const ERROR_FILE_NOT_FOUND = 'errFileNotFound'; // 'File not found.'
const ERROR_FTP_DOWNLOAD_FILE = 'errFtpDownloadFile';
const ERROR_FTP_MKDIR = 'errFtpMkdir';
const ERROR_FTP_UPLOAD_FILE = 'errFtpUploadFile';
const ERROR_INV_PARAMS = 'errCmdParams';
const ERROR_INVALID_DIRNAME = 'errInvDirname'; // 'Invalid folder name.'
const ERROR_INVALID_NAME = 'errInvName'; // 'Invalid file name.'
const ERROR_LOCKED = 'errLocked'; // '"$1" is locked and can not be renamed, moved or removed.'
const ERROR_MAX_TARGTES = 'errMaxTargets'; // 'Max number of selectable items is $1.'
const ERROR_MKDIR = 'errMkdir';
const ERROR_MKFILE = 'errMkfile';
const ERROR_MKOUTLINK = 'errMkOutLink'; // 'Unable to create a link to outside the volume root.'
const ERROR_MOVE = 'errMove';
const ERROR_NETMOUNT = 'errNetMount';
const ERROR_NETMOUNT_FAILED = 'errNetMountFailed';
const ERROR_NETMOUNT_NO_DRIVER = 'errNetMountNoDriver';
const ERROR_NETUNMOUNT = 'errNetUnMount';
const ERROR_NOT_ARCHIVE = 'errNoArchive';
const ERROR_NOT_DIR = 'errNotFolder';
const ERROR_NOT_FILE = 'errNotFile';
const ERROR_NOT_REPLACE = 'errNotReplace'; // Object "$1" already exists at this location and can not be replaced with object of another type.
const ERROR_NOT_UTF8_CONTENT = 'errNotUTF8Content';
const ERROR_OPEN = 'errOpen';
const ERROR_PERM_DENIED = 'errPerm';
const ERROR_REAUTH_REQUIRE = 'errReauthRequire'; // 'Re-authorization is required.'
const ERROR_RENAME = 'errRename';
const ERROR_REPLACE = 'errReplace'; // 'Unable to replace "$1".'
const ERROR_RESIZE = 'errResize';
const ERROR_RESIZESIZE = 'errResizeSize';
const ERROR_RM = 'errRm'; // 'Unable to remove "$1".'
const ERROR_RM_SRC = 'errRmSrc'; // 'Unable remove source file(s)'
const ERROR_SAVE = 'errSave';
const ERROR_SEARCH_TIMEOUT = 'errSearchTimeout'; // 'Timed out while searching "$1". Search result is partial.'
const ERROR_SESSION_EXPIRES = 'errSessionExpires';
const ERROR_TRGDIR_NOT_FOUND = 'errTrgFolderNotFound'; // 'Target folder "$1" not found.'
const ERROR_UNKNOWN = 'errUnknown';
const ERROR_UNKNOWN_CMD = 'errUnknownCmd';
const ERROR_UNSUPPORT_TYPE = 'errUsupportType';
const ERROR_UPLOAD = 'errUpload'; // 'Upload error.'
const ERROR_UPLOAD_FILE = 'errUploadFile'; // 'Unable to upload "$1".'
const ERROR_UPLOAD_FILE_MIME = 'errUploadMime'; // 'File type not allowed.'
const ERROR_UPLOAD_FILE_SIZE = 'errUploadFileSize'; // 'File exceeds maximum allowed size.'
const ERROR_UPLOAD_NO_FILES = 'errUploadNoFiles'; // 'No files found for upload.'
const ERROR_UPLOAD_TEMP = 'errUploadTemp'; // 'Unable to make temporary file for upload.'
const ERROR_UPLOAD_TOTAL_SIZE = 'errUploadTotalSize'; // 'Data exceeds the maximum allowed size.'
const ERROR_UPLOAD_TRANSFER = 'errUploadTransfer'; // '"$1" transfer error.'
const ERROR_MAX_MKDIRS = 'errMaxMkdirs'; // 'You can create up to $1 folders at one time.'
/**
* Constructor
*
* @param array elFinder and roots configurations
*
* @author Dmitry (dio) Levashov
*/
public function __construct($opts)
{
// set default_charset
if (version_compare(PHP_VERSION, '5.6', '>=')) {
if (($_val = ini_get('iconv.internal_encoding')) && strtoupper($_val) !== 'UTF-8') {
ini_set('iconv.internal_encoding', '');
}