diff --git a/Assets/Connector/FileManager.php b/Assets/Connector/FileManager.php old mode 100644 new mode 100755 index f9ef84b..c2d1df9 --- a/Assets/Connector/FileManager.php +++ b/Assets/Connector/FileManager.php @@ -15,7 +15,7 @@ * * Copyright: * Copyright (c) 2009-2011 [Christoph Pojer](http://cpojer.net) - * Backend: FileManager & FMgr4Alias Copyright (c) 2011 [Ger Hobbelt](http://hobbelt.com) + * Backend: FileManager & FileManagerWithAliasSupport Copyright (c) 2011 [Ger Hobbelt](http://hobbelt.com) * * Dependencies: * - Tooling.php @@ -23,23 +23,25 @@ * - getId3 Library * * Options: - * - directory: (string) The URI base directory to be used for the FileManager ('URI path' i.e. an absolute path here would be rooted at DocumentRoot: '/' == DocumentRoot) - * - assetBasePath: (string, optional) The URI path to all images and swf files used by the filemanager + * - documentRootPath: (string) The URI base directory to be used for the FileManager ('URI path' i.e. an absolute path here would be rooted at DocumentRoot: '/' == DocumentRoot) + * - assetPath: (string, optional) The URI path to all images and swf files used by the filemanager * - thumbnailPath: (string) The URI path where the thumbnails of the pictures will be saved - * - mimeTypesPath: (string, optional) The filesystem path to the MimeTypes.ini file. May exist in a place outside the DocumentRoot tree. + * - thumbSmallSize: (integer) The (maximum) width / height in pixels of the thumb48 'small' thumbnails produced by this backend + * - thumbBigSize: (integer) The (maximum) width / height in pixels of the thumb250 'big' thumbnails produced by this backend + * - mimeTypesFilePath: (string, optional) The filesystem path to the MimeTypes.ini file. May exist in a place outside the DocumentRoot tree. * - dateFormat: (string, defaults to *j M Y - H:i*) The format in which dates should be displayed * - maxUploadSize: (integer, defaults to *20280000* bytes) The maximum file size for upload in bytes * - maxImageDimension: (array, defaults to *array('width' => 1024, 'height' => 768)*) The maximum number of pixels in height and width an image can have, if the user enables "resize on upload". - * - upload: (boolean, defaults to *false*) allow uploads, this is also set in the FileManager.js (this here is only for security protection when uploads should be deactivated) - * - destroy: (boolean, defaults to *false*) allow files to get deleted, this is also set in the FileManager.js (this here is only for security protection when file/directory delete operations should be deactivated) - * - create: (boolean, defaults to *false*) allow creating new subdirectories, this is also set in the FileManager.js (this here is only for security protection when dir creates should be deactivated) - * - move: (boolean, defaults to *false*) allow file and directory move/rename and copy, this is also set in the FileManager.js (this here is only for security protection when rename/move/copy should be deactivated) - * - download: (boolean, defaults to *false*) allow downloads, this is also set in the FileManager.js (this here is only for security protection when downloads should be deactivated) - * - allowExtChange: (boolean, defaults to *false*) allow the file extension to be changed when performing a rename operation. - * - safe: (boolean, defaults to *true*) If true, disallows 'exe', 'dll', 'php', 'php3', 'php4', 'php5', 'phps' and saves them as 'txt' instead. + * - upload: (boolean, defaults to *FALSE*) allow uploads, this is also set in the FileManager.js (this here is only for security protection when uploads should be deactivated) + * - destroy: (boolean, defaults to *FALSE*) allow files to get deleted, this is also set in the FileManager.js (this here is only for security protection when file/directory delete operations should be deactivated) + * - create: (boolean, defaults to *FALSE*) allow creating new subdirectories, this is also set in the FileManager.js (this here is only for security protection when dir creates should be deactivated) + * - move: (boolean, defaults to *FALSE*) allow file and directory move/rename and copy, this is also set in the FileManager.js (this here is only for security protection when rename/move/copy should be deactivated) + * - download: (boolean, defaults to *FALSE*) allow downloads, this is also set in the FileManager.js (this here is only for security protection when downloads should be deactivated) + * - allowExtChange: (boolean, defaults to *FALSE*) allow the file extension to be changed when performing a rename operation. + * - safe: (boolean, defaults to *TRUE*) If TRUE, disallows 'exe', 'dll', 'php', 'php3', 'php4', 'php5', 'phps' and saves them as 'txt' instead. * - chmod: (integer, default is 0777) the permissions set to the uploaded files and created thumbnails (must have a leading "0", e.g. 0777) * - filter: (string, defaults to *null*) If not empty, this is a list of allowed mimetypes (overruled by the GET request 'filter' parameter: single requests can thus overrule the common setup in the constructor for this option) - * - showHiddenFoldersAndFiles: (boolean, defaults to *false*) whether or not to show 'dotted' directories and files -- such files are considered 'hidden' on UNIX file systems + * - showHiddenFoldersAndFiles: (boolean, defaults to *FALSE*) whether or not to show 'dotted' directories and files -- such files are considered 'hidden' on UNIX file systems * - ViewIsAuthorized_cb (function/reference, default is *null*) authentication + authorization callback which can be used to determine whether the given directory may be viewed. * The parameter $action = 'view'. * - DetailIsAuthorized_cb (function/reference, default is *null*) authentication + authorization callback which can be used to determine whether the given file may be inspected (and the details listed). @@ -56,480 +58,55 @@ * Note that currently support for copying subdirectories is missing. * The parameter $action = 'move'. * - * Obsoleted options: - * - maxImageSize: (integer, default is 1024) The maximum number of pixels in both height and width an image can have, if the user enables "resize on upload". (This option is obsoleted by the 'suggestedMaxImageDimension' option.) * - * - * About the action permissions (upload|destroy|create|move|download): - * - * All the option "permissions" are set to FALSE by default. Developers should always SPECIFICALLY enable a permission to have that permission, for two reasons: - * - * 1. Developers forget to disable permissions, they don't forget to enable them (because things don't work!) - * - * 2. Having open permissions by default leaves potential for security vulnerabilities where those open permissions are exploited. - * - * - * For all authorization hooks (callback functions) the following applies: - * - * The callback should return TRUE for yes (permission granted), FALSE for no (permission denied). - * Parameters sent to the callback are: - * ($this, $action, $fileinfo) - * where $fileinfo is an array containing info about the file being uploaded, $action is a (string) identifying the current operation, $this is a reference to this FileManager instance. - * $action was included as a redundant parameter to each callback as a simple means to allow users to hook a single callback function to all the authorization hooks, without the need to create a wrapper function for each. - * - * For more info about the hook parameter $fileinfo contents and a basic implementation, see further below (section 'Hooks: Detailed Interface Specification') and the examples in - * Demos/FM-common.php, Demos/manager.php and Demos/selectImage.php - * - * - * Notes on relative paths and safety / security: - * - * If any option is specifying a relative path, e.g. '../Assets' or 'Media/Stuff/', this is assumed to be relative to the request URI path, - * i.e. dirname($_SERVER['SCRIPT_NAME']). - * - * Requests may post/submit relative paths as arguments to their FileManager events/actions in $_GET/$_POST, and those relative paths will be - * regarded as relative to the request URI handling script path, i.e. dirname($_SERVER['SCRIPT_NAME']) to make the most - * sense from bother server and client coding perspective. - * - * - * We also assume that any of the paths may be specified from the outside, so each path is processed and filtered to prevent malicious intent - * from succeeding. (An example of such would be an attacker posting his own 'destroy' event request requesting the destruction of - * '../../../../../../../../../etc/passwd' for example. In more complex rigs, the attack may be assisted through attacks at these options' paths, - * so these are subjected to the same scrutiny in here.) - * - * All paths, absolute or relative, as passed to the event handlers (see the onXXX methods of this class) are ENFORCED TO ABIDE THE RULE - * 'every path resides within the options['directory'] a.k.a. BASEDIR rooted tree' without exception. - * Because we can do without exceptions to important rules. ;-) - * - * When paths apparently don't, they are coerced into adherence to this rule; when this fails, an exception is thrown internally and an error - * will be reported and the action temrinated. - * - * 'LEGAL URL paths': - * - * Paths which adhere to the aforementioned rule are so-called LEGAL URL paths; their 'root' equals BASEDIR. - * - * BASEDIR equals the path pointed at by the options['directory'] setting. It is therefore imperative that you ensure this value is - * correctly set up; worst case, this setting will equal DocumentRoot. - * In other words: you'll never be able to reach any file or directory outside this site's DocumentRoot directory tree, ever. - * - * - * Path transformations: - * - * To allow arbitrary directory/path mapping algorithms to be applied (e.g. when implementing Alias support such as available in the - * derived class FileManagerWithAliasSupport), all paths are, on every change/edit, transformed from their LEGAL URL representation to - * their 'absolute URI path' (which is suitable to be used in links and references in HTML output) and 'absolute physical filesystem path' - * equivalents. - * By enforcing such a unidirectional transformation we implicitly support non-reversible and hard-to-reverse path aliasing mechanisms, - * e.g. complex regex+context based path manipulations in the server. - * - * - * When you need your paths to be restricted to the bounds of the options['directory'] tree (which is a subtree of the DocumentRoot based - * tree), you may wish to use the 'legal' class of path transformation member functions: - * - * - legal2abs_url_path() - * - rel2abs_legal_url_path() - * - legal_url_path2file_path() - * - * When you have a 'absolute URI path' or a path relative in URI space (implicitly relative to dirname($_SERVER['SCRIPT_NAME']) ), you can - * transform such a path to either a guaranteed-absolute URI space path or a filesystem path: - * - * - rel2abs_url_path() - * - url_path2file_path() - * - * Any other path transformations are ILLEGAL and DANGEROUS. The only other possibly legal transformation is from absolute URI path to - * BASEDIR-based LEGAL URL path, as the URI path space is assumed to be linear and contiguous. However, this operation is HIGHLY discouraged - * as it is a very strong indicator of other faulty logic, so we do NOT offer a method for this. - * - * - * Hooks: Detailed Interface Specification: - * - * All 'authorization' callback hooks share a common interface specification (function parameter set). This is by design, so one callback - * function can be used to process any and all of these events: - * - * Function prototype: - * - * function CallbackFunction($mgr, $action, &$info) - * - * where - * - * $msg: (object) reference to the current FileManager class instance. Can be used to invoke public FileManager methods inside - * the callback. - * - * $action: (string) identifies the event being processed. Can be one of these: - * - * 'create' create new directory - * 'move' move or copy a file or directory - * 'destroy' delete a file or directory - * 'upload' upload a single file (when performing a bulk upload, each file will be uploaded individually) - * 'download' download a file - * 'view' show a directory listing (in either 'list' or 'thumb' mode) - * 'detail' show detailed information about the file and, whn possible, provide a link to a (largish) thumbnail - * - * $info (array) carries all the details. Some of which can even be manipulated if your callbac is more than just an - * authentication / authorization checker. ;-) - * For more detail, see the next major section. - * - * The callback should return a boolean, where TRUE means the session/client is authorized to execute the action, while FALSE - * will cause the backend to report an authentication error and abort the action. - * - * Exceptions throwing from the callback: - * - * Note that you may choose to throw exceptions from inside the callback; those will be caught and transformed to proper error reports. - * - * You may either throw any exceptions based on either the FileManagerException or Exception classes. When you format the exception - * message as "XYZ:data", where 'XYZ' is a alphanumeric-only word, this will be transformed to a i18n-support string, where - * 'backend.XYZ' must map to a translation string (e.g. 'backend.nofile', see also the Language/Language.XX.js files) and the optional - * 'data' tail will be appended to the translated message. - * - * - * $info: the details: - * - * Here is the list of $info members per $action event code: - * - * 'upload': - * - * $info[] contains: - * - * 'legal_dir_url' (string) LEGAL URI path to the directory where the file is being uploaded. You may invoke - * $dir = $mgr->legal_url_path2file_path($legal_dir_url); - * to obtain the physical filesystem path (also available in the 'dir' $info entry, by the way!), or - * $dir_url = $mgr->legal2abs_url_path($legal_dir_url); - * to obtain the absolute URI path for the given directory. - * - * 'dir' (string) physical filesystem path to the directory where the file is being uploaded. - * - * 'raw_filename' (string) the raw, unprocessed filename of the file being being uploaded, as specified by the client. - * - * WARNING: 'raw_filename' may contain anything illegal, such as directory paths instead of just a filename, - * filesystem-illegal characters and what-not. Use 'name'+'extension' instead if you want to know - * where the upload will end up. - * - * 'filename' (string) the filename, plus extension, of the file being uploaded; this filename is ensured - * to be both filesystem-legal, unique and not yet existing in the given directory. - * - * Note that the file name extension has already been cleaned, including 'safe' mode processing, - * i.e. any uploaded binary executable will have been assigned the extension '.txt' already, when - * FileManager's options['safe'] is enabled. - * - * 'tmp_filepath' (string) filesystem path pointing at the temporary storage location of the uploaded file: you can - * access the file data available here to optionally validate the uploaded content. - * - * 'meta_data' (array) the content sniffed infor as produced by getID3 - * - * 'mime' (string) the mime type as sniffed from the file - * - * 'mime_filter' (optional, string) mime filter as specified by the client: a comma-separated string containing - * full or partial mime types, where a 'partial' mime types is the part of a mime type before - * and including the slash, e.g. 'image/' - * - * 'mime_filters' (optional, array of strings) the set of allowed mime types, derived from the 'mime_filter' setting. - * - * 'size' (integer) number of bytes of the uploaded file - * - * 'maxsize' (integer) the configured maximum number of bytes for any single upload - * - * 'overwrite' (boolean) FALSE: the uploaded file will not overwrite any existing file, it will fail instead. - * - * Set to TRUE (and adjust the 'name' and 'extension' entries as you desire) when you wish to overwrite - * an existing file. - * - * 'resize' (boolean) TRUE: any uploaded images are resized to the configured maximum dimensions before they - * are stored on disk. - * - * 'chmod' (integer) UNIX access rights (default: 0666) for the file-to-be-created (RW for user,group,world). - * - * Note that the eXecutable bits have already been stripped before the callback was invoked. - * - * 'preliminary_json' (array) the JSON data collected so far; when ['status']==1, then we're performing a regular upload - * operation, when the ['status']==0, we are performing a defective upload operation. - * - * 'validation_failure' (string) NULL: no validation error has been detected before the callback was invoked; non-NULL, e.g. - * "nofile": the string passed as message parameter of the FileManagerException, which will be thrown - * after the callback has returned. (You may alter the 'validation_failure' string value to change the - * reported error, or set it to NULL to turn off the validation error report entirely -- we assume you - * will have corrected the other fileinfo[] items as well, when resetting the validation error. - * - * - * Note that this request originates from a Macromedia Flash client: hence you'll need to use the - * $_POST[session_name()] value to manually set the PHP session_id() before you start your your session - * again. - * - * The frontend-specified options.propagateData items will be available as $_POST[] items. - * - * The frontend-specified options.uploadAuthData items will be available as $_POST[] items. - * - * - * 'download': - * - * $info[] contains: - * - * 'legal_url' (string) LEGAL URI path to the file to be downloaded. You may invoke - * $dir = $mgr->legal_url_path2file_path($legal_url); - * to obtain the physical filesystem path (also available in the 'file' $info entry, by the way!), or - * $url = $mgr->legal2abs_url_path($legal_url); - * to obtain the absolute URI path for the given file. - * - * 'file' (string) physical filesystem path to the file being downloaded. - * - * 'meta_data' (array) the content sniffed infor as produced by getID3 - * - * 'mime' (string) the mime type as sniffed from the file - * - * 'mime_filter' (optional, string) mime filter as specified by the client: a comma-separated string containing - * full or partial mime types, where a 'partial' mime types is the part of a mime type before - * and including the slash, e.g. 'image/' - * - * 'mime_filters' (optional, array of strings) the set of allowed mime types, derived from the 'mime_filter' setting. - * - * 'validation_failure' (string) NULL: no validation error has been detected before the callback was invoked; non-NULL, e.g. - * "nofile": the string passed as message parameter of the FileManagerException, which will be thrown - * after the callback has returned. (You may alter the 'validation_failure' string value to change the - * reported error, or set it to NULL to turn off the validation error report entirely -- we assume you - * will have corrected the other fileinfo[] items as well, when resetting the validation error. - * - * The frontend-specified options.propagateData items will be available as $_POST[] items. - * - * - * 'create': // create directory - * - * $info[] contains: - * - * 'legal_url' (string) LEGAL URI path to the parent directory of the directory being created. You may invoke - * $dir = $mgr->legal_url_path2file_path($legal_url); - * to obtain the physical filesystem path (also available in the 'dir' $info entry, by the way!), or - * $url = $mgr->legal2abs_url_path($legal_url); - * to obtain the absolute URI path for this parent directory. - * - * 'dir' (string) physical filesystem path to the parent directory of the directory being created. - * - * 'raw_name' (string) the name of the directory to be created, as specified by the client (unfiltered!) - * - * 'uniq_name' (string) the name of the directory to be created, filtered and ensured to be both unique and - * not-yet-existing in the filesystem. - * - * 'newdir' (string) the filesystem absolute path to the directory to be created; identical to: - * $newdir = $mgr->legal_url_path2file_path($legal_url . $uniq_name); - * Note the above: all paths are transformed from URI space to physical disk every time a change occurs; - * this allows us to map even not-existing 'directories' to possibly disparate filesystem locations. - * - * 'chmod' (integer) UNIX access rights (default: 0777) for the directory-to-be-created (RWX for user,group,world) - * - * 'preliminary_json' (array) the JSON data collected so far; when ['status']==1, then we're performing a regular 'create' - * operation, when the ['status']==0, we are performing a defective 'create' operation. - * - * 'validation_failure' (string) NULL: no validation error has been detected before the callback was invoked; non-NULL, e.g. - * "nofile": the string passed as message parameter of the FileManagerException, which will be thrown - * after the callback has returned. (You may alter the 'validation_failure' string value to change the - * reported error, or set it to NULL to turn off the validation error report entirely -- we assume you - * will have corrected the other fileinfo[] items as well, when resetting the validation error. - * - * The frontend-specified options.propagateData items will be available as $_POST[] items. - * - * - * 'destroy': - * - * $info[] contains: - * - * 'legal_url' (string) LEGAL URI path to the file/directory to be deleted. You may invoke - * $dir = $mgr->legal_url_path2file_path($legal_url); - * to obtain the physical filesystem path (also available in the 'file' $info entry, by the way!), or - * $url = $mgr->legal2abs_url_path($legal_url); - * to obtain the absolute URI path for the given file/directory. - * - * 'file' (string) physical filesystem path to the file/directory being deleted. - * - * 'meta_data' (array) the content sniffed infor as produced by getID3 - * - * 'mime' (string) the mime type as sniffed from the file / directory (directories are mime type: 'text/directory') - * - * 'mime_filter' (optional, string) mime filter as specified by the client: a comma-separated string containing - * full or partial mime types, where a 'partial' mime types is the part of a mime type before - * and including the slash, e.g. 'image/' - * - * 'mime_filters' (optional, array of strings) the set of allowed mime types, derived from the 'mime_filter' setting. - * - * Note that the 'mime_filters', if any, are applied to the 'delete' operation in a special way: only - * files matching one of the mime types in this list will be deleted; anything else will remain intact. - * This can be used to selectively clean a directory tree. - * - * The design idea behind this approach is that you are only allowed what you can see ('view'), so - * all 'view' restrictions should equally to the 'delete' operation. - * - * 'preliminary_json' (array) the JSON data collected so far; when ['status']==1, then we're performing a regular 'destroy' - * operation, when the ['status']==0, we are performing a defective 'destroy' operation. - * - * 'validation_failure' (string) NULL: no validation error has been detected before the callback was invoked; non-NULL, e.g. - * "nofile": the string passed as message parameter of the FileManagerException, which will be thrown - * after the callback has returned. (You may alter the 'validation_failure' string value to change the - * reported error, or set it to NULL to turn off the validation error report entirely -- we assume you - * will have corrected the other fileinfo[] items as well, when resetting the validation error. - * - * The frontend-specified options.propagateData items will be available as $_POST[] items. - * - * - * 'move': // move or copy! - * - * $info[] contains: - * - * 'legal_url' (string) LEGAL URI path to the source parent directory of the file/directory being moved/copied. You may invoke - * $dir = $mgr->legal_url_path2file_path($legal_url); - * to obtain the physical filesystem path (also available in the 'dir' $info entry, by the way!), or - * $url = $mgr->legal2abs_url_path($legal_url); - * to obtain the absolute URI path for the given directory. - * - * 'dir' (string) physical filesystem path to the source parent directory of the file/directory being moved/copied. - * - * 'path' (string) physical filesystem path to the file/directory being moved/copied itself; this is the full source path. - * - * 'name' (string) the name itself of the file/directory being moved/copied; this is the source name. - * - * 'legal_newurl' (string) LEGAL URI path to the target parent directory of the file/directory being moved/copied. You may invoke - * $dir = $mgr->legal_url_path2file_path($legal_url); - * to obtain the physical filesystem path (also available in the 'dir' $info entry, by the way!), or - * $url = $mgr->legal2abs_url_path($legal_url); - * to obtain the absolute URI path for the given directory. - * - * 'newdir' (string) physical filesystem path to the target parent directory of the file/directory being moved/copied; - * this is the full path of the directory where the file/directory will be moved/copied to. (filesystem absolute) - * - * 'newpath' (string) physical filesystem path to the target file/directory being moved/copied itself; this is the full destination path, - * i.e. the full path of where the file/directory should be renamed/moved to. (filesystem absolute) - * - * 'newname' (string) the target name itself of the file/directory being moved/copied; this is the destination name. - * - * This filename is ensured to be both filesystem-legal, unique and not yet existing in the given target directory. - * - * 'rename' (boolean) TRUE when a file/directory RENAME operation is requested (name change, staying within the same - * parent directory). FALSE otherwise. - * - * 'is_dir' (boolean) TRUE when the subject is a directory itself, FALSE when it is a regular file. - * - * 'function' (string) PHP call which will perform the operation. ('rename' or 'copy') - * - * 'preliminary_json' (array) the JSON data collected so far; when ['status']==1, then we're performing a regular 'move' - * operation, when the ['status']==0, we are performing a defective 'move' operation. - * - * 'validation_failure' (string) NULL: no validation error has been detected before the callback was invoked; non-NULL, e.g. - * "nofile": the string passed as message parameter of the FileManagerException, which will be thrown - * after the callback has returned. (You may alter the 'validation_failure' string value to change the - * reported error, or set it to NULL to turn off the validation error report entirely -- we assume you - * will have corrected the other fileinfo[] items as well, when resetting the validation error. - * - * The frontend-specified options.propagateData items will be available as $_POST[] items. - * - * - * 'view': - * - * $info[] contains: - * - * 'legal_url' (string) LEGAL URI path to the directory being viewed/scanned. You may invoke - * $dir = $mgr->legal_url_path2file_path($legal_url); - * to obtain the physical filesystem path (also available in the 'dir' $info entry, by the way!), or - * $url = $mgr->legal2abs_url_path($legal_url); - * to obtain the absolute URI path for the scanned directory. - * - * 'dir' (string) physical filesystem path to the directory being viewed/scanned. - * - * 'collection' (dual array of strings) arrays of files and directories (including '..' entry at the top when this is a - * subdirectory of the FM-managed tree): only names, not full paths. The files array is located at the - * ['files'] index, while the directories are available at the ['dirs'] index. - * - * 'meta_data' (array) the content sniffed infor as produced by getID3 - * - * 'mime_filter' (optional, string) mime filter as specified by the client: a comma-separated string containing - * full or partial mime types, where a 'partial' mime types is the part of a mime type before - * and including the slash, e.g. 'image/' - * - * 'mime_filters' (optional, array of strings) the set of allowed mime types, derived from the 'mime_filter' setting. - * - * 'file_preselect' (optional, string) filename of a file in this directory which should be located and selected. - * When found, the backend will provide an index number pointing at the corresponding JSON files[] - * entry to assist the front-end in jumping to that particular item in the view. - * - * 'preliminary_json' (array) the JSON data collected so far; when ['status']==1, then we're performing a regular view - * operation (possibly as the second half of a copy/move/delete operation), when the ['status']==0, - * we are performing a view operation as the second part of another otherwise failed action, e.g. a - * failed 'create directory'. - * - * 'validation_failure' (string) NULL: no validation error has been detected before the callback was invoked; non-NULL, e.g. - * "nofile": the string passed as message parameter of the FileManagerException, which will be thrown - * after the callback has returned. (You may alter the 'validation_failure' string value to change the - * reported error, or set it to NULL to turn off the validation error report entirely -- we assume you - * will have corrected the other fileinfo[] items as well, when resetting the validation error. - * - * The frontend-specified options.propagateData items will be available as $_POST[] items. - * - * - * 'detail': - * - * $info[] contains: - * - * 'legal_url' (string) LEGAL URI path to the file/directory being inspected. You may invoke - * $dir = $mgr->legal_url_path2file_path($legal_url); - * to obtain the physical filesystem path (also available in the 'file' $info entry, by the way!), or - * $url = $mgr->legal2abs_url_path($legal_url); - * to obtain the absolute URI path for the given file. - * - * 'file' (string) physical filesystem path to the file being inspected. - * - * 'meta_data' (array) the content sniffed infor as produced by getID3 - * - * 'mime' (string) the mime type as sniffed from the file - * - * 'mime_filter' (optional, string) mime filter as specified by the client: a comma-separated string containing - * full or partial mime types, where a 'partial' mime types is the part of a mime type before - * and including the slash, e.g. 'image/' - * - * 'mime_filters' (optional, array of strings) the set of allowed mime types, derived from the 'mime_filter' setting. - * - * 'preliminary_json' (array) the JSON data collected so far; when ['status']==1, then we're performing a regular 'detail' - * operation, when the ['status']==0, we are performing a defective 'detail' operation. - * - * 'validation_failure' (string) NULL: no validation error has been detected before the callback was invoked; non-NULL, e.g. - * "nofile": the string passed as message parameter of the FileManagerException, which will be thrown - * after the callback has returned. (You may alter the 'validation_failure' string value to change the - * reported error, or set it to NULL to turn off the validation error report entirely -- we assume you - * will have corrected the other fileinfo[] items as well, when resetting the validation error. - * - * The frontend-specified options.propagateData items will be available as $_POST[] items. - * - * - * - * Developer Notes: - * - * - member functions which have a commented out 'static' keyword have it removed by design: it makes for easier overloading through - * inheritance that way and meanwhile there's no pressing need to have those (public) member functions acccessible from the outside world - * without having an instance of the FileManager class itself round at the same time. */ // ----------- compatibility checks ---------------------------------------------------------------------------- if (version_compare(PHP_VERSION, '5.2.0') < 0) { // die horribly: server does not match our requirements! - header('HTTP/1.0 500 FileManager requires PHP 5.2.0 or later', true, 500); // Internal server error + header('HTTP/1.0 500 FileManager requires PHP 5.2.0 or later', TRUE, 500); // Internal server error throw Exception('FileManager requires PHP 5.2.0 or later'); // this exception will most probably not be caught; that's our intent! } -if (function_exists('UploadIsAuthenticated')) -{ - // die horribly: user has not upgraded his callback hook(s)! - header('HTTP/1.0 500 FileManager callback has not been upgraded!', true, 500); // Internal server error - throw Exception('FileManager callback has not been upgraded!'); // this exception will most probably not be caught; that's our intent! -} - //------------------------------------------------------------------------------------------------------------- if (!defined('DEVELOPMENT')) define('DEVELOPMENT', 0); // make sure this #define is always known to us - require(strtr(dirname(__FILE__), '\\', '/') . '/Tooling.php'); require(strtr(dirname(__FILE__), '\\', '/') . '/Image.class.php'); require(strtr(dirname(__FILE__), '\\', '/') . '/Assets/getid3/getid3.php'); +/* +require(strtr(dirname(__FILE__), '\\', '/') . '/Filemanager/Tooling.php'); +require(strtr(dirname(__FILE__), '\\', '/') . '/Filemanager/Image.class.php'); +require(strtr(dirname(__FILE__), '\\', '/') . '/getid3/getid3.php'); +*/ + + + + +# Should log to the same directory as this file +require(strtr(dirname(__FILE__), '\\', '/') . '/KLogger.php'); + +/* +$log->logInfo('Info Test'); +$log->logNotice('Notice Test'); +$log->logWarn('Warn Test'); +$log->logError('Error Test'); +$log->logFatal('Fatal Test'); +$log->logAlert('Alert Test'); +$log->logCrit('Crit test'); +$log->logEmerg('Emerg Test'); +*/ + + + // the jpeg quality for the largest thumbnails (smaller ones are automatically done at increasingly higher quality) -define('MTFM_THUMBNAIL_JPEG_QUALITY', 75); +define('MTFM_THUMBNAIL_JPEG_QUALITY', 80); // the number of directory levels in the thumbnail cache; set to 2 when you expect to handle huge image collections. // @@ -542,7 +119,7 @@ define('MTFM_MIN_GETID3_CACHESIZE', 16); // allow MTFM to use finfo_open() to help us produce mime types for files. This is slower than the basic file extension to mimetype mapping -define('MTFM_USE_FINFO_OPEN', false); +define('MTFM_USE_FINFO_OPEN', FALSE); @@ -552,13 +129,6 @@ // flags for clean_ID3info_results() define('MTFM_CLEAN_ID3_STRIP_EMBEDDED_IMAGES', 0x0001); -// 'UsageMode' bits; these work as bit flags: -define('MTFM_USAGE_ASYNC_THUMB250_PRODUCTION', 0x0001); -define('MTFM_USAGE_ASYNC_THUMB48_PRODUCTION', 0x0002); -define('MTFM_USAGE_AGGRESSIVE_META_INFO_CACHING', 0x0004); -// and some aggregates for ease of use: -define('MTFM_USAGE_BASIC', 0); -define('MTFM_USAGE_SPEED_FREAK', MTFM_USAGE_ASYNC_THUMB250_PRODUCTION | MTFM_USAGE_ASYNC_THUMB48_PRODUCTION | MTFM_USAGE_AGGRESSIVE_META_INFO_CACHING); @@ -571,7 +141,7 @@ * * Makes sure the generated (thumbpath) template is unique for each source file ('$legal_url'). We prevent * reduced performance for large file sets: all thumbnails/templates derived from any files in the entire - * FileManager-managed directory tree, rooted by options['directory'], can become a huge collection, + * FileManager-managed directory tree, rooted by options['documentRootPath'], can become a huge collection, * so we distribute them across a (thumbnail/cache) directory tree, which is created on demand. * * The thumbnails cache directory tree is determined by the MD5 of the full path to the source file ($legal_url), @@ -599,23 +169,28 @@ class MTFMCacheItem protected $cache_file; - public function __construct($fm_obj, $legal_url, $prefetch = false, $persistent_edits = true) + public function __construct($fm_obj, $legal_url, $prefetch = FALSE, $persistent_edits = TRUE) { $this->init($fm_obj, $legal_url, $prefetch, $persistent_edits); + + $this->log = KLogger::instance(dirname(__FILE__), KLogger::DEBUG); + + } - public function init($fm_obj, $legal_url, $prefetch = false, $persistent_edits) + public function init($fm_obj, $legal_url, $prefetch = FALSE, $persistent_edits) { - $this->dirty = false; + $this->dirty = FALSE; $this->persistent_edits = $persistent_edits; - $this->loaded = false; + $this->loaded = FALSE; $this->store = array(); $fmopts = $fm_obj->getSettings(); $this->legal_url = $legal_url; - $this->file = $fm_obj->legal_url_path2file_path($legal_url); - $this->fstat = null; +// $this->file = $fm_obj->legal_url_path2file_path($legal_url); + $this->file = $fm_obj->getAbsolutePath($legal_url); + $this->fstat = NULL; $fi = pathinfo($legal_url); if (is_dir($this->file)) @@ -667,7 +242,11 @@ public function init($fm_obj, $legal_url, $prefetch = false, $persistent_edits) $dircode = substr($dircode, 4); $fn = substr($fn . $dircode, 0, 38); - $this->cache_dir_url = $fmopts['thumbnailPath'] . $dir; + $this->cache_dir_url = $fmopts['thumbnailCacheUrl'] . $dir; + + + + $this->cache_dir = $fmopts['thumbnailCacheDir'] . $dir; $this->cache_dir_mode = $fmopts['chmod']; $this->cache_base = $fn; @@ -686,7 +265,7 @@ public function load() { if (!$this->loaded) { - $this->loaded = true; // always mark as loaded, even when the load fails + $this->loaded = TRUE; // always mark as loaded, even when the load fails if (!is_array($this->fstat) && file_exists($this->file)) { @@ -702,7 +281,7 @@ public function load() && $statdata[7] == $this->fstat[7] // size ) { - if (!DEVELOPMENT) + if ( ! DEVELOPMENT) { // mix disk cache data with items already existing in RAM cache: we use a delayed-load scheme which necessitates this. $this->store = array_merge($data, $this->store); @@ -717,9 +296,9 @@ public function load() } } - public function delete($every_ting_baby = false) + public function delete($every_ting_baby = FALSE) { - $rv = true; + $rv = TRUE; $dir = $this->cache_dir; $dir_exists = file_exists($dir); @@ -731,7 +310,7 @@ public function delete($every_ting_baby = false) $dir_and_mask = $dir . $this->cache_base . '*'; $coll = safe_glob($dir_and_mask, GLOB_NODOTS | GLOB_NOSORT); - if ($coll !== false) + if ($coll !== FALSE) { foreach($coll['files'] as $filename) { @@ -759,8 +338,8 @@ public function delete($every_ting_baby = false) } // also clear the data cached in RAM: - $this->dirty = false; - $this->loaded = true; // we know the cache file doesn't exist any longer, so don't bother trying to load it again later on! + $this->dirty = FALSE; + $this->loaded = TRUE; // we know the cache file doesn't exist any longer, so don't bother trying to load it again later on! $this->store = array(); return $rv; @@ -786,9 +365,9 @@ public function __destruct() // legal URL: ' . $this->legal_url . ' -$statdata = ' . var_export($this->fstat, true) . '; +$statdata = ' . var_export($this->fstat, TRUE) . '; -$data = ' . var_export($this->store, true) . ';' . PHP_EOL; +$data = ' . var_export($this->store, TRUE) . ';' . PHP_EOL; @file_put_contents($this->cache_file, $data); } @@ -797,7 +376,7 @@ public function __destruct() /* * @param boolean $persistent (default: TRUE) TRUE when we should also check the persistent cache storage for this item/key */ - public function fetch($key, $persistent = true) + public function fetch($key, $persistent = TRUE) { if (isset($this->store[$key])) { @@ -813,13 +392,13 @@ public function fetch($key, $persistent = true) } } - return null; + return NULL; } /* * @param boolean $persistent (default: TRUE) TRUE when we should also store this item/key in the persistent cache storage */ - public function store($key, $value, $persistent = true) + public function store($key, $value, $persistent = TRUE) { if (isset($this->store[$key])) { @@ -832,13 +411,13 @@ public function store($key, $value, $persistent = true) public function getThumbPath($dimensions) { - assert(!empty($dimensions)); + assert( ! empty($dimensions)); return $this->cache_dir . $this->cache_base . '-' . $dimensions . $this->cache_tnext; } public function getThumbURL($dimensions) { - assert(!empty($dimensions)); + assert( ! empty($dimensions)); return $this->cache_dir_url . $this->cache_base . '-' . $dimensions . $this->cache_tnext; } @@ -846,20 +425,20 @@ public function mkCacheDir() { if (!is_dir($this->cache_dir)) { - @mkdir($this->cache_dir, $this->cache_dir_mode, true); - return true; + @mkdir($this->cache_dir, $this->cache_dir_mode, TRUE); + return TRUE; } - return false; + return FALSE; } public function getMimeType() { - if (!empty($this->store['mime_type'])) + if ( ! empty($this->store['mime_type'])) { return $this->store['mime_type']; } //$mime = $fm_obj->getMimeFromExt($file); - return null; + return NULL; } } @@ -891,9 +470,9 @@ public function __construct($min_cache_size) * * You can store any arbitrary data in a cache slot: it doesn't have to be a MTFMCacheItem instance. */ - public function &pick($key, $fm_obj = null, $create_if_not_exist = true) + public function &pick($key, $fm_obj = NULL, $create_if_not_exist = TRUE) { - assert(!empty($key)); + assert( ! empty($key)); $age_limit = $this->store_lru_ts - $this->min_cache_size; @@ -955,20 +534,20 @@ public function &pick($key, $fm_obj = null, $create_if_not_exist = true) * add this slot (empty for now) to the cache. Only do this AFTER the pruning, so it won't risk being * picked by the random process in there. We _need_ this one right now. ;-) */ - $this->store[$key] = (!empty($fm_obj) ? new MTFMCacheItem($fm_obj, $key) : null); + $this->store[$key] = ( ! empty($fm_obj) ? new MTFMCacheItem($fm_obj, $key) : NULL); $this->store_ts[$key] = $this->store_lru_ts++; } else { // do not clutter the cache; all we're probably after this time is the assistance of a MTFMCacheItem: - // provide a dummy cache entry, nulled and all; we won't be saving the stored data, if any, anyhow. + // provide a dummy cache entry, NULLed and all; we won't be saving the stored data, if any, anyhow. if (isset($this->store['!']) && !empty($fm_obj)) { - $this->store['!']->init($fm_obj, $key, false, false); + $this->store['!']->init($fm_obj, $key, FALSE, FALSE); } else { - $this->store['!'] = (!empty($fm_obj) ? new MTFMCacheItem($fm_obj, $key, false, false) : null); + $this->store['!'] = ( ! empty($fm_obj) ? new MTFMCacheItem($fm_obj, $key, FALSE, FALSE) : NULL); } $this->store_ts['!'] = 0; $key = '!'; @@ -989,186 +568,168 @@ class FileManager protected $options; protected $getid3; protected $getid3_cache; - protected $icon_cache; // cache the icon paths per size (large/small) and file extension + protected $icon_cache; // cache the icon paths per size (large/small) and file extension + protected $documentRootPath; protected $thumbnailCacheDir; - protected $thumbnailCacheParentDir; // assistant precalculated value for scandir/view - protected $managedBaseDir; // precalculated filesystem path eqv. of options['directory'] - + protected $thumbnailCacheParentDir; // assistant precalculated value for scandir/view + protected $managedBaseDir; // precalculated filesystem path eqv. of options['documentRootPath'] + protected $assetPath; // Assets absolute filesystem path + + protected $mimeTypesFilePath; + + public function __construct($options) { + // LOG + $this->log = KLogger::instance(dirname(__FILE__), KLogger::DEBUG); + $this->options = array_merge(array( + /* * Note that all default paths as listed below are transformed to DocumentRoot-based paths * through the getRealPath() invocations further below: */ - 'directory' => null, // the root of the 'legal URI' directory tree, to be managed by MTFM. MUST be in the DocumentRoot tree. - 'assetBasePath' => null, // may sit outside options['directory'] but MUST be in the DocumentRoot tree - 'thumbnailPath' => null, // may sit outside options['directory'] but MUST be in the DocumentRoot tree - 'mimeTypesPath' => strtr(dirname(__FILE__), '\\', '/') . '/MimeTypes.ini', // an absolute filesystem path anywhere; when relative, it will be assumed to be against SERVER['SCRIPT_NAME'] - 'documentRootPath' => null, // an absolute filesystem path pointing at URI path '/'. Default: SERVER['DOCUMENT_ROOT'] + 'requestScript' => NULL, // default is $_SERVER['SCRIPT_NAME'] + + 'baseUrl' => NULL, // an absolute filesystem path pointing at URI path '/'. Default: SERVER['DOCUMENT_ROOT'] + 'documentRootPath' => NULL, // an absolute filesystem path pointing at URI path '/'. Default: SERVER['DOCUMENT_ROOT'] + 'directory' => NULL, // Relative to the the DocumentRoot path. + 'assetPath' => NULL, // may sit outside options['documentRootPath'] but MUST be in the DocumentRoot tree + 'thumbnailPath' => NULL, // may sit outside options['documentRootPath'] but MUST be in the DocumentRoot tree + + 'thumbSmallSize' => 48, // Used for thumb48 creation + 'thumbBigSize' => 250, // Used for thumb250 creation + 'mimeTypesFilePath' => strtr(dirname(__FILE__), '\\', '/') . '/MimeTypes.ini', // an absolute filesystem path anywhere; when relative, it will be assumed to be against options['requestScript'] + 'dateFormat' => 'j M Y - H:i', 'maxUploadSize' => 2600 * 2600 * 3, - // 'maxImageSize' => 99999, // OBSOLETED, replaced by 'suggestedMaxImageDimension' - 'maxImageDimension' => array('width' => 1024, 'height' => 768), // Allow to specify the "Resize Large Images" tolerance level. - 'upload' => false, - 'destroy' => false, - 'create' => false, - 'move' => false, - 'download' => false, - /* ^^^ this last one is easily circumnavigated if it's about images: when you can view 'em, you can 'download' them anyway. - * However, for other mime types which are not previewable / viewable 'in their full bluntal nugity' ;-) , this will - * be a strong deterent. - * - * Think Springer Verlag and PDFs, for instance. You can have 'em, but only /after/ you've ... - */ - 'allowExtChange' => false, - 'safe' => true, - 'filter' => null, + + 'maxImageDimension' => array('width' => 1024, 'height' => 768), // Allow to specify the "Resize Large Images" tolerance level. + 'upload' => FALSE, + 'destroy' => FALSE, + 'create' => FALSE, + 'move' => FALSE, + 'download' => FALSE, + + 'allowExtChange' => FALSE, + 'safe' => TRUE, + 'filter' => NULL, 'chmod' => 0777, - 'ViewIsAuthorized_cb' => null, - 'DetailIsAuthorized_cb' => null, - 'UploadIsAuthorized_cb' => null, - 'DownloadIsAuthorized_cb' => null, - 'CreateIsAuthorized_cb' => null, - 'DestroyIsAuthorized_cb' => null, - 'MoveIsAuthorized_cb' => null, - 'showHiddenFoldersAndFiles' => false, // Hide dot dirs/files ? - 'UsageMode' => MTFM_USAGE_BASIC + 'cleanFileName' => TRUE, + + 'ViewIsAuthorized_cb' => NULL, + 'DetailIsAuthorized_cb' => NULL, + 'UploadIsAuthorized_cb' => NULL, + 'DownloadIsAuthorized_cb' => NULL, + 'CreateIsAuthorized_cb' => NULL, + 'DestroyIsAuthorized_cb' => NULL, + 'MoveIsAuthorized_cb' => NULL, + 'showHiddenFoldersAndFiles' => FALSE // Hide dot dirs/files ? ), (is_array($options) ? $options : array())); - // transform the obsoleted/deprecated options: - if (!empty($this->options['maxImageSize']) && $this->options['maxImageSize'] != 1024 && $this->options['maxImageDimension']['width'] == 1024 && $this->options['maxImageDimension']['height'] == 768) - { - $this->options['maxImageDimension'] = array('width' => $this->options['maxImageSize'], 'height' => $this->options['maxImageSize']); - } - - $assumed_root = null; - if (!empty($this->options['documentRootPath'])) - { + $assumed_root = NULL; + if ( ! empty($this->options['documentRootPath'])) $assumed_root = realpath($this->options['documentRootPath']); - } + if (empty($assumed_root)) - { $assumed_root = realpath($_SERVER['DOCUMENT_ROOT']); - } + $assumed_root = strtr($assumed_root, '\\', '/'); $assumed_root = rtrim($assumed_root, '/'); - $this->options['documentRootPath'] = $assumed_root; - // only calculate the guestimated defaults when they are indeed required: - if ($this->options['directory'] == null || $this->options['assetBasePath'] == null || $this->options['thumbnailPath'] == null) - { - $my_path = @realpath(dirname(__FILE__)); - $my_path = strtr($my_path, '\\', '/'); - if (!FileManagerUtility::endsWith($my_path, '/')) - { - $my_path .= '/'; - } - $my_assumed_url_path = str_replace($assumed_root, '', $my_path); - // we throw an Exception here because when these do not apply, the user should have specified all three these entries! - if (empty($assumed_root) || empty($my_path) || !FileManagerUtility::startsWith($my_path, $assumed_root)) - { - throw new FileManagerException('nofile'); - } - - if ($this->options['directory'] == null) - { - $this->options['directory'] = $my_assumed_url_path . '../../Demos/Files/'; - } - if ($this->options['assetBasePath'] == null) - { - $this->options['assetBasePath'] = $my_assumed_url_path . '../../Demos/Files/../../Assets/'; - } - if ($this->options['thumbnailPath'] == null) - { - $this->options['thumbnailPath'] = $my_assumed_url_path . '../../Demos/Files/../../Assets/Thumbs/'; - } - } - - /* - * make sure we start with a very predictable and LEGAL options['directory'] setting, so that the checks applied to the - * (possibly) user specified value for this bugger acvtually can check out okay AS LONG AS IT'S INSIDE the DocumentRoot-based - * directory tree: - */ - $new_root = $this->options['directory']; - $this->options['directory'] = '/'; // use DocumentRoot temporarily as THE root for this optional transform - $this->options['directory'] = $this->rel2abs_url_path($new_root . '/'); + // apply default to requestScript: + if (empty($this->options['requestScript'])) + $this->options['requestScript'] = $this->getRequestURI(); - $this->managedBaseDir = $this->url_path2file_path($this->options['directory']); + $this->options['thumbnailPath'] = self::addTrailingSlash($this->options['thumbnailPath']); - // now that the correct options['directory'] has been set up, go and check/clean the other paths in the options[]: + $this->baseUrl = $this->options['baseUrl']; + + $this->documentRootPath = self::addTrailingSlash($assumed_root); + + // Assets + $this->options['assetPath'] = self::addTrailingSlash($this->options['assetPath']); + $this->assetPath = self::addTrailingSlash(realpath($this->documentRootPath . $this->options['assetPath'])); + $this->assetUrl = $this->baseUrl . trim($this->options['assetPath'], '/') .'/'; + + $this->managedBaseDir = $this->documentRootPath . trim($this->options['directory'], '/') .'/'; + $this->managedBaseUrl = $this->baseUrl . trim($this->options['directory'], '/') .'/'; - $this->options['thumbnailPath'] = $this->rel2abs_url_path($this->options['thumbnailPath'] . '/'); - $this->thumbnailCacheDir = $this->url_path2file_path($this->options['thumbnailPath']); // precalculate this value; safe as we can assume the entire cache dirtree maps 1:1 to filesystem. - $this->thumbnailCacheParentDir = $this->url_path2file_path(self::getParentDir($this->options['thumbnailPath'])); // precalculate this value as well; used by scandir/view + // By default for the moment + // This way of config allows to change easily the store folder of thumbs if wished + $this->thumbnailCacheDir = $this->documentRootPath . trim($this->options['thumbnailPath'], '/') .'/'; + $this->thumbnailCacheUrl = $this->baseUrl . trim($this->options['thumbnailPath'], '/') .'/'; + $this->thumbnailCacheParentDir = $this->documentRootPath . (self::getParentDir($this->options['thumbnailPath'])); - $this->options['assetBasePath'] = $this->rel2abs_url_path($this->options['assetBasePath'] . '/'); + // Mimes types file + $mimeTypesFilePath = @realpath($this->options['mimeTypesFilePath']); - $this->options['mimeTypesPath'] = @realpath($this->options['mimeTypesPath']); - if (empty($this->options['mimeTypesPath'])) - { + if (empty($mimeTypesFilePath)) throw new FileManagerException('nofile'); - } - $this->options['mimeTypesPath'] = strtr($this->options['mimeTypesPath'], '\\', '/'); + + $this->mimeTypesFilePath = strtr($mimeTypesFilePath, '\\', '/'); // getID3 is slower as it *copies* the image to the temp dir before processing: see GetDataImageSize(). // This is done as getID3 can also analyze *embedded* images, for which this approach is required. $this->getid3 = new getID3(); $this->getid3->setOption(array('encoding' => 'UTF-8')); - //$this->getid3->encoding = 'UTF-8'; - $this->getid3_cache = new MTFMCache(MTFM_MIN_GETID3_CACHESIZE); $this->icon_cache = array(array(), array()); + } - + + /** - * @return array the FileManager options and settings. + * Returns the FileManager options and settings. + * Used by MTFMCacheItem + * + * @return Array Array if settings + * */ public function getSettings() { return array_merge(array( - 'basedir' => $this->url_path2file_path($this->options['directory']), - 'thumbnailCacheDir' => $this->thumbnailCacheDir, - 'thumbnailCacheParentDir' => $this->thumbnailCacheParentDir, - 'managedBaseDir' => $this->managedBaseDir + 'thumbnailCacheUrl' => $this->thumbnailCacheUrl, + 'thumbnailCacheDir' => $this->thumbnailCacheDir, + 'thumbnailCacheParentDir' => $this->thumbnailCacheParentDir, + 'managedBaseDir' => $this->managedBaseDir, + 'chmod' => $this->options['chmod'] ), $this->options); } - - /** * Central entry point for any client side request. */ - public function fireEvent($event = null) + public function fireEvent($event = NULL) { - $event = (!empty($event) ? 'on' . ucfirst($event) : null); + $event = ( ! empty($event) ? 'on' . ucfirst($event) : NULL); if (!$event || !method_exists($this, $event)) $event = 'onView'; $this->{$event}(); } - - - - /** * Generalized 'view' handler, which produces a directory listing. * * Return the directory listing in a nested array, suitable for JSON encoding. */ - protected function _onView($legal_url, $json, $mime_filter, $file_preselect_arg = null, $filemask = '*') + protected function _onView($legal_url, $json, $mime_filter, $file_preselect_arg = NULL, $filemask = '*') { $v_ex_code = 'nofile'; - $dir = $this->legal_url_path2file_path($legal_url); - $doubledot = null; - $coll = null; +// $dir = $this->legal_url_path2file_path($legal_url); + + $dir = $this->managedBaseDir . $legal_url; + + $doubledot = NULL; + $coll = NULL; + if (is_dir($dir)) { /* @@ -1201,8 +762,8 @@ protected function _onView($legal_url, $json, $mime_filter, $file_preselect_arg * Code: TODO */ - $coll = $this->scandir($dir, $filemask, false, 0, ($this->options['showHiddenFoldersAndFiles'] ? ~GLOB_NOHIDDEN : ~0)); - if ($coll !== false) + $coll = $this->scandir($dir, $filemask, FALSE, 0, ($this->options['showHiddenFoldersAndFiles'] ? ~GLOB_NOHIDDEN : ~0)); + if ($coll !== FALSE) { /* * To ensure '..' ends up at the very top of the view, no matter what the other entries in $coll['dirs'][] are made of, @@ -1210,15 +771,15 @@ protected function _onView($legal_url, $json, $mime_filter, $file_preselect_arg * let the sort run. */ $doubledot = array_pop($coll['dirs']); - if ($doubledot !== null && $doubledot !== '..') + if ($doubledot !== NULL && $doubledot !== '..') { $coll['dirs'][] = $doubledot; - $doubledot = null; + $doubledot = NULL; } natcasesort($coll['dirs']); natcasesort($coll['files']); - $v_ex_code = null; + $v_ex_code = NULL; } } @@ -1235,12 +796,12 @@ protected function _onView($legal_url, $json, $mime_filter, $file_preselect_arg 'validation_failure' => $v_ex_code ); - if (!empty($this->options['ViewIsAuthorized_cb']) && function_exists($this->options['ViewIsAuthorized_cb']) && !$this->options['ViewIsAuthorized_cb']($this, 'view', $fileinfo)) + if ( ! empty($this->options['ViewIsAuthorized_cb']) && function_exists($this->options['ViewIsAuthorized_cb']) && !$this->options['ViewIsAuthorized_cb']($this, 'view', $fileinfo)) { $v_ex_code = $fileinfo['validation_failure']; if (empty($v_ex_code)) $v_ex_code = 'authorized'; } - if (!empty($v_ex_code)) + if ( ! empty($v_ex_code)) throw new FileManagerException($v_ex_code); $legal_url = $fileinfo['legal_url']; @@ -1255,9 +816,9 @@ protected function _onView($legal_url, $json, $mime_filter, $file_preselect_arg $out = array(array(), array()); $mime = 'text/directory'; - $iconspec = false; + $iconspec = FALSE; - if ($doubledot !== null) + if ($doubledot !== NULL) { $filename = '..'; @@ -1266,12 +827,17 @@ protected function _onView($legal_url, $json, $mime_filter, $file_preselect_arg // must transform here so alias/etc. expansions inside legal_url_path2file_path() get a chance: $file = $this->legal_url_path2file_path($l_url); +/* +$this->log->logInfo('$l_url : ' . $l_url); +$this->log->logInfo('$file : ' . $file); +*/ + $iconspec = 'is.directory_up'; - $icon48 = $this->getIcon($iconspec, false); + $icon48 = $this->getIcon($iconspec, FALSE); $icon48_e = FileManagerUtility::rawurlencode_path($icon48); - $icon = $this->getIcon($iconspec, true); + $icon = $this->getIcon($iconspec, TRUE); $icon_e = FileManagerUtility::rawurlencode_path($icon); $out[1][] = array( @@ -1286,10 +852,10 @@ protected function _onView($legal_url, $json, $mime_filter, $file_preselect_arg // now precalc the directory-common items (a.k.a. invariant computation / common subexpression hoisting) $iconspec_d = 'is.directory'; - $icon48_d = $this->getIcon($iconspec_d, false); + $icon48_d = $this->getIcon($iconspec_d, FALSE); $icon48_de = FileManagerUtility::rawurlencode_path($icon48_d); - $icon_d = $this->getIcon($iconspec_d, true); + $icon_d = $this->getIcon($iconspec_d, TRUE); $icon_de = FileManagerUtility::rawurlencode_path($icon_d); foreach ($coll['dirs'] as $filename) @@ -1336,10 +902,10 @@ protected function _onView($legal_url, $json, $mime_filter, $file_preselect_arg * For now, simply assign a basic icon to any and all; the 'detail' event will replace this item in the frontend * when the time has arrives when that 'detail' request has been answered. */ - $icon48 = $this->getIcon($iconspec, false); + $icon48 = $this->getIcon($iconspec, FALSE); $icon48_e = FileManagerUtility::rawurlencode_path($icon48); - $icon = $this->getIcon($iconspec, true); + $icon = $this->getIcon($iconspec, TRUE); $icon_e = FileManagerUtility::rawurlencode_path($icon); $out[0][] = array( @@ -1347,7 +913,7 @@ protected function _onView($legal_url, $json, $mime_filter, $file_preselect_arg 'name' => $filename, 'mime' => $mime, // we don't know the thumbnail paths yet --> this will trigger deferred requests: (event=detail, mode=direct) - 'thumbs_deferred' => true, + 'thumbs_deferred' => TRUE, 'icon48' => $icon48_e, 'icon' => $icon_e ); @@ -1355,20 +921,20 @@ protected function _onView($legal_url, $json, $mime_filter, $file_preselect_arg } return array_merge((is_array($json) ? $json : array()), array( - 'root' => substr($this->options['directory'], 1), - 'this_dir' => array( - 'path' => $legal_url, - 'name' => basename($legal_url), - 'date' => date($this->options['dateFormat'], @filemtime($dir)), - 'mime' => 'text/directory', - 'icon48' => $icon48_de, - 'icon' => $icon_de - ), - 'preselect_index' => ($file_preselect_index >= 0 ? $file_preselect_index + count($out[1]) + 1 : 0), - 'preselect_name' => ($file_preselect_index >= 0 ? $file_preselect_arg : null), - 'dirs' => $out[1], - 'files' => $out[0] - )); + 'root' => substr($this->documentRootPath, 1), + 'this_dir' => array( + 'path' => $legal_url, + 'name' => basename($legal_url), + 'date' => date($this->options['dateFormat'], @filemtime($dir)), + 'mime' => 'text/directory', + 'icon48' => $icon48_de, + 'icon' => $icon_de + ), + 'preselect_index' => ($file_preselect_index >= 0 ? $file_preselect_index + count($out[1]) + 1 : 0), + 'preselect_name' => ($file_preselect_index >= 0 ? $file_preselect_arg : NULL), + 'dirs' => $out[1], + 'files' => $out[0] + )); } /** @@ -1378,7 +944,7 @@ protected function _onView($legal_url, $json, $mime_filter, $file_preselect_arg * * Expected parameters: * - * $_POST['directory'] path relative to basedir a.k.a. options['directory'] root + * $_POST['directory'] path relative to basedir a.k.a. options['documentRootPath'] root * * $_POST['file_preselect'] optional filename or path: * when a filename, this is the filename of a file in this directory @@ -1400,9 +966,9 @@ protected function _onView($legal_url, $json, $mime_filter, $file_preselect_arg * transforms them to LEGAL URI paths. * * When the specified path is illegal, i.e. does not reside inside the - * options['directory']-rooted LEGAL URI subtree, it will be discarded + * options['documentRootPath']-rooted LEGAL URI subtree, it will be discarded * entirely (as all file paths, whether they are absolute or relative, - * must end up inside the options['directory']-rooted subtree to be + * must end up inside the options['documentRootPath']-rooted subtree to be * considered manageable files) and the process will continue as if * the $_POST['file_preselect'] entry had not been set. * @@ -1427,14 +993,11 @@ protected function onView() { // try to produce the view; if it b0rks, retry with the parent, until we've arrived at the basedir: // then we fail more severely. - - $emsg = null; - $jserr = array( - 'status' => 1 - ); + $emsg = NULL; + $jserr = array('status' => 1); $mime_filter = $this->getPOSTparam('filter', $this->options['filter']); - $legal_url = null; + $legal_url = NULL; try { @@ -1444,10 +1007,10 @@ protected function onView() $file_preselect_arg = $this->getPOSTparam('file_preselect'); try { - if (!empty($file_preselect_arg)) + if ( ! empty($file_preselect_arg)) { // check if this a path instead of just a basename, then convert to legal_url and split across filename and directory. - if (strpos($file_preselect_arg, '/') !== false) + if (strpos($file_preselect_arg, '/') !== FALSE) { // this will also convert a relative path to an absolute path before transforming it to a LEGAL URI path: $legal_presel = $this->abs2legal_url_path($file_preselect_arg); @@ -1456,7 +1019,7 @@ protected function onView() $file_preselect_arg = $prseli['basename']; // override the directory! $legal_url = $prseli['dirname']; - $legal_url = self::enforceTrailingSlash($legal_url); + $legal_url = self::addTrailingSlash($legal_url); } else { @@ -1467,63 +1030,63 @@ protected function onView() catch(FileManagerException $e) { // discard the preselect input entirely: - $file_preselect_arg = null; + $file_preselect_arg = NULL; } } catch(FileManagerException $e) { $emsg = $e->getMessage(); $legal_url = '/'; - $file_preselect_arg = null; + $file_preselect_arg = NULL; } catch(Exception $e) { // catching other severe failures; since this can be anything it may not be a translation keyword in the message... $emsg = $e->getMessage(); $legal_url = '/'; - $file_preselect_arg = null; + $file_preselect_arg = NULL; } // loop until we drop below the bottomdir; meanwhile getDir() above guarantees that $dir is a subdir of bottomdir, hence dir >= bottomdir. $original_legal_url = $legal_url; + do { try { $rv = $this->_onView($legal_url, $jserr, $mime_filter, $file_preselect_arg); - - $this->sendHttpHeaders('Content-Type: application/json'); - +// $this->sendHttpHeaders('Content-Type: application/json'); echo json_encode($rv); return; } catch(FileManagerException $e) { - if ($emsg === null) + if ($emsg === NULL) $emsg = $e->getMessage(); } catch(Exception $e) { // catching other severe failures; since this can be anything it may not be a translation keyword in the message... - if ($emsg === null) + if ($emsg === NULL) $emsg = $e->getMessage(); } // step down to the parent dir and retry: $legal_url = self::getParentDir($legal_url); - $file_preselect_arg = null; + $file_preselect_arg = NULL; $jserr['status']++; - } while ($legal_url !== false); + } while ($legal_url !== FALSE); $this->modify_json4exception($jserr, $emsg, 'path = ' . $original_legal_url); $this->sendHttpHeaders('Content-Type: application/json'); // when we fail here, it's pretty darn bad and nothing to it. - // just push the error JSON as go. + // just push the error JSON and go. echo json_encode($jserr); + die(); } /** @@ -1534,7 +1097,7 @@ protected function onView() * * Expected parameters: * - * $_POST['directory'] path relative to basedir a.k.a. options['directory'] root + * $_POST['directory'] path relative to basedir a.k.a. options['documentRootPath'] root * * $_POST['file'] filename (including extension, of course) of the file to * be detailed. @@ -1553,6 +1116,16 @@ protected function onView() * will neglect to provide those, expecting the frontend to * delay-load them through another 'event=detail / mode=direct' * request later on. + * 'metaHTML': show the metadata as extra HTML content in + * the preview pane (you can also turn that off using CSS: + * div.filemanager div.filemanager-diag-dump + * { + * display: none; + * } + * 'metaJSON': deliver the extra getID3 metadata in JSON format + * in the json['metadata'] field. + * + * Modes can be mixed by adding a '+' between them. * * Errors will produce a JSON encoded error report, including at least two fields: * @@ -1562,94 +1135,84 @@ protected function onView() */ protected function onDetail() { - $emsg = null; - $legal_url = null; - $file_arg = null; + $emsg = NULL; + $legal_url = NULL; + $file_arg = NULL; $jserr = array( - 'status' => 1 - ); + 'status' => 1 + ); try { $v_ex_code = 'nofile'; $mode = $this->getPOSTparam('mode'); + $mode = explode('+', $mode); + if (empty($mode)) $mode = array(); - $file_arg = $this->getPOSTparam('file'); - - $dir_arg = $this->getPOSTparam('directory'); - $legal_url = $this->rel2abs_legal_url_path($dir_arg . '/'); - - $mime_filter = $this->getPOSTparam('filter', $this->options['filter']); + $file_arg = $this->getPOSTparam('file'); + $mime_filter = $this->getPOSTparam('filter', $this->options['filter']); $mime_filters = $this->getAllowedMimeTypes($mime_filter); - $filename = null; - $file = null; - $mime = null; - $meta = null; - if (!empty($file_arg)) + $filename = NULL; + $file = NULL; + $mime = NULL; + $meta = NULL; + + if ( ! empty($file_arg)) { $filename = basename($file_arg); - // must normalize the combo as the user CAN legitimally request filename == '.' (directory detail view) for this event! - $path = $this->rel2abs_legal_url_path($legal_url . $filename); - //echo " path = $path, ($legal_url . $filename);\n"; - $legal_url = $path; - // must transform here so alias/etc. expansions inside legal_url_path2file_path() get a chance: - $file = $this->legal_url_path2file_path($legal_url); + + // relative to document root + $rel_path = $this->normalize($this->normalize($this->getPOSTparam('directory')) . '/'. $filename); + + // absolute system file path + $file = $this->getAbsolutePath($rel_path); if (is_readable($file)) { if (is_file($file)) { - $meta = $this->getFileInfo($file, $legal_url); + $meta = $this->getFileInfo($file, $rel_path); $mime = $meta->getMimeType(); + if (!$this->IsAllowedMimeType($mime, $mime_filters)) - { $v_ex_code = 'extension'; - } else - { - $v_ex_code = null; - } + $v_ex_code = NULL; } else if (is_dir($file)) { $mime = 'text/directory'; - $v_ex_code = null; + $v_ex_code = NULL; } } } $fileinfo = array( - 'legal_url' => $legal_url, - 'file' => $file, - 'mode' => $mode, - 'meta_data' => $meta, - 'mime' => $mime, - 'mime_filter' => $mime_filter, - 'mime_filters' => $mime_filters, - 'preliminary_json' => $jserr, - 'validation_failure' => $v_ex_code - ); + 'legal_url' => $rel_path, + 'file' => $file, + 'mode' => $mode, + 'meta_data' => $meta, + 'mime' => $mime, + 'mime_filter' => $mime_filter, + 'mime_filters' => $mime_filters, + 'preliminary_json' => $jserr, + 'validation_failure' => $v_ex_code + ); - if (!empty($this->options['DetailIsAuthorized_cb']) && function_exists($this->options['DetailIsAuthorized_cb']) && !$this->options['DetailIsAuthorized_cb']($this, 'detail', $fileinfo)) + if ( ! empty($this->options['DetailIsAuthorized_cb']) && function_exists($this->options['DetailIsAuthorized_cb']) && !$this->options['DetailIsAuthorized_cb']($this, 'detail', $fileinfo)) { + $v_ex_code = $fileinfo['validation_failure']; if (empty($v_ex_code)) $v_ex_code = 'authorized'; } - if (!empty($v_ex_code)) + if ( ! empty($v_ex_code)) + { throw new FileManagerException($v_ex_code); + } - $legal_url = $fileinfo['legal_url']; - //$file = $fileinfo['file']; - $mode = $fileinfo['mode']; - $meta = $fileinfo['meta_data']; - //$mime = $fileinfo['mime']; - $mime_filter = $fileinfo['mime_filter']; - $mime_filters = $fileinfo['mime_filters']; - $jserr = $fileinfo['preliminary_json']; - - $jserr = $this->extractDetailInfo($jserr, $legal_url, $meta, $mime_filter, $mime_filters, $mode); + $jserr = $this->extractDetailInfo($jserr, $rel_path, $meta, $mime_filter, $mime_filters, $mode); $this->sendHttpHeaders('Content-Type: application/json'); @@ -1668,31 +1231,31 @@ protected function onDetail() $this->modify_json4exception($jserr, $emsg, 'file = ' . $file_arg . ', path = ' . $legal_url); - $icon48 = $this->getIconForError($emsg, 'is.default-error', false); + $icon48 = $this->getIconForError($emsg, 'is.default-error', FALSE); $icon48_e = FileManagerUtility::rawurlencode_path($icon48); - $icon = $this->getIconForError($emsg, 'is.default-error', true); + $icon = $this->getIconForError($emsg, 'is.default-error', TRUE); $icon_e = FileManagerUtility::rawurlencode_path($icon); - $jserr['thumb250'] = $icon48_e; - $jserr['thumb48'] = $icon48_e; + $jserr['thumb250'] = NULL; + $jserr['thumb48'] = NULL; $jserr['icon48'] = $icon48_e; $jserr['icon'] = $icon_e; $postdiag_err_HTML = '
' . $emsg . '
'; $preview_HTML = '${nopreview}'; $content = ''; - //$content .= 'Made with ' . (empty($sw_make) ? '???' : $sw_make) . ' @ ' . (empty($time_make) ? '???' : $time_make) . '
'; } @@ -2904,7 +2487,7 @@ public function extractDetailInfo($json_in, $legal_url, &$meta, $mime_filter, $m // are we delaying the thumbnail generation? When yes, then we need to infer the thumbnail dimensions *anyway*! if (empty($thumb48) && $thumbnails_done_or_deferred) { - $dims = $this->predictThumbDimensions($width, $height, 48, 48); + $dims = $this->predictThumbDimensions($width, $height, $this->options['thumbSmallSize'], $this->options['thumbSmallSize']); $json['thumb48_width'] = $dims['width']; $json['thumb48_height'] = $dims['height']; @@ -2916,10 +2499,10 @@ public function extractDetailInfo($json_in, $legal_url, &$meta, $mime_filter, $m // to show the loader.gif in the preview' . $jsa['error'] . '
'; - if (strpos($emsg, 'img_will_not_fit') !== false) + if (strpos($emsg, 'img_will_not_fit') !== FALSE) { $earr = explode(':', $emsg, 2); $postdiag_err_HTML .= "\n" . 'Estimated minimum memory requirements to create thumbnails for this image: ' . $earr[1] . '
'; @@ -2954,13 +2537,15 @@ public function extractDetailInfo($json_in, $legal_url, &$meta, $mime_filter, $m switch ($mime_els[1]) { case 'directory': + $content = '' . $this->mkSafeUTF8(implode(', ', $fi['error'])) . '
'; } - $emsgX = null; + $emsgX = NULL; + if (empty($thumb250)) { if (!$thumbnails_done_or_deferred) { // check if we have stored a thumbnail for this file anyhow: - $thumb250 = $this->getThumb($meta, $file, 250, 250, true); + $thumb250 = $this->getThumb($meta, $file, $this->options['thumbBigSize'], $this->options['thumbBigSize'], TRUE); + if (empty($thumb250)) { - if (!empty($fi) && $check_for_embedded_img) + if ( ! empty($fi) && $check_for_embedded_img) { /* * No thumbnail available yet, so find me one! @@ -3132,7 +2719,7 @@ public function extractDetailInfo($json_in, $legal_url, &$meta, $mime_filter, $m * low cost. */ $embed = $this->extract_ID3info_embedded_image($fi); - //@file_put_contents(dirname(__FILE__) . '/extract_embedded_img.log', print_r(array('html' => $preview_HTML, 'json' => $json, 'thumb250_e' => $thumb250_e, 'thumb250' => $thumb250, 'embed' => $embed, 'fileinfo' => $fi), true)); + //@file_put_contents(dirname(__FILE__) . '/extract_embedded_img.log', print_r(array('html' => $preview_HTML, 'json' => $json, 'thumb250_e' => $thumb250_e, 'thumb250' => $thumb250, 'embed' => $embed, 'fileinfo' => $fi), TRUE)); if (is_object($embed)) { $thumbX = $meta->getThumbURL('embed'); @@ -3144,29 +2731,29 @@ public function extractDetailInfo($json_in, $legal_url, &$meta, $mime_filter, $m // as we've spent some effort to dig out the embedded thumbnail, and 'knowing' (assuming) that generally // embedded thumbnails are not too large, we don't concern ourselves with delaying the thumbnail generation (the // source file mapping is not bidirectional, either!) and go straight ahead and produce the 250px thumbnail at least. - $thumb250 = false; - $thumb250_e = false; - $thumb48 = false; - $thumb48_e = false; + $thumb250 = FALSE; + $thumb250_e = FALSE; + $thumb48 = FALSE; + $thumb48_e = FALSE; $meta->mkCacheDir(); - if (false === file_put_contents($thumbX_f, $embed->imagedata)) + if (FALSE === file_put_contents($thumbX_f, $embed->imagedata)) { @unlink($thumbX_f); $emsgX = 'Cannot save embedded image data to cache.'; - $icon48 = $this->getIcon('is.default-error', false); - $icon = $this->getIcon('is.default-error', true); + $icon48 = $this->getIcon('is.default-error', FALSE); + $icon = $this->getIcon('is.default-error', TRUE); } else { try { - $thumb250 = $this->getThumb($meta, $thumbX_f, 250, 250, false); - if (!empty($thumb250)) + $thumb250 = $this->getThumb($meta, $thumbX_f, $this->options['thumbBigSize'], $this->options['thumbBigSize'], FALSE); + if ( ! empty($thumb250)) { $thumb250_e = FileManagerUtility::rawurlencode_path($thumb250); } - $thumb48 = $this->getThumb($meta, (!empty($thumb250) ? $this->url_path2file_path($thumb250) : $thumbX_f), 48, 48, false); - if (!empty($thumb48)) + $thumb48 = $this->getThumb($meta, ( ! empty($thumb250) ? $this->url_path2file_path($thumb250) : $thumbX_f), $this->options['thumbSmallSize'], $this->options['thumbSmallSize'], FALSE); + if ( ! empty($thumb48)) { $thumb48_e = FileManagerUtility::rawurlencode_path($thumb48); } @@ -3174,35 +2761,36 @@ public function extractDetailInfo($json_in, $legal_url, &$meta, $mime_filter, $m catch (Exception $e) { $emsgX = $e->getMessage(); - $icon48 = $this->getIconForError($emsgX, $legal_url, false); - $icon = $this->getIconForError($emsgX, $legal_url, true); + $icon48 = $this->getIconForError($emsgX, $legal_url, FALSE); + $icon = $this->getIconForError($emsgX, $legal_url, TRUE); } } } } } + // $thumb250 isn't empty else { - // !empty($thumb250) $thumb250_e = FileManagerUtility::rawurlencode_path($thumb250); try { - $thumb48 = $this->getThumb($meta, $this->url_path2file_path($thumb250), 48, 48, false); - assert(!empty($thumb48)); + $thumb48 = $this->getThumb($meta, $this->url_path2file_path($thumb250), $this->options['thumbSmallSize'], $this->options['thumbSmallSize'], FALSE); + assert( ! empty($thumb48)); $thumb48_e = FileManagerUtility::rawurlencode_path($thumb48); } catch (Exception $e) { $emsgX = $e->getMessage(); - $icon48 = $this->getIconForError($emsgX, $legal_url, false); - $icon = $this->getIconForError($emsgX, $legal_url, true); - $thumb48 = false; - $thumb48_e = false; + $icon48 = $this->getIconForError($emsgX, $legal_url, FALSE); + $icon = $this->getIconForError($emsgX, $legal_url, TRUE); + $thumb48 = FALSE; + $thumb48_e = FALSE; } } } } - else // if (!empty($thumb250)) + // if ( ! empty($thumb250)) + else { if (empty($thumb250_e)) { @@ -3212,17 +2800,22 @@ public function extractDetailInfo($json_in, $legal_url, &$meta, $mime_filter, $m { try { - $thumb48 = $this->getThumb($meta, $this->url_path2file_path($thumb250), 48, 48, false); - assert(!empty($thumb48)); + +// $this->log->logInfo('$thumb250 : ' . $this->url_path2file_path($thumb250)); +// $meta->store('mime_type from file extension', $mime2); + + + $thumb48 = $this->getThumb($meta, $this->url_path2file_path($thumb250), $this->options['thumbSmallSize'], $this->options['thumbSmallSize'], FALSE); + assert( ! empty($thumb48)); $thumb48_e = FileManagerUtility::rawurlencode_path($thumb48); } catch (Exception $e) { $emsgX = $e->getMessage(); - $icon48 = $this->getIconForError($emsgX, $legal_url, false); - $icon = $this->getIconForError($emsgX, $legal_url, true); - $thumb48 = false; - $thumb48_e = false; + $icon48 = $this->getIconForError($emsgX, $legal_url, FALSE); + $icon = $this->getIconForError($emsgX, $legal_url, TRUE); + $thumb48 = FALSE; + $thumb48_e = FALSE; } } if (empty($thumb48_e)) @@ -3232,15 +2825,32 @@ public function extractDetailInfo($json_in, $legal_url, &$meta, $mime_filter, $m } // also provide X/Y size info with each direct-access thumbnail file: - if (!empty($thumb250)) + if ( ! empty($thumb250)) { $json['thumb250'] = $thumb250_e; + $meta->store('thumb250_direct', $thumb250); $tnsize = $meta->fetch('thumb250_info'); + if (empty($tnsize)) { - $tnsize = getimagesize($this->url_path2file_path($thumb250)); +// $this->log->logInfo('thumb250 : ' . $this->url_path2file_path($thumb250)); + +// $this->log->logInfo(print_r($meta, true)); + +// $tnsize = getimagesize($this->url_path2file_path($thumb250)); + $thumbPath = $meta->getThumbPath('250x250'); + +// $tnsize = getimagesize($thumb250); + $tnsize = getimagesize($thumbPath); + + $this->log->logInfo(print_r($tnsize, true)); + + +// $this->log->logInfo('$tnsize : ' .$this->url_path2file_path($thumb250), true); + + $meta->store('thumb250_info', $tnsize); } if (is_array($tnsize)) @@ -3251,13 +2861,13 @@ public function extractDetailInfo($json_in, $legal_url, &$meta, $mime_filter, $m if (empty($preview_HTML)) { $preview_HTML = ' -Time elapses since request start: ' . number_format($diff, 3) . ' seconds
' . "\n"; - } - - if (!empty($extra)) - { - $rv .= '"; - $rv .= var_dump_ex($extra, 0, $sorting, $show_WS, 500); - $rv .= ""; - } - - if ($dump_options & DUMP2LOG_ENV_GLOBALS) - { - $rv .= '
"; - $rv .= var_dump_ex($_ENV, 0, $sorting, $show_WS); - $rv .= ""; - } - if ($dump_options & DUMP2LOG_SESSION_GLOBALS) - { - $rv .= '
"; - $rv .= var_dump_ex($_SESSION, 0, $sorting, $show_WS); - $rv .= ""; - } - if ($dump_options & DUMP2LOG_POST_GLOBALS) - { - $rv .= '
"; - $rv .= var_dump_ex($_POST, 0, $sorting, $show_WS); - $rv .= ""; - } - if ($dump_options & DUMP2LOG_GET_GLOBALS) - { - $rv .= '
"; - $rv .= var_dump_ex($_GET, 0, $sorting, $show_WS); - $rv .= ""; - } - if ($dump_options & DUMP2LOG_FILES_GLOBALS) - { - $rv .= '
"; - $rv .= var_dump_ex($_FILES, 0, $sorting, $show_WS); - $rv .= ""; - } - if ($dump_options & DUMP2LOG_COOKIE_GLOBALS) - { - $rv .= '
"; - $rv .= var_dump_ex($_COOKIE, 0, $sorting, $show_WS); - $rv .= ""; - } - if ($dump_options & DUMP2LOG_REQUEST_GLOBALS) - { - $rv .= '
"; - $rv .= var_dump_ex($_REQUEST, 0, $sorting, $show_WS); - $rv .= ""; - } - - if ($dump_options & DUMP2LOG_SERVER_GLOBALS) - { - $rv .= '
"; - $rv .= var_dump_ex($_SERVER, 0, $sorting, $show_WS); - $rv .= ""; - } - - if ($dump_options & DUMP2LOG_STACKTRACE) - { - $st = debug_backtrace(false); - $rv .= '
"; - $rv .= var_dump_ex($st, 0, 0, $show_WS); - $rv .= ""; - } - - $rv .= ''; - - $tstamp = date('Y-m-d.His') . '.' . sprintf('%07d', fmod($now, 1) * 1E6); - - $filename_options = array_merge(array( - 'namebase' => 'LOG-', - 'origin-section' => substr($_SERVER['REQUEST_URI'], 0, -42), - 'extension' => (($dump_options & DUMP2LOG_FORMAT_AS_HTML) ? 'html' : 'log') - ), (is_array($filename_options) ? $filename_options : array())); - - $fname = $filename_options['namebase'] . $tstamp . '.' . sprintf('%03u', $sequence_number) . '-' . $filename_options['origin-section']; - $fname = substr(preg_replace('/[^A-Za-z0-9_.-]+/', '_', $fname), 0, 46) . '.' . substr(preg_replace('/[^A-Za-z0-9_.-]+/', '_', $filename_options['extension']), 0, 9); // make suitable for filesystem - if (isset($_SESSION)) - { - $_SESSION['dbg_last_dump'] = $fname; - } - - if (!($dump_options & DUMP2LOG_FORMAT_AS_HTML)) - { - $rv = preg_replace('/^.*?(.+)<\/body>.*?$/sD', '\\1', $rv); - - $trans['
-= 32 ? htmlentities(chr($c), ENT_NOQUOTES, 'UTF-8') : '' . $c . ';'); - break; - } - $str .= chr($c); - } - - echo "ORIG: [X" . $msg . "X]"; - if ($i < 2) - { - echo " (these characters are 'low ASCII' charactercodes " . ($i * 16) . " ... " . ($i * 16 + 15); - } - echo "\n"; - - $r = FileManagerUtility::pagetitle('X' . $str . 'X', null, $re_extra, $trim_extra); - - echo "FILTERED: [" . htmlentities($r, ENT_NOQUOTES, 'UTF-8') . "]\n\n"; - } - - $trimset = '_.'; - echo "\n\ntrim() with multiple characters in the trim set: [$trimset]\n"; - - $test = array( - '.ignore', - '___ignore', - '_._.ignore', - '._._ignore', - 'X.ignore', - 'X___ignore', - 'X_._.ignore', - 'X._._ignore', - '__X_ignore', - '_._X.ignore', - '._.X_ignore' - ); - foreach ($test as $t) - { - $r = trim($t, $trimset); - - echo "\nORIG: [" . htmlentities($t, ENT_NOQUOTES, 'UTF-8') . "]\nRES: [" . htmlentities($r, ENT_NOQUOTES, 'UTF-8') . "]\n"; - } -} - - -$browser = new FileManagerWithAliasSupport(array( - 'directory' => 'Files/', // relative paths: are relative to the URI request script path, i.e. dirname(__FILE__) - //'thumbnailPath' => 'Files/Thumbnails/', - 'assetBasePath' => '../Assets', - 'chmod' => 0777, - //'maxUploadSize' => 1024 * 1024 * 5, - //'upload' => false, - //'destroy' => false, - //'create' => false, - //'move' => false, - //'download' => false, - //'filter' => 'image/', - 'allowExtChange' => true, // allow file name extensions to be changed; the default however is: NO (FALSE) - 'UploadIsAuthorized_cb' => 'FM_IsAuthorized', - 'DownloadIsAuthorized_cb' => 'FM_IsAuthorized', - 'CreateIsAuthorized_cb' => 'FM_IsAuthorized', - 'DestroyIsAuthorized_cb' => 'FM_IsAuthorized', - 'MoveIsAuthorized_cb' => 'FM_IsAuthorized' - - // http://httpd.apache.org/docs/2.2/mod/mod_alias.html -- we only emulate the Alias statement. (Also useful for VhostAlias, BTW!) - // Implementing other path translation features is left as an exercise to the reader: - , 'Aliases' => array( - // '/c/lib/includes/js/mootools-filemanager/Demos/Files/alias' => "D:/xxx", - // '/c/lib/includes/js/mootools-filemanager/Demos/Files/d' => "D:/xxx.tobesorted", - // '/c/lib/includes/js/mootools-filemanager/Demos/Files/u' => "D:/websites-uploadarea", - - // '/c/lib/includes/js/mootools-filemanager/Demos/Files' => "D:/experiment" - ) -)); - -echo "\n\n"; -$settings = $browser->getSettings(); -var_dump($settings); - -?> --
$_SERVER['DOCUMENT_ROOT'] = ''
-$_SERVER['SCRIPT_NAME'] = ''
- -ORIG: [" . htmlentities($t, ENT_NOQUOTES, 'UTF-8') . "]\nRES: [" . htmlentities($r, ENT_NOQUOTES, 'UTF-8') . "]\n"; - - if (strcmp($e, $r) != 0) - { - echo "
FAILED!
\n"; - } - echo "\n$_SERVER['DOCUMENT_ROOT'] = ''
- -realpath('/') = ''
- -getRequestPath() => 'getRequestPath(); ?>'
- - -ORIG: [" . htmlentities($t, ENT_NOQUOTES, 'UTF-8') . "]\nURI.ABS: [" . htmlentities($r1, ENT_NOQUOTES, 'UTF-8') . "]\nDIR.ABS: [" . htmlentities($r2, ENT_NOQUOTES, 'UTF-8') . "]\n"; - - if ($emsg !== null) - { - echo "
FileManagerException('$emsg')!
\n"; - } - echo "\nORIG: [" . htmlentities($t, ENT_NOQUOTES, 'UTF-8') . "]\nURI.ABS: [" . htmlentities($r1, ENT_NOQUOTES, 'UTF-8') . "]\nDIR.ABS: [" . htmlentities($r2, ENT_NOQUOTES, 'UTF-8') . "]\nRAW.URI: [" . htmlentities($r3, ENT_NOQUOTES, 'UTF-8') . "]\nNORMLZD: [" . htmlentities($r5, ENT_NOQUOTES, 'UTF-8') . "]\nDIR.ABS: [" . htmlentities($r4, ENT_NOQUOTES, 'UTF-8') . "]\n"; - - if ($emsg !== null) - { - echo "
FileManagerException('$emsg')!
\n"; - } - echo "\ndir = '$r2'\n"; - - echo "\n
"; - var_dump($c1); - echo "\n"; - - if ($emsg !== null) - { - echo "
FileManagerException('$emsg')!
\n"; - } - echo "\n- 'Files/', // relative paths: are relative to the URI request script path, i.e. dirname(__FILE__) - 'thumbnailPath' => 'Files/Thumbnails/', - //'assetBasePath' => '../Assets', - 'chmod' => 0777, - //'maxUploadSize' => 1024 * 1024 * 5, - //'upload' => false, - //'destroy' => false, - //'create' => false, - //'move' => false, - //'download' => false, - //'filter' => 'image/', - 'allowExtChange' => true, // allow file name extensions to be changed; the default however is: NO (FALSE) - 'UploadIsAuthorized_cb' => 'FM_IsAuthorized', - 'DownloadIsAuthorized_cb' => 'FM_IsAuthorized', - 'CreateIsAuthorized_cb' => 'FM_IsAuthorized', - 'DestroyIsAuthorized_cb' => 'FM_IsAuthorized', - 'MoveIsAuthorized_cb' => 'FM_IsAuthorized' - - // http://httpd.apache.org/docs/2.2/mod/mod_alias.html -- we only emulate the Alias statement. (Also useful for VhostAlias, BTW!) - // Implementing other path translation features is left as an exercise to the reader: - , 'Aliases' => array( - // '/c/lib/includes/js/mootools-filemanager/Demos/Files/alias' => "D:/xxx", - // '/c/lib/includes/js/mootools-filemanager/Demos/Files/d' => "D:/xxx.tobesorted", - // '/c/lib/includes/js/mootools-filemanager/Demos/Files/u' => "D:/websites-uploadarea", - - // '/c/lib/includes/js/mootools-filemanager/Demos/Files' => "D:/experiment" - ) -)); - -echo "\n\n"; -$settings = $browser->getSettings(); -var_dump($settings); - -?> --
$_SERVER['DOCUMENT_ROOT'] = ''
-$_SERVER['SCRIPT_NAME'] = ''
- - - --fireEvent('detail'); -$dump = ob_get_clean(); - -echo "input:\n"; -var_dump($_POST); -echo "\n\noutput for event 'detail':\n\n"; - -$json = json_decode($dump); -var_dump($json); - -?> -
- - --fireEvent('detail'); -$dump = ob_get_clean(); - -echo "input:\n"; -var_dump($_POST); -echo "\n\noutput for event 'detail':\n\n"; - -//echo "" . htmlentities($dump, ENT_NOQUOTES, 'UTF-8') . "\n"; -//echo "\n\n"; - -$json = json_decode($dump); -var_dump($json); - -?> -
- -
- 'Files/', // relative paths: are relative to the URI request script path, i.e. dirname(__FILE__) - //'thumbnailPath' => 'Files/Thumbnails/', - 'assetBasePath' => '../Assets', - 'chmod' => 0777, - //'maxUploadSize' => 1024 * 1024 * 5, - //'upload' => false, - //'destroy' => false, - //'create' => false, - //'move' => false, - //'download' => false, - //'filter' => 'image/', - 'allowExtChange' => true, // allow file name extensions to be changed; the default however is: NO (FALSE) - 'UploadIsAuthorized_cb' => 'FM_IsAuthorized', - 'DownloadIsAuthorized_cb' => 'FM_IsAuthorized', - 'CreateIsAuthorized_cb' => 'FM_IsAuthorized', - 'DestroyIsAuthorized_cb' => 'FM_IsAuthorized', - 'MoveIsAuthorized_cb' => 'FM_IsAuthorized' - - // http://httpd.apache.org/docs/2.2/mod/mod_alias.html -- we only emulate the Alias statement. (Also useful for VhostAlias, BTW!) - // Implementing other path translation features is left as an exercise to the reader: - , 'Aliases' => array( - // '/c/lib/includes/js/mootools-filemanager/Demos/Files/alias' => "D:/xxx", - // '/c/lib/includes/js/mootools-filemanager/Demos/Files/d' => "D:/xxx.tobesorted", - // '/c/lib/includes/js/mootools-filemanager/Demos/Files/u' => "D:/websites-uploadarea", - - // '/c/lib/includes/js/mootools-filemanager/Demos/Files' => "D:/experiment" - ) -)); - -echo "\n\n"; -$settings = $browser->getSettings(); -var_dump($settings); - -?> --
$_SERVER['DOCUMENT_ROOT'] = ''
-$_SERVER['SCRIPT_NAME'] = ''
- - - -$_SERVER['DOCUMENT_ROOT'] = ''
- -realpath('/') = ''
- -getRequestPath() => 'getRequestPath(); ?>'
- - -dir = '$r2'\n"; - - echo "\n
"; - var_dump($c1); - echo "\n"; - - if ($emsg !== null) - { - echo "
FileManagerException('$emsg')!
\n"; - } - echo "\n- 'Files/', // relative paths: are relative to the URI request script path, i.e. dirname(__FILE__) - //'thumbnailPath' => 'Files/Thumbnails/', - 'assetBasePath' => '../Assets', - 'chmod' => 0777, - //'maxUploadSize' => 1024 * 1024 * 5, - //'upload' => false, - //'destroy' => false, - //'create' => false, - //'move' => false, - //'download' => false, - //'filter' => 'image/', - 'allowExtChange' => true, // allow file name extensions to be changed; the default however is: NO (FALSE) - 'UploadIsAuthorized_cb' => 'FM_IsAuthorized', - 'DownloadIsAuthorized_cb' => 'FM_IsAuthorized', - 'CreateIsAuthorized_cb' => 'FM_IsAuthorized', - 'DestroyIsAuthorized_cb' => 'FM_IsAuthorized', - 'MoveIsAuthorized_cb' => 'FM_IsAuthorized' - - // http://httpd.apache.org/docs/2.2/mod/mod_alias.html -- we only emulate the Alias statement. (Also useful for VhostAlias, BTW!) - // Implementing other path translation features is left as an exercise to the reader: - , 'Aliases' => array( - // '/c/lib/includes/js/mootools-filemanager/Demos/Files/alias' => "D:/xxx", - // '/c/lib/includes/js/mootools-filemanager/Demos/Files/d' => "D:/xxx.tobesorted", - // '/c/lib/includes/js/mootools-filemanager/Demos/Files/u' => "D:/websites-uploadarea", - - // '/c/lib/includes/js/mootools-filemanager/Demos/Files' => "D:/experiment" - ) -)); - -echo "\n\n"; -$settings = $browser->getSettings(); -var_dump($settings); - -?> --
$_SERVER['DOCUMENT_ROOT'] = ''
-$_SERVER['SCRIPT_NAME'] = ''
- - - --fireEvent('view'); -$dump = ob_get_clean(); - -echo "input:\n"; -var_dump($_POST); -echo "\n\noutput for event 'view':\n\n"; - -$json = json_decode($dump); -var_dump($json); - -?> --