diff --git a/lib/api/common.php b/lib/api/common.php index f09eb35..aaa0125 100644 --- a/lib/api/common.php +++ b/lib/api/common.php @@ -1,190 +1,200 @@ | +--------------------------------------------------------------------------+ | Author: Aleksander Machniak | +--------------------------------------------------------------------------+ */ class file_api_common { protected $api; protected $rc; protected $args = array(); - public function __construct($api) + public function __construct($api, $args = array()) { - $this->rc = rcube::get_instance(); - $this->api = $api; + $this->rc = rcube::get_instance(); + $this->api = $api; + $this->args = (array) $args; } /** * Request handler */ public function handle() { // GET arguments - $this->args = &$_GET; + if (!empty($_GET)) { + foreach (array_keys($_GET) as $key) { + $this->args[$key] = &$_GET[$key]; + } + } // POST arguments (JSON) if ($_SERVER['REQUEST_METHOD'] == 'POST') { $post = file_get_contents('php://input'); $this->args += (array) json_decode($post, true); unset($post); } // disable script execution time limit, so we can handle big files @set_time_limit(360); } /** * File uploads handler */ protected function upload() { $files = array(); if (is_array($_FILES['file']['tmp_name'])) { foreach ($_FILES['file']['tmp_name'] as $i => $filepath) { if ($err = $_FILES['file']['error'][$i]) { if ($err == UPLOAD_ERR_INI_SIZE || $err == UPLOAD_ERR_FORM_SIZE) { $maxsize = ini_get('upload_max_filesize'); $maxsize = $this->show_bytes(parse_bytes($maxsize)); throw new Exception("Maximum file size ($maxsize) exceeded", file_api_core::ERROR_CODE); } throw new Exception("File upload failed", file_api_core::ERROR_CODE); } $files[] = array( 'path' => $filepath, 'name' => $_FILES['file']['name'][$i], 'size' => filesize($filepath), 'type' => rcube_mime::file_content_type($filepath, $_FILES['file']['name'][$i], $_FILES['file']['type']), ); } } else if ($_SERVER['REQUEST_METHOD'] == 'POST') { // if filesize exceeds post_max_size then $_FILES array is empty, if ($maxsize = ini_get('post_max_size')) { $maxsize = $this->show_bytes(parse_bytes($maxsize)); throw new Exception("Maximum file size ($maxsize) exceeded", file_api_core::ERROR_CODE); } throw new Exception("File upload failed", file_api_core::ERROR_CODE); } return $files; } /** * Return built-in viewer opbject for specified mimetype * * @return object Viewer object */ protected function find_viewer($mimetype) { $dir = RCUBE_INSTALL_PATH . 'lib/viewers'; $files = array(); // First get viewers and sort by name to get priority if ($handle = opendir($dir)) { while (false !== ($file = readdir($handle))) { if (preg_match('/^([a-z0-9_]+)\.php$/i', $file, $matches)) { $files[$matches[1]] = $dir . '/' . $file; } } closedir($handle); } ksort($files); foreach ($files as $name => $file) { include_once $file; $class = 'file_viewer_' . $name; $viewer = new $class($this->api); if ($viewer->supports($mimetype)) { return $viewer; } } } /** * Parse driver metadata information */ protected function parse_metadata($metadata, $default = false) { if ($default) { unset($metadata['form']); $metadata['name'] .= ' (' . $this->api->translate('localstorage') . ')'; } // localize form labels foreach ($metadata['form'] as $key => $val) { $label = $this->api->translate('form.' . $val); if (strpos($label, 'form.') !== 0) { $metadata['form'][$key] = $label; } } return $metadata; } /** * Get folder rights */ protected function folder_rights($folder) { list($driver, $path) = $this->api->get_driver($folder); $rights = $driver->folder_rights($path); $result = array(); $map = array( file_storage::ACL_READ => 'read', file_storage::ACL_WRITE => 'write', ); foreach ($map as $key => $value) { if ($rights & $key) { $result[] = $value; } } return $result; } /** - * Update manticore session on file/folder move + * Update document session on file/folder move */ protected function session_uri_update($from, $to, $is_folder = false) { - // check Manticore support. Note: we don't use config->get('fileapi_manticore') + // check Manticore/WOPI support. Note: we don't use config->get('fileapi_manticore') // here as it may be not properly set if backend driver wasn't initialized yet $capabilities = $this->api->capabilities(false); - if (empty($capabilities['MANTICORE'])) { - return; + + if (!empty($capabilities['WOPI'])) { + $document = new file_wopi($this->api); + } + else if (!empty($capabilities['MANTICORE'])) { + $document = new file_manticore($this->api); } - $manticore = new file_manticore($this->api); - $manticore->session_uri_update($from, $to, $is_folder); + if (!empty($document)) { + $document->session_uri_update($from, $to, $is_folder); + } } } diff --git a/lib/api/file_create.php b/lib/api/file_create.php index 6323037..e4450de 100644 --- a/lib/api/file_create.php +++ b/lib/api/file_create.php @@ -1,109 +1,109 @@ | +--------------------------------------------------------------------------+ | Author: Aleksander Machniak | +--------------------------------------------------------------------------+ */ class file_api_file_create extends file_api_common { /** * Request handler */ public function handle() { parent::handle(); if (!isset($this->args['file']) || $this->args['file'] === '') { throw new Exception("Missing file name", file_api_core::ERROR_CODE); } if (!isset($this->args['content'])) { if (!($this->api instanceof file_api_lib) || empty($this->args['path'])) { throw new Exception("Missing file content", file_api_core::ERROR_CODE); } } if (is_resource($this->args['content'])) { $chunk = stream_get_contents($this->args['content'], 1024000, 0); } else if ($this->args['path']) { $chunk = $this->args['path']; $is_file = true; } else { $chunk = $this->args['content']; } $ctype = $this->args['content-type']; if ($ctype && !preg_match('/^[a-z_-]+\/[a-z._-]+$/', $ctype)) { $ctype = ''; } $request = $this instanceof file_api_file_update ? 'file_update' : 'file_create'; $file = array( 'content' => $this->args['content'], 'path' => $this->args['path'], 'type' => rcube_mime::file_content_type($chunk, $this->args['file'], $ctype, !$is_file), ); if (strpos($file['type'], 'empty') !== false && $ctype) { $file['type'] = $ctype; } else if (empty($file['type'])) { $file['type'] = 'application/octet-stream'; } // Get file content from a template - if ($request == 'file_create' && empty($file['path']) && !strlen($file['content'])) { + if ($request == 'file_create' && empty($file['path']) && empty($file['content'])) { $this->use_file_template($file); } list($driver, $path) = $this->api->get_driver($this->args['file']); $driver->$request($path, $file); if (rcube_utils::get_boolean((string) $this->args['info'])) { return $driver->file_info($path); } } /** * Use templates when creating empty files */ protected function use_file_template(&$file) { if ($ext = array_search($file['type'], file_utils::$ext_map)) { // find the template $ext = ".$ext"; if ($handle = opendir(__DIR__ . '/../templates')) { while (false !== ($entry = readdir($handle))) { if (substr($entry, -strlen($ext)) == $ext) { // set path to the template file $file['path'] = __DIR__ . '/../templates/' . $entry; break; } } closedir($handle); } } } } diff --git a/lib/file_api_lib.php b/lib/file_api_lib.php index 3747141..35fff5d 100644 --- a/lib/file_api_lib.php +++ b/lib/file_api_lib.php @@ -1,195 +1,147 @@ | +--------------------------------------------------------------------------+ | Author: Aleksander Machniak | +--------------------------------------------------------------------------+ */ /** * This class gives access to Chwala API as a library */ class file_api_lib extends file_api_core { /** * API methods handler */ public function __call($name, $arguments) { $this->init(); switch ($name) { case 'configure': foreach (array_keys($this->env) as $name) { if (isset($arguments[0][$name])) { $this->env[$name] = $arguments[0][$name]; } } return $this->env; case 'mimetypes': return $this->supported_mimetypes(); case 'file_list': $args = array( 'folder' => $arguments[0], ); break; case 'file_create': case 'file_update': $args = array( 'file' => $arguments[0], 'path' => $arguments[1]['path'], 'content' => $arguments[1]['content'], 'content-type' => $arguments[1]['type'], ); break; case 'file_delete': case 'file_info': $args = array( 'file' => $arguments[0], ); break; case 'file_copy': case 'file_move': $args = array( 'file' => array($arguments[0] => $arguments[1]), ); break; case 'file_get': // override default action, we need only to support // writes to file handle list($driver, $path) = $this->get_driver($arguments[0]); $driver->file_get($path, $arguments[1], $arguments[2]); return; case 'folder_list': // no arguments $args = array(); break; case 'folder_create': case 'folder_subscribe': case 'folder_unsubscribe': case 'folder_delete': $args = array( 'folder' => $arguments[0], ); break; case 'folder_info': $args = array( 'folder' => $arguments[0], 'rights' => 1, 'sessions' => 1, ); break; case 'folder_move': $args = array( 'folder' => $arguments[0], 'new' => $arguments[1], ); break; case 'lock_create': case 'lock_delete': $args = $arguments[1]; $args['uri'] = $arguments[0]; break; case 'lock_list': $args = array( 'uri' => $arguments[0], 'child_locks' => $arguments[1], ); break; default: throw new Exception("Invalid method name", \file_storage::ERROR_UNSUPPORTED); } + require_once __DIR__ . "/api/common.php"; require_once __DIR__ . "/api/$name.php"; $class = "file_api_$name"; $handler = new $class($this, $args); return $handler->handle(); } /** * Configure environment (this is to be overriden by implementation class) */ protected function init() { } } - - -/** - * Common handler class, from which action handler classes inherit - */ -class file_api_common -{ - protected $api; - protected $rc; - protected $args; - - - public function __construct($api, $args) - { - $this->rc = rcube::get_instance(); - $this->api = $api; - $this->args = $args; - } - - /** - * Request handler - */ - public function handle() - { - // disable script execution time limit, so we can handle big files - @set_time_limit(0); - } - - /** - * Parse driver metadata information - */ - protected function parse_metadata($metadata, $default = false) - { - if ($default) { - unset($metadata['form']); - $metadata['name'] .= ' (' . $this->api->translate('localstorage') . ')'; - } - - // localize form labels - foreach ($metadata['form'] as $key => $val) { - $label = $this->api->translate('form.' . $val); - if (strpos($label, 'form.') !== 0) { - $metadata['form'][$key] = $label; - } - } - - return $metadata; - } -}