Merge pull request #4553 from owncloud/update_search_classes

Update search classes
This commit is contained in:
Vincent Petry 2014-06-06 13:24:16 +02:00
commit 5cebb6fb9b
22 changed files with 692 additions and 139 deletions

View File

@ -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');

View File

@ -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'));

View File

@ -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=[];

View File

@ -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();
}
}

View File

@ -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 {
}

View File

@ -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 {
}

View File

@ -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;
}
}

View File

@ -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 {
private $providers = array();
private $registeredProviders = array();
/**
* remove all registered search providers
*/
public static function clearProviders() {
self::$providers=array();
self::$registeredProviders=array();
}
/**
* register a new search provider to be used
*/
public static function registerProvider($class, $options=array()) {
self::$registeredProviders[]=array('class'=>$class, 'options'=>$options);
}
/**
* search all provider for $query
* Search all providers for $query
* @param string $query
* @return array An array of OC_Search_Result's
* @return array An array of OC\Search\Result's
*/
public static function search($query) {
self::initProviders();
$results=array();
foreach(self::$providers as $provider) {
$results=array_merge($results, $provider->search($query));
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;
}
/**
* remove an existing search provider
* @param string $provider class name of a OC_Search_Provider
* Remove all registered search providers
*/
public static function removeProvider($provider) {
self::$registeredProviders = array_filter(
self::$registeredProviders,
function ($element) use ($provider) {
return ($element['class'] != $provider);
}
);
// force regeneration of providers on next search
self::$providers=array();
public function clearProviders() {
$this->providers=array();
$this->registeredProviders=array();
}
/**
* create instances of all the registered search providers
* Remove one existing search provider
* @param string $provider class name of a OC\Search\Provider
*/
private static function initProviders() {
if(count(self::$providers)>0) {
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
$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
*/
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);
}
}
}

View File

@ -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);
}

View File

@ -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{
namespace OC\Search\Provider;
use OC\Files\Filesystem;
/**
* Provide search results from the 'files' app
*/
class File extends \OCP\Search\Provider {
/**
* Search for files and folders matching the given query
* @param string $query
* @return \OCP\Search\Result
*/
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'];
$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');
}
}
$files = Filesystem::search($query);
$results = array();
// edit results
foreach ($files as $fileData) {
// skip versions
if (strpos($fileData['path'], '_versions') === 0) {
continue;
}
if(!$skip) {
$results[] = new OC_Search_Result($name, $text, $link, $type, $container);
// 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);
}
// or create file result
else{
$result = new \OC\Search\Result\File($fileData);
}
// add to results
$results[] = $result;
}
// return
return $results;
}
}

View File

@ -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;
}
}

View File

@ -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
*/
}

View File

@ -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;
}
}

View File

@ -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';
}

View File

@ -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
*/
}

View File

@ -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

57
lib/public/isearch.php Normal file
View File

@ -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();
}

View File

@ -204,4 +204,12 @@ interface IServerContainer {
* @return \OCP\Route\IRouter
*/
function getRouter();
/**
* Returns a search instance
*
* @return \OCP\ISearch
*/
function getSearch();
}

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -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 {

View File

@ -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);
}