diff --git a/lib/api/file_info.php b/lib/api/file_info.php index 8c04783..8ae55e7 100644 --- a/lib/api/file_info.php +++ b/lib/api/file_info.php @@ -1,91 +1,92 @@ | +--------------------------------------------------------------------------+ | Author: Aleksander Machniak | +--------------------------------------------------------------------------+ */ class file_api_file_info 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); } list($driver, $path) = $this->api->get_driver($this->args['file']); $info = $driver->file_info($path); // Possible 'viewer' types are defined in files_api.js:file_type_supported() // 1 - Native browser support // 2 - Chwala viewer exists // 4 - Manticore (WebODF collaborative editor) if (rcube_utils::get_boolean((string) $this->args['viewer'])) { $this->file_viewer_info($this->args['file'], $info); - if ((intval($this->args['viewer']) & 4) && $this->rc->config->get('fileapi_manticore')) { + // check if file type is supported by webodf editor? + if ($this->rc->config->get('fileapi_manticore')) { + if (strtolower($info['type']) == 'application/vnd.oasis.opendocument.text') { + $info['viewer']['manticore'] = true; + } + } + + if ((intval($this->args['viewer']) & 4) && $info['viewer']['manticore']) { $this->file_manticore_handler($this->args['file'], $info); } } return $info; } /** * Merge file viewer data into file info */ protected function file_viewer_info($file, &$info) { if ($viewer = $this->find_viewer($info['type'])) { $info['viewer'] = array(); if ($frame = $viewer->frame($file, $info['type'])) { $info['viewer']['frame'] = $frame; } else if ($href = $viewer->href($file, $info['type'])) { $info['viewer']['href'] = $href; } } } /** * Merge manticore session data into file info */ protected function file_manticore_handler($file, &$info) { - // check if file type is supported by webodf editor? - if (strtolower($info['type']) != 'application/vnd.oasis.opendocument.text') { - return; - } - $manticore = new file_manticore($this->api); if ($uri = $manticore->viewer_uri($file)) { - $info['viewer']['href'] = $uri; - $info['viewer']['manticore'] = true; + $info['viewer']['href'] = $uri; } } } diff --git a/lib/file_manticore.php b/lib/file_manticore.php index 85a4110..47e1767 100644 --- a/lib/file_manticore.php +++ b/lib/file_manticore.php @@ -1,288 +1,288 @@ | +--------------------------------------------------------------------------+ | Author: Aleksander Machniak | +--------------------------------------------------------------------------+ */ /** * Document editing sessions handling */ class file_manticore { protected $api; protected $rc; protected $request; protected $table = 'chwala_sessions'; /** * Class constructor * * @param file_api Chwala API app instance */ public function __construct($api) { $this->rc = rcube::get_instance(); $this->api = $api; } /** * Return viewer URI for specified file. This creates * a new collaborative editing session when needed * * @param string $file File path * * @return string Manticore URI * @throws Exception */ public function viewer_uri($file) { list($driver, $path) = $this->api->get_driver($file); $backend = $this->api->get_backend(); $uri = $driver->path2uri($path); $id = rcube_utils::bin2ascii(md5(time() . $uri, true)); $data = array( 'user' => $_SESSION['user'], ); // @TODO: check if session exists and is valid (?) // we'll store user credentials if the file comes from // an external source that requires authentication if ($backend != $driver) { $auth = $driver->auth_info(); $auth['password'] = $this->rc->encrypt($auth['password']); $data['auth_info'] = $auth; } // Do this before starting the session in Manticore, // it will immediately call api/document to get the file body $res = $this->session_create($id, $uri, $data); if (!$res) { throw new Exception("Failed creating document editing session", file_api_core::ERROR_CODE); } // get filename $path = explode(file_storage::SEPARATOR, $path); $filename = $path[count($path)-1]; // create the session in Manticore $req = $this->get_request(); $res = $req->session_create(array( 'id' => $id, - 'title' => $filename, + 'title' => '', // @TODO: maybe set to a file path without extension? 'access' => array( array( 'identity' => $data['user'], 'permission' => 'write', ), ), )); if (!$res) { $this->session_delete($id); throw new Exception("Failed creating document editing session", file_api_core::ERROR_CODE); } return $this->frame_uri($id); } /** * Get file path (not URI) from session. * * @param string $id Session ID * * @return string File path * @throws Exception */ public function session_file($id) { $session = $this->session_info($id); if (empty($session)) { throw new Exception("Document session ID not found.", file_api_core::ERROR_CODE); } $path = $this->uri2path($session['uri']); if (empty($path)) { throw new Exception("Document session ID not found.", file_api_core::ERROR_CODE); } return $path; } /** * Get editing session info */ public function session_info($id) { $db = $this->rc->get_dbh(); $result = $db->query("SELECT * FROM `{$this->table}`" . " WHERE `id` = ?", $id); if ($row = $db->fetch_assoc($result)) { $row['data'] = json_decode($row['data'], true); return $row; } } /** * Find editing sessions for specified path */ public function session_find($path) { // create an URI for specified path list($driver, $path) = $this->api->get_driver($path); $uri = trim($driver->path2uri($path), '/') . '/'; // get existing sessions $db = $this->rc->get_dbh(); $sessions = array(); $result = $db->query("SELECT * FROM `{$this->table}`" . " WHERE `uri` LIKE '" . $db->escape($uri) . "%'"); if ($row = $db->fetch_assoc($result)) { if ($path = $this->uri2path($row['uri'])) { $data = json_decode($row['data'], true); $sessions[$row['id']] = array( 'file' => $path, 'owner' => $data['user'], // @TODO: invitated?, last_modified? ); } } return $sessions; } /** * Create editing session */ protected function session_create($id, $uri, $data) { $db = $this->rc->get_dbh(); $result = $db->query("INSERT INTO `{$this->table}`" . " (`id`, `uri`, `data`) VALUES (?, ?, ?)", $id, $uri, json_encode($data)); return $db->affected_rows($result) > 0; } /** * Delete editing session */ protected function session_delete($id) { $db = $this->rc->get_dbh(); $result = $db->query("DELETE FROM `{$this->table}`" . " WHERE `id` = ?", $id); return $db->affected_rows($result) > 0; } /** * Generate URI of Manticore editing session */ protected function frame_uri($id) { $base_url = rtrim($this->rc->config->get('fileapi_manticore'), ' /'); return $base_url . '/document/' . $id . '/' . $_SESSION['manticore_token']; } /** * Get file path from the URI */ protected function uri2path($uri) { $backend = $this->api->get_backend(); try { return $backend->uri2path($uri); } catch (Exception $e) { // do nothing } foreach ($this->api->get_drivers(true) as $driver) { try { $path = $driver->uri2path($uri); $title = $driver->title(); if ($title) { $path = $title . file_storage::SEPARATOR . $path; } return $path; } catch (Exception $e) { // do nothing } } } /** * Return Manticore user/session info */ public function user_info() { $req = $this->get_request(); $res = $req->get('api/users/me'); return $res->get(); } /** * Initialize Manticore API request handler */ protected function get_request() { if (!$this->request) { $uri = rcube_utils::resolve_url($this->rc->config->get('fileapi_manticore')); $this->request = new file_manticore_api($uri); // Use stored session token, check if it's still valid if ($_SESSION['manticore_token']) { $is_valid = $this->request->set_session_token($_SESSION['manticore_token'], true); if ($is_valid) { return $this->request; } } $backend = $this->api->get_backend(); $auth = $backend->auth_info(); $_SESSION['manticore_token'] = $this->request->login($auth['username'], $auth['password']); if (empty($_SESSION['manticore_token'])) { throw new Exception("Unable to login to Manticore server.", file_api_core::ERROR_CODE); } } return $this->request; } }