diff options
32 files changed, 821 insertions, 197 deletions
diff --git a/apps/files/appinfo/app.php b/apps/files/appinfo/app.php index 43e6cffa335..9af36c682fd 100644 --- a/apps/files/appinfo/app.php +++ b/apps/files/appinfo/app.php @@ -10,7 +10,7 @@ OCP\App::addNavigationEntry(array("id" => "files_index", "icon" => OCP\Util::imagePath("core", "places/files.svg"), "name" => $l->t("Files"))); -OC_Search::registerProvider('OC_Search_Provider_File'); +\OC::$server->getSearch()->registerProvider('OC\Search\Provider\File'); $templateManager = OC_Helper::getFileTemplateManager(); $templateManager->registerTemplate('text/html', 'core/templates/filetemplates/template.html'); diff --git a/apps/files/appinfo/update.php b/apps/files/appinfo/update.php index de635e5ce6b..a9b8ccbf824 100644 --- a/apps/files/appinfo/update.php +++ b/apps/files/appinfo/update.php @@ -6,3 +6,60 @@ if (version_compare(\OCP\Config::getSystemValue('version', '0.0.0'), '7.0.0', '< \OCP\Config::deleteSystemValue('allowZipDownload'); \OCP\Config::deleteSystemValue('maxZipInputSize'); } + +if (version_compare(\OCP\Config::getAppValue('files', 'installed_version'), '1.1.9', '<')) { + + // update wrong mimetypes + $wrongMimetypes = array( + 'application/mspowerpoint' => 'application/vnd.ms-powerpoint', + 'application/msexcel' => 'application/vnd.ms-excel', + ); + + $stmt = OC_DB::prepare(' + UPDATE `*PREFIX*mimetypes` + SET `mimetype` = ? + WHERE `mimetype` = ? + '); + + foreach ($wrongMimetypes as $wrong => $correct) { + OC_DB::executeAudited($stmt, array($wrong, $correct)); + } + + $updatedMimetypes = array( + 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'xlsx' => 'application/vnd.ms-excel', + 'pptx' => 'application/vnd.ms-powerpoint', + ); + + // separate doc from docx etc + foreach ($updatedMimetypes as $extension => $mimetype ) { + $result = OC_DB::executeAudited(' + SELECT count(`mimetype`) + FROM `*PREFIX*mimetypes` + WHERE `mimetype` = ? + ', array($mimetype) + ); + + $exists = $result->fetchOne(); + + if ( ! $exists ) { + // insert mimetype + OC_DB::executeAudited(' + INSERT INTO `*PREFIX*mimetypes` ( `mimetype` ) + VALUES ( ? ) + ', array($mimetype) + ); + } + + // change mimetype for files with x extension + OC_DB::executeAudited(' + UPDATE `*PREFIX*filecache` + SET `mimetype` = ( + SELECT `id` + FROM `*PREFIX*mimetypes` + WHERE `mimetype` = ? + ) WHERE `name` LIKE ? + ', array($mimetype, '%.'.$extension) + ); + } +}
\ No newline at end of file diff --git a/apps/files/appinfo/version b/apps/files/appinfo/version index 18efdb9ae67..512a1faa680 100644 --- a/apps/files/appinfo/version +++ b/apps/files/appinfo/version @@ -1 +1 @@ -1.1.8 +1.1.9 diff --git a/apps/files/css/files.css b/apps/files/css/files.css index 0392733f4ca..55f3d17ac2b 100644 --- a/apps/files/css/files.css +++ b/apps/files/css/files.css @@ -92,31 +92,12 @@ height: 100%; } -/** - * Override global #controls styles - * to be more flexible / relative - */ -#body-user .app-files #controls { - left: 250px; /* sidebar width */ - position: fixed; - padding-left: 0px; -} - -/* this is mostly for file viewer apps, text editor, etc */ -#body-user .app-files.no-sidebar #controls { - left: 0px; -} - /* move Deleted Files to bottom of sidebar */ .nav-trashbin { position: absolute !important; bottom: 0; } -.app-files #app-settings input { - width: 90%; -} - #filestable tbody tr { background-color:#fff; height:40px; } #filestable tbody tr:hover, tbody tr:active { background-color: rgb(240,240,240); @@ -224,7 +205,7 @@ table.multiselect thead { z-index: 10; -moz-box-sizing: border-box; box-sizing: border-box; - left: 230px; /* sidebar */ + left: 250px; /* sidebar */ } table.multiselect thead th { diff --git a/apps/files/js/files.js b/apps/files/js/files.js index 8d871d6dac6..df0c40a4405 100644 --- a/apps/files/js/files.js +++ b/apps/files/js/files.js @@ -284,7 +284,7 @@ $('#webdavurl').select(); }); - //scroll to and highlight preselected file + //FIXME scroll to and highlight preselected file /* if (getURLParameter('scrollto')) { FileList.scrollTo(getURLParameter('scrollto')); diff --git a/core/css/apps.css b/core/css/apps.css index ebb0c269000..f919bf09fb9 100644 --- a/core/css/apps.css +++ b/core/css/apps.css @@ -190,6 +190,10 @@ overflow-y: auto; } + + +/* APP-SETTINGS ---------------------------------------------------------------*/ + /* settings area */ #app-settings { position: fixed; @@ -215,6 +219,11 @@ overflow-y: auto; } +/* display input fields at full width */ +#app-settings-content input { + width: 93%; +} + .settings-button { display: block; height: 44px; diff --git a/core/css/mobile.css b/core/css/mobile.css index 98033528210..2e515957c80 100644 --- a/core/css/mobile.css +++ b/core/css/mobile.css @@ -40,11 +40,6 @@ display: none; } -/* don’t require a minimum width for controls bar */ -#controls { - min-width: initial !important; -} - /* position share dropdown */ #dropdown { margin-right: 10% !important; @@ -109,12 +104,19 @@ opacity: 1; } -/* fix controls bar for apps which don't use the standard */ -#body-user .app-files #controls, -#user-controls { + +/* controls bar for mobile */ +#controls { + min-width: initial !important; left: 0 !important; - padding-left: 44px !important; + padding-left: 0; + padding-right: 0 !important; +} +/* position controls for apps with app-navigation */ +#app-navigation+#app-content #controls { + padding-left: 44px; } + /* .viewer-mode is when text editor, PDF viewer, etc is open */ #body-user .app-files.viewer-mode #controls { padding-left: 0 !important; @@ -134,11 +136,8 @@ table.multiselect thead { /* fix controls bar jumping when navigation is slid out */ -.snapjs-left #app-navigation-toggle { - top: 0; -} -.snapjs-left .app-files #controls, -.snapjs-left #user-controls { +.snapjs-left #app-navigation-toggle, +.snapjs-left #controls { top: 0; } .snapjs-left table.multiselect thead { diff --git a/core/css/styles.css b/core/css/styles.css index 5ad9796137d..6e8f6868b1d 100644 --- a/core/css/styles.css +++ b/core/css/styles.css @@ -243,14 +243,14 @@ input[type="submit"].enabled { -webkit-box-sizing: border-box; box-sizing: border-box; position: fixed; - top:45px; + top: 45px; right: 0; - left:0; + left: 0; height: 44px; width: 100%; padding: 0; margin: 0; - background: #eee; + background-color: rgba(235, 235, 235, .85); border-bottom: 1px solid #e7e7e7; z-index: 50; -webkit-user-select: none; @@ -258,6 +258,12 @@ input[type="submit"].enabled { -ms-user-select: none; user-select: none; } +/* position controls for apps with app-navigation */ +#app-navigation+#app-content #controls { + left: 250px; + padding-right: 250px; +} + #controls .button, #controls button, #controls input[type='submit'], diff --git a/core/js/js.js b/core/js/js.js index d02dc6445f2..bc4d135f9a7 100644 --- a/core/js/js.js +++ b/core/js/js.js @@ -585,6 +585,13 @@ OC.search.customResults={}; OC.search.currentResult=-1; OC.search.lastQuery=''; OC.search.lastResults={}; +//translations for result type ids, can be extended by apps +OC.search.resultTypes={ + file: t('core','File'), + folder: t('core','Folder'), + image: t('core','Image'), + audio: t('core','Audio') +}; OC.addStyle.loaded=[]; OC.addScript.loaded=[]; @@ -1133,7 +1140,7 @@ function initCore() { setupMainMenu(); // just add snapper for logged in users - if($('#body-login, #body-public').length === 0) { + if($('#app-navigation').length) { // App sidebar on mobile var snapper = new Snap({ diff --git a/lib/private/files/cache/storage.php b/lib/private/files/cache/storage.php index 6b6b0bce9d7..3a267874431 100644 --- a/lib/private/files/cache/storage.php +++ b/lib/private/files/cache/storage.php @@ -43,12 +43,15 @@ class Storage { } } + /** + * @return string + */ public function getNumericId() { return $this->numericId; } /** - * @return string + * @return string|null */ public static function getStorageId($numericId) { @@ -62,37 +65,46 @@ class Storage { } /** - * @param string $storageId + * @return string|null */ - public static function exists($storageId) { + public static function getNumericStorageId($storageId) { if (strlen($storageId) > 64) { $storageId = md5($storageId); } + $sql = 'SELECT `numeric_id` FROM `*PREFIX*storages` WHERE `id` = ?'; $result = \OC_DB::executeAudited($sql, array($storageId)); if ($row = $result->fetchRow()) { - return true; + return $row['numeric_id']; } else { - return false; + return null; } } /** + * @param string $storageId + * @return bool + */ + public static function exists($storageId) { + return !is_null(self::getNumericStorageId($storageId)); + } + + /** * remove the entry for the storage * * @param string $storageId */ public static function remove($storageId) { - $storageCache = new Storage($storageId); - $numericId = $storageCache->getNumericId(); - if (strlen($storageId) > 64) { $storageId = md5($storageId); } $sql = 'DELETE FROM `*PREFIX*storages` WHERE `id` = ?'; \OC_DB::executeAudited($sql, array($storageId)); - $sql = 'DELETE FROM `*PREFIX*filecache` WHERE `storage` = ?'; - \OC_DB::executeAudited($sql, array($numericId)); + $numericId = self::exists($storageId); + if (!is_null($numericId)) { + $sql = 'DELETE FROM `*PREFIX*filecache` WHERE `storage` = ?'; + \OC_DB::executeAudited($sql, array($numericId)); + } } } diff --git a/lib/private/legacy/search.php b/lib/private/legacy/search.php new file mode 100644 index 00000000000..f77b43be2e0 --- /dev/null +++ b/lib/private/legacy/search.php @@ -0,0 +1,68 @@ +<?php +/** + * ownCloud + * + * @author Frank Karlitschek + * @copyright 2012 Frank Karlitschek frank@owncloud.org + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + +/** + * provides an interface to all search providers + * @deprecated see lib/search.php + */ +class OC_Search { + /** + * @return \OCP\ISearch + */ + private static function getSearch() { + return \OC::$server->getSearch(); + } + + /** + * Search all providers for $query + * @param string $query + * @return array An array of OCP\Search\Result's + */ + public static function search($query) { + return self::getSearch()->search($query); + } + + /** + * Register a new search provider to search with + * @param string $class class name of a OCP\Search\Provider + * @param array $options optional + */ + public static function registerProvider($class, $options = array()) { + return self::getSearch()->registerProvider($class, $options); + } + + /** + * Remove one existing search provider + * @param string $provider class name of a OCP\Search\Provider + */ + public static function removeProvider($provider) { + return self::getSearch()->removeProvider($provider); + } + + /** + * Remove all registered search providers + */ + public static function clearProviders() { + return self::getSearch()->clearProviders(); + } + +} diff --git a/lib/private/legacy/search/provider.php b/lib/private/legacy/search/provider.php new file mode 100644 index 00000000000..d200c988c45 --- /dev/null +++ b/lib/private/legacy/search/provider.php @@ -0,0 +1,22 @@ +<?php +/** + * ownCloud + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + +abstract class OC_Search_Provider extends \OCP\Search\Provider { + +} diff --git a/lib/private/legacy/search/provider/file.php b/lib/private/legacy/search/provider/file.php new file mode 100644 index 00000000000..e610281131d --- /dev/null +++ b/lib/private/legacy/search/provider/file.php @@ -0,0 +1,22 @@ +<?php +/** + * ownCloud + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + +class OC_Search_Provider_File extends \OC\Search\Provider\File { + +} diff --git a/lib/private/legacy/search/result.php b/lib/private/legacy/search/result.php new file mode 100644 index 00000000000..f3e6ecbb990 --- /dev/null +++ b/lib/private/legacy/search/result.php @@ -0,0 +1,35 @@ +<?php +/** + * ownCloud + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + +class OC_Search_Result extends \OCP\Search\Result { + + /** + * Create a new search result + * @param string $id unique identifier from application: '[app_name]/[item_identifier_in_app]' + * @param string $name displayed text of result + * @param string $link URL to the result within its app + * @param string $type @deprecated because it is now set in \OC\Search\Result descendants + */ + public function __construct($id = null, $name = null, $link = null, $type = null) { + $this->id = $id; + $this->name = $name; + $this->link = $link; + $this->type = $type; + } +} diff --git a/lib/private/mimetypes.list.php b/lib/private/mimetypes.list.php index 3fe454f41f1..ba1b9ca10b1 100644 --- a/lib/private/mimetypes.list.php +++ b/lib/private/mimetypes.list.php @@ -52,6 +52,7 @@ return array( 'c++' => array('text/x-c++src', null), 'deb' => array('application/x-deb', null), 'doc' => array('application/msword', null), + 'docm' => array('application/vnd.ms-word.document.macroEnabled.12', null), 'docx' => array('application/vnd.openxmlformats-officedocument.wordprocessingml.document', null), 'dot' => array('application/msword', null), 'dotx' => array('application/vnd.openxmlformats-officedocument.wordprocessingml.template', null), @@ -91,6 +92,7 @@ return array( 'mpg' => array('video/mpeg', null), 'msi' => array('application/x-msi', null), 'numbers' => array('application/x-iwork-numbers-sffnumbers', null), + 'odf' => array('application/vnd.oasis.opendocument.formula', null), 'odg' => array('application/vnd.oasis.opendocument.graphics', null), 'odp' => array('application/vnd.oasis.opendocument.presentation', null), 'ods' => array('application/vnd.oasis.opendocument.spreadsheet', null), @@ -104,7 +106,16 @@ return array( 'php' => array('application/x-php', null), 'pl' => array('application/x-perl', null), 'png' => array('image/png', null), - 'ppt' => array('application/mspowerpoint', null), + 'pot' => array('application/vnd.ms-powerpoint', null), + 'potm' => array('application/vnd.ms-powerpoint.template.macroEnabled.12', null), + 'potx' => array('application/vnd.openxmlformats-officedocument.presentationml.template', null), + 'ppa' => array('application/vnd.ms-powerpoint', null), + 'ppam' => array('application/vnd.ms-powerpoint.addin.macroEnabled.12', null), + 'pps' => array('application/vnd.ms-powerpoint', null), + 'ppsm' => array('application/vnd.ms-powerpoint.slideshow.macroEnabled.12', null), + 'ppsx' => array('application/vnd.openxmlformats-officedocument.presentationml.slideshow', null), + 'ppt' => array('application/vnd.ms-powerpoint', null), + 'pptm' => array('application/vnd.ms-powerpoint.presentation.macroEnabled.12', null), 'pptx' => array('application/vnd.openxmlformats-officedocument.presentationml.presentation', null), 'psd' => array('application/x-photoshop', null), 'py' => array('text/x-python', null), @@ -130,8 +141,15 @@ return array( 'woff' => array('application/font-woff', null), 'wmv' => array('video/x-ms-asf', null), 'xcf' => array('application/x-gimp', null), - 'xls' => array('application/msexcel', null), + 'xla' => array('application/vnd.ms-excel', null), + 'xlam' => array('application/vnd.ms-excel.addin.macroEnabled.12', null), + 'xls' => array('application/vnd.ms-excel', null), + 'xlsb' => array('application/vnd.ms-excel.sheet.binary.macroEnabled.12', null), + 'xlsm' => array('application/vnd.ms-excel.sheet.macroEnabled.12', null), 'xlsx' => array('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', null), + 'xlt' => array('application/vnd.ms-excel', null), + 'xltm' => array('application/vnd.ms-excel.template.macroEnabled.12', null), + 'xltx' => array('application/vnd.openxmlformats-officedocument.spreadsheetml.template', null), 'xml' => array('application/xml', 'text/plain'), 'zip' => array('application/zip', null), ); diff --git a/lib/private/search.php b/lib/private/search.php index 3f540090fdd..bcaebdddd9c 100644 --- a/lib/private/search.php +++ b/lib/private/search.php @@ -20,70 +20,77 @@ * */ +namespace OC; +use OCP\Search\Provider; +use OCP\ISearch; /** - * provides an interface to all search providers + * Provide an interface to all search providers */ -class OC_Search{ - static private $providers=array(); - static private $registeredProviders=array(); +class Search implements ISearch { - /** - * remove all registered search providers - */ - public static function clearProviders() { - self::$providers=array(); - self::$registeredProviders=array(); - } + private $providers = array(); + private $registeredProviders = array(); /** - * register a new search provider to be used + * Search all providers for $query + * @param string $query + * @return array An array of OC\Search\Result's */ - public static function registerProvider($class, $options=array()) { - self::$registeredProviders[]=array('class'=>$class, 'options'=>$options); + public function search($query) { + $this->initProviders(); + $results = array(); + foreach($this->providers as $provider) { + /** @var $provider Provider */ + $results = array_merge($results, $provider->search($query)); + } + return $results; } /** - * search all provider for $query - * @param string $query - * @return array An array of OC_Search_Result's + * Remove all registered search providers */ - public static function search($query) { - self::initProviders(); - $results=array(); - foreach(self::$providers as $provider) { - $results=array_merge($results, $provider->search($query)); - } - return $results; + public function clearProviders() { + $this->providers=array(); + $this->registeredProviders=array(); } /** - * remove an existing search provider - * @param string $provider class name of a OC_Search_Provider + * Remove one existing search provider + * @param string $provider class name of a OC\Search\Provider */ - public static function removeProvider($provider) { - self::$registeredProviders = array_filter( - self::$registeredProviders, - function ($element) use ($provider) { - return ($element['class'] != $provider); - } + public function removeProvider($provider) { + $this->registeredProviders = array_filter( + $this->registeredProviders, + function ($element) use ($provider) { + return ($element['class'] != $provider); + } ); // force regeneration of providers on next search - self::$providers=array(); + $this->providers=array(); } + /** + * Register a new search provider to search with + * @param string $class class name of a OC\Search\Provider + * @param array $options optional + */ + public function registerProvider($class, $options=array()) { + $this->registeredProviders[]=array('class'=>$class, 'options'=>$options); + } /** - * create instances of all the registered search providers + * Create instances of all the registered search providers */ - private static function initProviders() { - if(count(self::$providers)>0) { + private function initProviders() { + if(count($this->providers)>0) { return; } - foreach(self::$registeredProviders as $provider) { - $class=$provider['class']; - $options=$provider['options']; - self::$providers[]=new $class($options); + foreach($this->registeredProviders as $provider) { + $class = $provider['class']; + $options = $provider['options']; + $this->providers[]=new $class($options); } } + } diff --git a/lib/private/search/provider.php b/lib/private/search/provider.php deleted file mode 100644 index b617b9c5d94..00000000000 --- a/lib/private/search/provider.php +++ /dev/null @@ -1,18 +0,0 @@ -<?php -/** - * provides search functionalty - */ -abstract class OC_Search_Provider { - private $options; - - public function __construct($options) { - $this->options=$options; - } - - /** - * search for $query - * @param string $query - * @return array An array of OC_Search_Result's - */ - abstract public function search($query); -} diff --git a/lib/private/search/provider/file.php b/lib/private/search/provider/file.php index 9bd50931517..cbd3a253732 100644 --- a/lib/private/search/provider/file.php +++ b/lib/private/search/provider/file.php @@ -1,46 +1,69 @@ <?php +/** + * ownCloud + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ -class OC_Search_Provider_File extends OC_Search_Provider{ - function search($query) { - $files=\OC\Files\Filesystem::search($query, true); - $results=array(); - $l=OC_L10N::get('lib'); - foreach($files as $fileData) { - $path = $fileData['path']; - $mime = $fileData['mimetype']; +namespace OC\Search\Provider; +use OC\Files\Filesystem; + +/** + * Provide search results from the 'files' app + */ +class File extends \OCP\Search\Provider { - $name = basename($path); - $container = dirname($path); - $text = ''; - $skip = false; - if($mime=='httpd/unix-directory') { - $link = OC_Helper::linkTo( 'files', 'index.php', array('dir' => $path)); - $type = (string)$l->t('Files'); - }else{ - $link = OC_Helper::linkToRoute( 'download', array('file' => $path)); - $mimeBase = $fileData['mimepart']; - switch($mimeBase) { - case 'audio': - $skip = true; - break; - case 'text': - $type = (string)$l->t('Text'); - break; - case 'image': - $type = (string)$l->t('Images'); - break; - default: - if($mime=='application/xml') { - $type = (string)$l->t('Text'); - }else{ - $type = (string)$l->t('Files'); - } - } + /** + * Search for files and folders matching the given query + * @param string $query + * @return \OCP\Search\Result + */ + function search($query) { + $files = Filesystem::search($query); + $results = array(); + // edit results + foreach ($files as $fileData) { + // skip versions + if (strpos($fileData['path'], '_versions') === 0) { + continue; + } + // skip top-level folder + if ($fileData['name'] === 'files' && $fileData['parent'] === -1) { + continue; + } + // create audio result + if($fileData['mimepart'] === 'audio'){ + $result = new \OC\Search\Result\Audio($fileData); + } + // create image result + elseif($fileData['mimepart'] === 'image'){ + $result = new \OC\Search\Result\Image($fileData); + } + // create folder result + elseif($fileData['mimetype'] === 'httpd/unix-directory'){ + $result = new \OC\Search\Result\Folder($fileData); } - if(!$skip) { - $results[] = new OC_Search_Result($name, $text, $link, $type, $container); + // or create file result + else{ + $result = new \OC\Search\Result\File($fileData); } + // add to results + $results[] = $result; } + // return return $results; } + } diff --git a/lib/private/search/result.php b/lib/private/search/result.php deleted file mode 100644 index ceefeab2dae..00000000000 --- a/lib/private/search/result.php +++ /dev/null @@ -1,27 +0,0 @@ -<?php -/** - * a result of a search - */ -class OC_Search_Result{ - public $name; - public $text; - public $link; - public $type; - public $container; - - /** - * create a new search result - * @param string $name short name for the result - * @param string $text some more information about the result - * @param string $link link for the result - * @param string $type the type of result as human readable string ('File', 'Music', etc) - * @param string $container - */ - public function __construct($name, $text, $link, $type, $container) { - $this->name=$name; - $this->text=$text; - $this->link=$link; - $this->type=$type; - $this->container=$container; - } -} diff --git a/lib/private/search/result/audio.php b/lib/private/search/result/audio.php new file mode 100644 index 00000000000..3adbb400560 --- /dev/null +++ b/lib/private/search/result/audio.php @@ -0,0 +1,36 @@ +<?php +/** + * ownCloud + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OC\Search\Result; + +/** + * A found audio file + */ +class Audio extends File { + + /** + * Type name; translated in templates + * @var string + */ + public $type = 'audio'; + + /** + * @TODO add ID3 information + */ +} diff --git a/lib/private/search/result/file.php b/lib/private/search/result/file.php new file mode 100644 index 00000000000..da5fa64ef45 --- /dev/null +++ b/lib/private/search/result/file.php @@ -0,0 +1,111 @@ +<?php +/** + * ownCloud + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OC\Search\Result; +use \OC\Files\Filesystem; +/** + * A found file + */ +class File extends \OCP\Search\Result { + + /** + * Type name; translated in templates + * @var string + */ + public $type = 'file'; + + /** + * Path to file + * @var string + */ + public $path; + + /** + * Size, in bytes + * @var int + */ + public $size; + + /** + * Date modified, in human readable form + * @var string + */ + public $modified; + + /** + * File mime type + * @var string + */ + public $mime_type; + + /** + * File permissions: + * + * @var string + */ + public $permissions; + + /** + * Create a new file search result + * @param array $data file data given by provider + */ + public function __construct(array $data = null) { + $info = pathinfo($data['path']); + $this->id = $data['fileid']; + $this->name = $info['basename']; + $this->link = \OCP\Util::linkTo( + 'files', + 'index.php', + array('dir' => $info['dirname'], 'file' => $info['basename']) + ); + $this->permissions = self::get_permissions($data['path']); + $this->path = (strpos($data['path'], 'files') === 0) ? substr($data['path'], 5) : $data['path']; + $this->size = $data['size']; + $this->modified = $data['mtime']; + $this->mime_type = $data['mimetype']; + } + + /** + * Determine permissions for a given file path + * @param string $path + * @return int + */ + function get_permissions($path) { + // add read permissions + $permissions = \OCP\PERMISSION_READ; + // get directory + $fileinfo = pathinfo($path); + $dir = $fileinfo['dirname'] . '/'; + // add update permissions + if (Filesystem::isUpdatable($dir)) { + $permissions |= \OCP\PERMISSION_UPDATE; + } + // add delete permissions + if (Filesystem::isDeletable($dir)) { + $permissions |= \OCP\PERMISSION_DELETE; + } + // add share permissions + if (Filesystem::isSharable($dir)) { + $permissions |= \OCP\PERMISSION_SHARE; + } + // return + return $permissions; + } + +} diff --git a/lib/private/search/result/folder.php b/lib/private/search/result/folder.php new file mode 100644 index 00000000000..29469a1d112 --- /dev/null +++ b/lib/private/search/result/folder.php @@ -0,0 +1,33 @@ +<?php +/** + * ownCloud + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OC\Search\Result; + +/** + * A found folder + */ +class Folder extends File { + + /** + * Type name; translated in templates + * @var string + */ + public $type = 'folder'; + +} diff --git a/lib/private/search/result/image.php b/lib/private/search/result/image.php new file mode 100644 index 00000000000..f4e6be56c8d --- /dev/null +++ b/lib/private/search/result/image.php @@ -0,0 +1,36 @@ +<?php +/** + * ownCloud + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OC\Search\Result; + +/** + * A found image file + */ +class Image extends File { + + /** + * Type name; translated in templates + * @var string + */ + public $type = 'image'; + + /** + * @TODO add EXIF information + */ +} diff --git a/lib/private/server.php b/lib/private/server.php index 47bdee4b0f8..da705863078 100644 --- a/lib/private/server.php +++ b/lib/private/server.php @@ -186,6 +186,9 @@ class Server extends SimpleContainer implements IServerContainer { } return $router; }); + $this->registerService('Search', function($c){ + return new Search(); + }); $this->registerService('Db', function($c){ return new Db(); }); @@ -422,6 +425,13 @@ class Server extends SimpleContainer implements IServerContainer { return $this->query('Router'); } + /** + * Returns a search instance + * @return \OCP\ISearch + */ + function getSearch() { + return $this->query('Search'); + } /** * Returns an instance of the db facade diff --git a/lib/public/isearch.php b/lib/public/isearch.php new file mode 100644 index 00000000000..3b83dbf35e8 --- /dev/null +++ b/lib/public/isearch.php @@ -0,0 +1,57 @@ +<?php + +/** + * ownCloud - App Framework + * + * @author Jörn Dreyer + * @copyright 2014 Jörn Dreyer jfd@owncloud.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OCP; + + +/** + * Small Interface for Search + */ +interface ISearch { + + /** + * Search all providers for $query + * @param string $query + * @return array An array of OCP\Search\Result's + */ + public function search($query); + + /** + * Register a new search provider to search with + * @param string $class class name of a OCP\Search\Provider + * @param array $options optional + */ + public function registerProvider($class, $options = array()); + + /** + * Remove one existing search provider + * @param string $provider class name of a OCP\Search\Provider + */ + public function removeProvider($provider); + + /** + * Remove all registered search providers + */ + public function clearProviders(); + +} diff --git a/lib/public/iservercontainer.php b/lib/public/iservercontainer.php index 22176c36b8a..8bf97828581 100644 --- a/lib/public/iservercontainer.php +++ b/lib/public/iservercontainer.php @@ -204,4 +204,12 @@ interface IServerContainer { * @return \OCP\Route\IRouter */ function getRouter(); + + /** + * Returns a search instance + * + * @return \OCP\ISearch + */ + function getSearch(); + } diff --git a/lib/public/search/provider.php b/lib/public/search/provider.php new file mode 100644 index 00000000000..0506f091dd9 --- /dev/null +++ b/lib/public/search/provider.php @@ -0,0 +1,47 @@ +<?php +/** + * ownCloud + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OCP\Search; + +/** + * Provides a template for search functionality throughout ownCloud; + */ +abstract class Provider { + + /** + * List of options (currently unused) + * @var array + */ + private $options; + + /** + * Constructor + * @param array $options + */ + public function __construct($options) { + $this->options = $options; + } + + /** + * Search for $query + * @param string $query + * @return array An array of OCP\Search\Result's + */ + abstract public function search($query); +} diff --git a/lib/public/search/result.php b/lib/public/search/result.php new file mode 100644 index 00000000000..c70f1bde880 --- /dev/null +++ b/lib/public/search/result.php @@ -0,0 +1,65 @@ +<?php +/** + * ownCloud + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OCP\Search; + +/** + * The generic result of a search + */ +class Result { + + /** + * A unique identifier for the result, usually given as the item ID in its + * corresponding application. + * @var string + */ + public $id; + + /** + * The name of the item returned; this will be displayed in the search + * results. + * @var string + */ + public $name; + + /** + * URL to the application item. + * @var string + */ + public $link; + + /** + * The type of search result returned; for consistency, name this the same + * as the class name (e.g. \OC\Search\File -> 'file') in lowercase. + * @var string + */ + public $type = 'generic'; + + /** + * Create a new search result + * @param string $id unique identifier from application: '[app_name]/[item_identifier_in_app]' + * @param string $name displayed text of result + * @param string $link URL to the result within its app + */ + public function __construct($id = null, $name = null, $link = null) { + $this->id = $id; + $this->name = $name; + $this->link = $link; + } +} diff --git a/search/ajax/search.php b/search/ajax/search.php index 0cc1f9d30cd..546fccc644f 100644 --- a/search/ajax/search.php +++ b/search/ajax/search.php @@ -26,7 +26,7 @@ OC_JSON::checkLoggedIn(); $query=(isset($_GET['query']))?$_GET['query']:''; if($query) { - $result=OC_Search::search($query); + $result = \OC::$server->getSearch()->search($query); OC_JSON::encodedPrint($result); } else { diff --git a/search/js/result.js b/search/js/result.js index 780f513edcf..04e999c62ee 100644 --- a/search/js/result.js +++ b/search/js/result.js @@ -57,22 +57,27 @@ OC.search.showResults=function(results){ var row=$('#searchresults tr.template').clone(); row.removeClass('template'); row.addClass('result'); + row.data('type', typeid); row.data('name', type[i].name); row.data('text', type[i].text); - row.data('container', type[i].container); + row.data('index',index); + if (i === 0){ - row.children('td.type').text(typeid); + var typeName = OC.search.resultTypes[typeid]; + row.children('td.type').text(t('lib', typeName)); } row.find('td.result div.name').text(type[i].name); row.find('td.result div.text').text(type[i].text); - if (type[i].container) { - var containerName = OC.basename(type[i].container); + + if (type[i].path) { + var parent = OC.dirname(type[i].path); + var containerName = OC.basename(parent); if (containerName === '') { containerName = '/'; } var containerLink = OC.linkTo('files', 'index.php') - +'?dir='+encodeURIComponent(type[i].container) + +'?dir='+encodeURIComponent(parent) +'&scrollto='+encodeURIComponent(type[i].name); row.find('td.result a') .attr('href', containerLink) @@ -80,10 +85,16 @@ OC.search.showResults=function(results){ } else { row.find('td.result a').attr('href', type[i].link); } - row.data('index',index); + index++; - if(OC.search.customResults[typeid]){//give plugins the ability to customize the entries in here - OC.search.customResults[typeid](row,type[i]); + /** + * Give plugins the ability to customize the search results. For example: + * OC.search.customResults.file = function (row, item){ + * if(item.name.search('.json') >= 0) ... + * }; + */ + if(OC.search.customResults[typeid]){ + OC.search.customResults[typeid](row, type[i]); } $('#searchresults tbody').append(row); } @@ -104,4 +115,4 @@ OC.search.renderCurrent=function(){ $('#searchresults tr.result').removeClass('current'); $(result).addClass('current'); } -}; +};
\ No newline at end of file diff --git a/settings/css/settings.css b/settings/css/settings.css index 638d2fc576b..5fd16b2da86 100644 --- a/settings/css/settings.css +++ b/settings/css/settings.css @@ -5,17 +5,6 @@ select#languageinput, select#timezone { width:15em; } input#openid, input#webdav { width:20em; } -#user-controls { - -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; - position: fixed; - right: 0; - left: 250px; - height: 44px; - padding: 0; margin: 0; - background: #eee; border-bottom: 1px solid #e7e7e7; - z-index: 50; -} - /* PERSONAL */ #rootcert_import { margin: 0 0 10px 0; diff --git a/settings/templates/users/part.createuser.php b/settings/templates/users/part.createuser.php index 4d573168fc1..3dfd27ee52d 100644 --- a/settings/templates/users/part.createuser.php +++ b/settings/templates/users/part.createuser.php @@ -1,4 +1,4 @@ -<div id="user-controls"> +<div id="controls"> <form id="newuser" autocomplete="off"> <input id="newusername" type="text" placeholder="<?php p($l->t('Login Name'))?>" |