Hand in the route and the parameters of the request

Signed-off-by: Joas Schilling <coding@schilljs.com>
Signed-off-by: npmbuildbot[bot] <npmbuildbot[bot]@users.noreply.github.com>
This commit is contained in:
Joas Schilling 2020-08-05 09:49:18 +02:00 committed by npmbuildbot[bot]
parent d98f7c1bd8
commit ea8f68bea6
26 changed files with 167 additions and 56 deletions

View File

@ -77,7 +77,11 @@ class CommentsSearchProvider implements IProvider {
/**
* @inheritDoc
*/
public function getOrder(string $from): int {
public function getOrder(string $route, array $routeParameters): int {
if ($route === 'files.View.index') {
// Files first
return 0;
}
return 10;
}

View File

@ -96,8 +96,11 @@ class ContactsSearchProvider implements IProvider {
/**
* @inheritDoc
*/
public function getOrder(string $from): int {
return 7;
public function getOrder(string $route, array $routeParameters): int {
if ($route === 'contacts.Page.index') {
return -1;
}
return 20;
}
/**

View File

@ -82,7 +82,10 @@ class EventsSearchProvider extends ACalendarSearchProvider {
/**
* @inheritDoc
*/
public function getOrder(string $from): int {
public function getOrder(string $route, array $routeParameters): int {
if ($route === 'calendar.View.index') {
return -1;
}
return 10;
}

View File

@ -74,7 +74,10 @@ class TasksSearchProvider extends ACalendarSearchProvider {
/**
* @inheritDoc
*/
public function getOrder(string $from): int {
public function getOrder(string $route, array $routeParameters): int {
if ($route === 'tasks.Page.index') {
return -1;
}
return 10;
}

View File

@ -77,7 +77,11 @@ class FilesSearchProvider implements IProvider {
/**
* @inheritDoc
*/
public function getOrder(string $from): int {
public function getOrder(string $route, array $routeParameters): int {
if ($route === 'files.View.index') {
// Before comments
return -5;
}
return 5;
}

View File

@ -75,9 +75,8 @@ class SectionSearch implements IProvider {
/**
* @inheritDoc
*/
public function getOrder(string $from): int {
if (strpos($from, $this->urlGenerator->linkToRoute('settings.PersonalSettings.index') === 0)
|| strpos($from, $this->urlGenerator->linkToRoute('settings.AdminSettings.index')) === 0) {
public function getOrder(string $route, array $routeParameters): int {
if ($route === 'settings.PersonalSettings.index' || $route === 'settings.AdminSettings.index') {
return -1;
}
return 20;

View File

@ -32,7 +32,9 @@ use OCP\AppFramework\Http;
use OCP\AppFramework\Http\JSONResponse;
use OCP\IRequest;
use OCP\IUserSession;
use OCP\Route\IRouter;
use OCP\Search\ISearchQuery;
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
class UnifiedSearchController extends Controller {
@ -42,26 +44,33 @@ class UnifiedSearchController extends Controller {
/** @var IUserSession */
private $userSession;
/** @var IRouter */
private $router;
public function __construct(IRequest $request,
IUserSession $userSession,
SearchComposer $composer) {
SearchComposer $composer,
IRouter $router) {
parent::__construct('core', $request);
$this->composer = $composer;
$this->userSession = $userSession;
$this->router = $router;
}
/**
* @NoAdminRequired
* @NoCSRFRequired
*
*
* @param string $from the url the user is currently at
*
*
* @return JSONResponse
*/
public function getProviders(string $from): JSONResponse {
public function getProviders(string $from = ''): JSONResponse {
[$route, $parameters] = $this->getRouteInformation($from);
return new JSONResponse(
$this->composer->getProviders($from)
$this->composer->getProviders($route, $parameters)
);
}
@ -74,6 +83,7 @@ class UnifiedSearchController extends Controller {
* @param int|null $sortOrder
* @param int|null $limit
* @param int|string|null $cursor
* @param string $from
*
* @return JSONResponse
*/
@ -81,10 +91,12 @@ class UnifiedSearchController extends Controller {
string $term = '',
?int $sortOrder = null,
?int $limit = null,
$cursor = null): JSONResponse {
$cursor = null,
string $from = ''): JSONResponse {
if (empty(trim($term))) {
return new JSONResponse(null, Http::STATUS_BAD_REQUEST);
}
[$route, $routeParameters] = $this->getRouteInformation($from);
return new JSONResponse(
$this->composer->search(
@ -94,9 +106,45 @@ class UnifiedSearchController extends Controller {
$term,
$sortOrder ?? ISearchQuery::SORT_DATE_DESC,
$limit ?? SearchQuery::LIMIT_DEFAULT,
$cursor
$cursor,
$route,
$routeParameters
)
)
);
}
protected function getRouteInformation(string $url): array {
$routeStr = '';
$parameters = [];
if ($url !== '') {
$urlParts = parse_url($url);
try {
$parameters = $this->router->findMatchingRoute($urlParts['path']);
// contacts.PageController.index => contacts.Page.index
$route = $parameters['caller'];
if (substr($route[1], -10) === 'Controller') {
$route[1] = substr($route[1], 0, -10);
}
$routeStr = implode('.', $route);
// cleanup
unset($parameters['_route'], $parameters['action'], $parameters['caller']);
} catch (ResourceNotFoundException $exception) {
}
if (isset($urlParts['query'])) {
parse_str($urlParts['query'], $queryParameters);
$parameters = array_merge($parameters, $queryParameters);
}
}
return [
$routeStr,
$parameters,
];
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -24,8 +24,7 @@ import { loadState } from '@nextcloud/initial-state'
import axios from '@nextcloud/axios'
export const defaultLimit = loadState('unified-search', 'limit-default')
export const activeApp = loadState('core', 'active-app')
export const minSearchLength = 2
/**
* Get the list of available search providers
*

View File

@ -67,7 +67,7 @@
<!-- Grouped search results -->
<template v-else>
<ul v-for="(list, type, typesIndex) in orderedResults"
<ul v-for="({list, type}, typesIndex) in orderedResults"
:key="type"
class="unified-search__results"
:class="`unified-search__results-${type}`"
@ -97,7 +97,7 @@
</template>
<script>
import { getTypes, search, defaultLimit, activeApp } from '../services/UnifiedSearchService'
import { minSearchLength, getTypes, search, defaultLimit } from '../services/UnifiedSearchService'
import EmptyContent from '@nextcloud/vue/dist/Components/EmptyContent'
import Magnify from 'vue-material-design-icons/Magnify'
import debounce from 'debounce'
@ -106,8 +106,6 @@ import HeaderMenu from '../components/HeaderMenu'
import SearchResult from '../components/UnifiedSearch/SearchResult'
import SearchResultPlaceholder from '../components/UnifiedSearch/SearchResultPlaceholder'
const minSearchLength = 2
export default {
name: 'UnifiedSearch',
@ -132,7 +130,6 @@ export default {
query: '',
focused: null,
activeApp,
defaultLimit,
minSearchLength,
@ -163,18 +160,16 @@ export default {
},
/**
* Order results by putting the active app first
* Return ordered results
* @returns {Object}
*/
orderedResults() {
const ordered = {}
Object.keys(this.results)
.sort((a, b) => this.typesMap[a].order - this.typesMap[b].order)
.forEach(type => {
ordered[type] = this.results[type]
})
return ordered
return Object.values(this.typesIDs)
.filter(type => type in this.results)
.map(type => ({
type,
list: this.results[type],
}))
},
/**
@ -390,10 +385,10 @@ export default {
* @returns {Array}
*/
limitIfAny(list, type) {
if (!this.limits[type]) {
return list
if (type in this.limits) {
return list.slice(0, this.limits[type])
}
return list.slice(0, this.limits[type])
return list
},
getResultsList() {

View File

@ -239,9 +239,9 @@ class Router implements IRouter {
*
* @param string $url The url to find
* @throws \Exception
* @return void
* @return array
*/
public function match($url) {
public function findMatchingRoute(string $url): array {
if (substr($url, 0, 6) === '/apps/') {
// empty string / 'apps' / $app / rest of the route
list(, , $app,) = explode('/', $url, 4);
@ -287,6 +287,19 @@ class Router implements IRouter {
}
}
return $parameters;
}
/**
* Find and execute the route matching $url
*
* @param string $url The url to find
* @throws \Exception
* @return void
*/
public function match($url) {
$parameters = $this->findMatchingRoute($url);
\OC::$server->getEventLogger()->start('run_route', 'Run route');
if (isset($parameters['caller'])) {
$caller = $parameters['caller'];

View File

@ -109,19 +109,20 @@ class SearchComposer {
* Get a list of all provider IDs & Names for the consecutive calls to `search`
* Sort the list by the order property
*
* @param string $from the url the user is currently at
* @param string $route the route the user is currently at
* @param array $routeParameters the parameters of the route the user is currently at
*
* @return array
*/
public function getProviders(string $from): array {
public function getProviders(string $route, array $routeParameters): array {
$this->loadLazyProviders();
$providers = array_values(
array_map(function (IProvider $provider) use ($from) {
array_map(function (IProvider $provider) use ($route, $routeParameters) {
return [
'id' => $provider->getId(),
'name' => $provider->getName(),
'order' => $provider->getOrder($from)
'order' => $provider->getOrder($route, $routeParameters),
];
}, $this->providers)
);

View File

@ -42,20 +42,32 @@ class SearchQuery implements ISearchQuery {
/** @var int|string|null */
private $cursor;
/** @var string */
private $route;
/** @var array */
private $routeParameters;
/**
* @param string $term
* @param int $sortOrder
* @param int $limit
* @param int|string|null $cursor
* @param string $route
* @param array $routeParameters
*/
public function __construct(string $term,
int $sortOrder = ISearchQuery::SORT_DATE_DESC,
int $limit = self::LIMIT_DEFAULT,
$cursor = null) {
$cursor = null,
string $route = '',
array $routeParameters = []) {
$this->term = $term;
$this->sortOrder = $sortOrder;
$this->limit = $limit;
$this->cursor = $cursor;
$this->route = $route;
$this->routeParameters = $routeParameters;
}
/**
@ -85,4 +97,18 @@ class SearchQuery implements ISearchQuery {
public function getCursor() {
return $this->cursor;
}
/**
* @inheritDoc
*/
public function getRoute(): string {
return $this->route;
}
/**
* @inheritDoc
*/
public function getRouteParameters(): array {
return $this->routeParameters;
}
}

View File

@ -68,13 +68,14 @@ interface IProvider {
* Get the search provider order
* The lower the int, the higher it will be sorted (0 will be before 10)
*
* @param string $from the url the user is currently at. (e.g. /apps/files/?dir=/&fileid=982)
* @param string $route the route the user is currently at, e.g. files.view.index
* @param array $routeParameters the parameters of the route the user is currently at, e.g. [fileId = 982, dir = "/"]
*
* @return int
*
* @since 20.0.0
*/
public function getOrder(string $from): int;
public function getOrder(string $route, array $routeParameters): int;
/**
* Find matching search entries in an app

View File

@ -76,4 +76,16 @@ interface ISearchQuery {
* @since 20.0.0
*/
public function getCursor();
/**
* @return string
* @since 20.0.0
*/
public function getRoute(): string;
/**
* @return array
* @since 20.0.0
*/
public function getRouteParameters(): array;
}