Passed
Push — master ( 99ee00...47e725 )
by John
12:29 queued 19s
created
core/routes.php 1 patch
Indentation   +77 added lines, -77 removed lines patch added patch discarded remove patch
@@ -37,87 +37,87 @@  discard block
 block discarded – undo
37 37
 /** @var Application $application */
38 38
 $application = \OC::$server->query(Application::class);
39 39
 $application->registerRoutes($this, [
40
-	'routes' => [
41
-		['name' => 'lost#email', 'url' => '/lostpassword/email', 'verb' => 'POST'],
42
-		['name' => 'lost#resetform', 'url' => '/lostpassword/reset/form/{token}/{userId}', 'verb' => 'GET'],
43
-		['name' => 'lost#setPassword', 'url' => '/lostpassword/set/{token}/{userId}', 'verb' => 'POST'],
44
-		['name' => 'user#getDisplayNames', 'url' => '/displaynames', 'verb' => 'POST'],
45
-		['name' => 'avatar#getAvatar', 'url' => '/avatar/{userId}/{size}', 'verb' => 'GET'],
46
-		['name' => 'avatar#deleteAvatar', 'url' => '/avatar/', 'verb' => 'DELETE'],
47
-		['name' => 'avatar#postCroppedAvatar', 'url' => '/avatar/cropped', 'verb' => 'POST'],
48
-		['name' => 'avatar#getTmpAvatar', 'url' => '/avatar/tmp', 'verb' => 'GET'],
49
-		['name' => 'avatar#postAvatar', 'url' => '/avatar/', 'verb' => 'POST'],
50
-		['name' => 'GuestAvatar#getAvatar', 'url' => '/avatar/guest/{guestName}/{size}', 'verb' => 'GET'],
51
-		['name' => 'CSRFToken#index', 'url' => '/csrftoken', 'verb' => 'GET'],
52
-		['name' => 'login#tryLogin', 'url' => '/login', 'verb' => 'POST'],
53
-		['name' => 'login#confirmPassword', 'url' => '/login/confirm', 'verb' => 'POST'],
54
-		['name' => 'login#showLoginForm', 'url' => '/login', 'verb' => 'GET'],
55
-		['name' => 'login#logout', 'url' => '/logout', 'verb' => 'GET'],
56
-		// Original login flow used by all clients
57
-		['name' => 'ClientFlowLogin#showAuthPickerPage', 'url' => '/login/flow', 'verb' => 'GET'],
58
-		['name' => 'ClientFlowLogin#generateAppPassword', 'url' => '/login/flow', 'verb' => 'POST'],
59
-		['name' => 'ClientFlowLogin#grantPage', 'url' => '/login/flow/grant', 'verb' => 'GET'],
60
-		['name' => 'ClientFlowLogin#apptokenRedirect', 'url' => '/login/flow/apptoken', 'verb' => 'POST'],
61
-		// NG login flow used by desktop client in case of Kerberos/fancy 2fa (smart cards for example)
62
-		['name' => 'ClientFlowLoginV2#poll', 'url' => '/login/v2/poll', 'verb' => 'POST'],
63
-		['name' => 'ClientFlowLoginV2#showAuthPickerPage', 'url' => '/login/v2/flow', 'verb' => 'GET'],
64
-		['name' => 'ClientFlowLoginV2#landing', 'url' => '/login/v2/flow/{token}', 'verb' => 'GET'],
65
-		['name' => 'ClientFlowLoginV2#grantPage', 'url' => '/login/v2/grant', 'verb' => 'GET'],
66
-		['name' => 'ClientFlowLoginV2#generateAppPassword', 'url' => '/login/v2/grant', 'verb' => 'POST'],
67
-		['name' => 'ClientFlowLoginV2#init', 'url' => '/login/v2', 'verb' => 'POST'],
68
-		['name' => 'TwoFactorChallenge#selectChallenge', 'url' => '/login/selectchallenge', 'verb' => 'GET'],
69
-		['name' => 'TwoFactorChallenge#showChallenge', 'url' => '/login/challenge/{challengeProviderId}', 'verb' => 'GET'],
70
-		['name' => 'TwoFactorChallenge#solveChallenge', 'url' => '/login/challenge/{challengeProviderId}', 'verb' => 'POST'],
71
-		['name' => 'TwoFactorChallenge#setupProviders', 'url' => 'login/setupchallenge', 'verb' => 'GET'],
72
-		['name' => 'TwoFactorChallenge#setupProvider', 'url' => 'login/setupchallenge/{providerId}', 'verb' => 'GET'],
73
-		['name' => 'TwoFactorChallenge#confirmProviderSetup', 'url' => 'login/setupchallenge/{providerId}', 'verb' => 'POST'],
74
-		['name' => 'OCJS#getConfig', 'url' => '/core/js/oc.js', 'verb' => 'GET'],
75
-		['name' => 'Preview#getPreviewByFileId', 'url' => '/core/preview', 'verb' => 'GET'],
76
-		['name' => 'Preview#getPreview', 'url' => '/core/preview.png', 'verb' => 'GET'],
77
-		['name' => 'RecommendedApps#index', 'url' => '/core/apps/recommended', 'verb' => 'GET'],
78
-		['name' => 'Svg#getSvgFromCore', 'url' => '/svg/core/{folder}/{fileName}', 'verb' => 'GET'],
79
-		['name' => 'Svg#getSvgFromApp', 'url' => '/svg/{app}/{fileName}', 'verb' => 'GET'],
80
-		['name' => 'Css#getCss', 'url' => '/css/{appName}/{fileName}', 'verb' => 'GET'],
81
-		['name' => 'Js#getJs', 'url' => '/js/{appName}/{fileName}', 'verb' => 'GET'],
82
-		['name' => 'contactsMenu#index', 'url' => '/contactsmenu/contacts', 'verb' => 'POST'],
83
-		['name' => 'contactsMenu#findOne', 'url' => '/contactsmenu/findOne', 'verb' => 'POST'],
84
-		['name' => 'WalledGarden#get', 'url' => '/204', 'verb' => 'GET'],
85
-		['name' => 'Search#search', 'url' => '/core/search', 'verb' => 'GET'],
86
-		['name' => 'Wipe#checkWipe', 'url' => '/core/wipe/check', 'verb' => 'POST'],
87
-		['name' => 'Wipe#wipeDone', 'url' => '/core/wipe/success', 'verb' => 'POST'],
40
+    'routes' => [
41
+        ['name' => 'lost#email', 'url' => '/lostpassword/email', 'verb' => 'POST'],
42
+        ['name' => 'lost#resetform', 'url' => '/lostpassword/reset/form/{token}/{userId}', 'verb' => 'GET'],
43
+        ['name' => 'lost#setPassword', 'url' => '/lostpassword/set/{token}/{userId}', 'verb' => 'POST'],
44
+        ['name' => 'user#getDisplayNames', 'url' => '/displaynames', 'verb' => 'POST'],
45
+        ['name' => 'avatar#getAvatar', 'url' => '/avatar/{userId}/{size}', 'verb' => 'GET'],
46
+        ['name' => 'avatar#deleteAvatar', 'url' => '/avatar/', 'verb' => 'DELETE'],
47
+        ['name' => 'avatar#postCroppedAvatar', 'url' => '/avatar/cropped', 'verb' => 'POST'],
48
+        ['name' => 'avatar#getTmpAvatar', 'url' => '/avatar/tmp', 'verb' => 'GET'],
49
+        ['name' => 'avatar#postAvatar', 'url' => '/avatar/', 'verb' => 'POST'],
50
+        ['name' => 'GuestAvatar#getAvatar', 'url' => '/avatar/guest/{guestName}/{size}', 'verb' => 'GET'],
51
+        ['name' => 'CSRFToken#index', 'url' => '/csrftoken', 'verb' => 'GET'],
52
+        ['name' => 'login#tryLogin', 'url' => '/login', 'verb' => 'POST'],
53
+        ['name' => 'login#confirmPassword', 'url' => '/login/confirm', 'verb' => 'POST'],
54
+        ['name' => 'login#showLoginForm', 'url' => '/login', 'verb' => 'GET'],
55
+        ['name' => 'login#logout', 'url' => '/logout', 'verb' => 'GET'],
56
+        // Original login flow used by all clients
57
+        ['name' => 'ClientFlowLogin#showAuthPickerPage', 'url' => '/login/flow', 'verb' => 'GET'],
58
+        ['name' => 'ClientFlowLogin#generateAppPassword', 'url' => '/login/flow', 'verb' => 'POST'],
59
+        ['name' => 'ClientFlowLogin#grantPage', 'url' => '/login/flow/grant', 'verb' => 'GET'],
60
+        ['name' => 'ClientFlowLogin#apptokenRedirect', 'url' => '/login/flow/apptoken', 'verb' => 'POST'],
61
+        // NG login flow used by desktop client in case of Kerberos/fancy 2fa (smart cards for example)
62
+        ['name' => 'ClientFlowLoginV2#poll', 'url' => '/login/v2/poll', 'verb' => 'POST'],
63
+        ['name' => 'ClientFlowLoginV2#showAuthPickerPage', 'url' => '/login/v2/flow', 'verb' => 'GET'],
64
+        ['name' => 'ClientFlowLoginV2#landing', 'url' => '/login/v2/flow/{token}', 'verb' => 'GET'],
65
+        ['name' => 'ClientFlowLoginV2#grantPage', 'url' => '/login/v2/grant', 'verb' => 'GET'],
66
+        ['name' => 'ClientFlowLoginV2#generateAppPassword', 'url' => '/login/v2/grant', 'verb' => 'POST'],
67
+        ['name' => 'ClientFlowLoginV2#init', 'url' => '/login/v2', 'verb' => 'POST'],
68
+        ['name' => 'TwoFactorChallenge#selectChallenge', 'url' => '/login/selectchallenge', 'verb' => 'GET'],
69
+        ['name' => 'TwoFactorChallenge#showChallenge', 'url' => '/login/challenge/{challengeProviderId}', 'verb' => 'GET'],
70
+        ['name' => 'TwoFactorChallenge#solveChallenge', 'url' => '/login/challenge/{challengeProviderId}', 'verb' => 'POST'],
71
+        ['name' => 'TwoFactorChallenge#setupProviders', 'url' => 'login/setupchallenge', 'verb' => 'GET'],
72
+        ['name' => 'TwoFactorChallenge#setupProvider', 'url' => 'login/setupchallenge/{providerId}', 'verb' => 'GET'],
73
+        ['name' => 'TwoFactorChallenge#confirmProviderSetup', 'url' => 'login/setupchallenge/{providerId}', 'verb' => 'POST'],
74
+        ['name' => 'OCJS#getConfig', 'url' => '/core/js/oc.js', 'verb' => 'GET'],
75
+        ['name' => 'Preview#getPreviewByFileId', 'url' => '/core/preview', 'verb' => 'GET'],
76
+        ['name' => 'Preview#getPreview', 'url' => '/core/preview.png', 'verb' => 'GET'],
77
+        ['name' => 'RecommendedApps#index', 'url' => '/core/apps/recommended', 'verb' => 'GET'],
78
+        ['name' => 'Svg#getSvgFromCore', 'url' => '/svg/core/{folder}/{fileName}', 'verb' => 'GET'],
79
+        ['name' => 'Svg#getSvgFromApp', 'url' => '/svg/{app}/{fileName}', 'verb' => 'GET'],
80
+        ['name' => 'Css#getCss', 'url' => '/css/{appName}/{fileName}', 'verb' => 'GET'],
81
+        ['name' => 'Js#getJs', 'url' => '/js/{appName}/{fileName}', 'verb' => 'GET'],
82
+        ['name' => 'contactsMenu#index', 'url' => '/contactsmenu/contacts', 'verb' => 'POST'],
83
+        ['name' => 'contactsMenu#findOne', 'url' => '/contactsmenu/findOne', 'verb' => 'POST'],
84
+        ['name' => 'WalledGarden#get', 'url' => '/204', 'verb' => 'GET'],
85
+        ['name' => 'Search#search', 'url' => '/core/search', 'verb' => 'GET'],
86
+        ['name' => 'Wipe#checkWipe', 'url' => '/core/wipe/check', 'verb' => 'POST'],
87
+        ['name' => 'Wipe#wipeDone', 'url' => '/core/wipe/success', 'verb' => 'POST'],
88 88
 
89
-		// Logins for passwordless auth
90
-		['name' => 'WebAuthn#startAuthentication', 'url' => 'login/webauthn/start', 'verb' => 'POST'],
91
-		['name' => 'WebAuthn#finishAuthentication', 'url' => 'login/webauthn/finish', 'verb' => 'POST'],
92
-	],
93
-	'ocs' => [
94
-		['root' => '/cloud', 'name' => 'OCS#getCapabilities', 'url' => '/capabilities', 'verb' => 'GET'],
95
-		['root' => '', 'name' => 'OCS#getConfig', 'url' => '/config', 'verb' => 'GET'],
96
-		['root' => '/person', 'name' => 'OCS#personCheck', 'url' => '/check', 'verb' => 'POST'],
97
-		['root' => '/identityproof', 'name' => 'OCS#getIdentityProof', 'url' => '/key/{cloudId}', 'verb' => 'GET'],
98
-		['root' => '/core', 'name' => 'Navigation#getAppsNavigation', 'url' => '/navigation/apps', 'verb' => 'GET'],
99
-		['root' => '/core', 'name' => 'Navigation#getSettingsNavigation', 'url' => '/navigation/settings', 'verb' => 'GET'],
100
-		['root' => '/core', 'name' => 'AutoComplete#get', 'url' => '/autocomplete/get', 'verb' => 'GET'],
101
-		['root' => '/core', 'name' => 'WhatsNew#get', 'url' => '/whatsnew', 'verb' => 'GET'],
102
-		['root' => '/core', 'name' => 'WhatsNew#dismiss', 'url' => '/whatsnew', 'verb' => 'POST'],
103
-		['root' => '/core', 'name' => 'AppPassword#getAppPassword', 'url' => '/getapppassword', 'verb' => 'GET'],
104
-		['root' => '/core', 'name' => 'AppPassword#rotateAppPassword', 'url' => '/apppassword/rotate', 'verb' => 'POST'],
105
-		['root' => '/core', 'name' => 'AppPassword#deleteAppPassword', 'url' => '/apppassword', 'verb' => 'DELETE'],
89
+        // Logins for passwordless auth
90
+        ['name' => 'WebAuthn#startAuthentication', 'url' => 'login/webauthn/start', 'verb' => 'POST'],
91
+        ['name' => 'WebAuthn#finishAuthentication', 'url' => 'login/webauthn/finish', 'verb' => 'POST'],
92
+    ],
93
+    'ocs' => [
94
+        ['root' => '/cloud', 'name' => 'OCS#getCapabilities', 'url' => '/capabilities', 'verb' => 'GET'],
95
+        ['root' => '', 'name' => 'OCS#getConfig', 'url' => '/config', 'verb' => 'GET'],
96
+        ['root' => '/person', 'name' => 'OCS#personCheck', 'url' => '/check', 'verb' => 'POST'],
97
+        ['root' => '/identityproof', 'name' => 'OCS#getIdentityProof', 'url' => '/key/{cloudId}', 'verb' => 'GET'],
98
+        ['root' => '/core', 'name' => 'Navigation#getAppsNavigation', 'url' => '/navigation/apps', 'verb' => 'GET'],
99
+        ['root' => '/core', 'name' => 'Navigation#getSettingsNavigation', 'url' => '/navigation/settings', 'verb' => 'GET'],
100
+        ['root' => '/core', 'name' => 'AutoComplete#get', 'url' => '/autocomplete/get', 'verb' => 'GET'],
101
+        ['root' => '/core', 'name' => 'WhatsNew#get', 'url' => '/whatsnew', 'verb' => 'GET'],
102
+        ['root' => '/core', 'name' => 'WhatsNew#dismiss', 'url' => '/whatsnew', 'verb' => 'POST'],
103
+        ['root' => '/core', 'name' => 'AppPassword#getAppPassword', 'url' => '/getapppassword', 'verb' => 'GET'],
104
+        ['root' => '/core', 'name' => 'AppPassword#rotateAppPassword', 'url' => '/apppassword/rotate', 'verb' => 'POST'],
105
+        ['root' => '/core', 'name' => 'AppPassword#deleteAppPassword', 'url' => '/apppassword', 'verb' => 'DELETE'],
106 106
 
107
-		['root' => '/collaboration', 'name' => 'CollaborationResources#searchCollections', 'url' => '/resources/collections/search/{filter}', 'verb' => 'GET'],
108
-		['root' => '/collaboration', 'name' => 'CollaborationResources#listCollection', 'url' => '/resources/collections/{collectionId}', 'verb' => 'GET'],
109
-		['root' => '/collaboration', 'name' => 'CollaborationResources#renameCollection', 'url' => '/resources/collections/{collectionId}', 'verb' => 'PUT'],
110
-		['root' => '/collaboration', 'name' => 'CollaborationResources#addResource', 'url' => '/resources/collections/{collectionId}', 'verb' => 'POST'],
107
+        ['root' => '/collaboration', 'name' => 'CollaborationResources#searchCollections', 'url' => '/resources/collections/search/{filter}', 'verb' => 'GET'],
108
+        ['root' => '/collaboration', 'name' => 'CollaborationResources#listCollection', 'url' => '/resources/collections/{collectionId}', 'verb' => 'GET'],
109
+        ['root' => '/collaboration', 'name' => 'CollaborationResources#renameCollection', 'url' => '/resources/collections/{collectionId}', 'verb' => 'PUT'],
110
+        ['root' => '/collaboration', 'name' => 'CollaborationResources#addResource', 'url' => '/resources/collections/{collectionId}', 'verb' => 'POST'],
111 111
 
112
-		['root' => '/collaboration', 'name' => 'CollaborationResources#removeResource', 'url' => '/resources/collections/{collectionId}', 'verb' => 'DELETE'],
113
-		['root' => '/collaboration', 'name' => 'CollaborationResources#getCollectionsByResource', 'url' => '/resources/{resourceType}/{resourceId}', 'verb' => 'GET'],
114
-		['root' => '/collaboration', 'name' => 'CollaborationResources#createCollectionOnResource', 'url' => '/resources/{baseResourceType}/{baseResourceId}', 'verb' => 'POST'],
112
+        ['root' => '/collaboration', 'name' => 'CollaborationResources#removeResource', 'url' => '/resources/collections/{collectionId}', 'verb' => 'DELETE'],
113
+        ['root' => '/collaboration', 'name' => 'CollaborationResources#getCollectionsByResource', 'url' => '/resources/{resourceType}/{resourceId}', 'verb' => 'GET'],
114
+        ['root' => '/collaboration', 'name' => 'CollaborationResources#createCollectionOnResource', 'url' => '/resources/{baseResourceType}/{baseResourceId}', 'verb' => 'POST'],
115 115
 
116
-		// Unified search
117
-		['root' => '/search', 'name' => 'UnifiedSearch#getProviders', 'url' => '/providers', 'verb' => 'GET'],
118
-		['root' => '/search', 'name' => 'UnifiedSearch#search', 'url' => '/providers/{providerId}/search', 'verb' => 'GET'],
116
+        // Unified search
117
+        ['root' => '/search', 'name' => 'UnifiedSearch#getProviders', 'url' => '/providers', 'verb' => 'GET'],
118
+        ['root' => '/search', 'name' => 'UnifiedSearch#search', 'url' => '/providers/{providerId}/search', 'verb' => 'GET'],
119 119
 
120
-	],
120
+    ],
121 121
 ]);
122 122
 
123 123
 // Post installation check
@@ -126,4 +126,4 @@  discard block
 block discarded – undo
126 126
 // Core ajax actions
127 127
 // Routing
128 128
 $this->create('core_ajax_update', '/core/ajax/update.php')
129
-	->actionInclude('core/ajax/update.php');
129
+    ->actionInclude('core/ajax/update.php');
Please login to merge, or discard this patch.
core/Controller/UnifiedSearchController.php 1 patch
Indentation   +109 added lines, -109 removed lines patch added patch discarded remove patch
@@ -41,113 +41,113 @@
 block discarded – undo
41 41
 
42 42
 class UnifiedSearchController extends OCSController {
43 43
 
44
-	/** @var SearchComposer */
45
-	private $composer;
46
-
47
-	/** @var IUserSession */
48
-	private $userSession;
49
-
50
-	/** @var IRouter */
51
-	private $router;
52
-
53
-	public function __construct(IRequest $request,
54
-								IUserSession $userSession,
55
-								SearchComposer $composer,
56
-								IRouter $router) {
57
-		parent::__construct('core', $request);
58
-
59
-		$this->composer = $composer;
60
-		$this->userSession = $userSession;
61
-		$this->router = $router;
62
-	}
63
-
64
-	/**
65
-	 * @NoAdminRequired
66
-	 * @NoCSRFRequired
67
-	 *
68
-	 * @param string $from the url the user is currently at
69
-	 *
70
-	 * @return DataResponse
71
-	 */
72
-	public function getProviders(string $from = ''): DataResponse {
73
-		[$route, $parameters] = $this->getRouteInformation($from);
74
-
75
-		return new DataResponse(
76
-			$this->composer->getProviders($route, $parameters)
77
-		);
78
-	}
79
-
80
-	/**
81
-	 * @NoAdminRequired
82
-	 * @NoCSRFRequired
83
-	 *
84
-	 * @param string $providerId
85
-	 * @param string $term
86
-	 * @param int|null $sortOrder
87
-	 * @param int|null $limit
88
-	 * @param int|string|null $cursor
89
-	 * @param string $from
90
-	 *
91
-	 * @return DataResponse
92
-	 */
93
-	public function search(string $providerId,
94
-						   string $term = '',
95
-						   ?int $sortOrder = null,
96
-						   ?int $limit = null,
97
-						   $cursor = null,
98
-						   string $from = ''): DataResponse {
99
-		if (empty(trim($term))) {
100
-			return new DataResponse(null, Http::STATUS_BAD_REQUEST);
101
-		}
102
-		[$route, $routeParameters] = $this->getRouteInformation($from);
103
-
104
-		return new DataResponse(
105
-			$this->composer->search(
106
-				$this->userSession->getUser(),
107
-				$providerId,
108
-				new SearchQuery(
109
-					$term,
110
-					$sortOrder ?? ISearchQuery::SORT_DATE_DESC,
111
-					$limit ?? SearchQuery::LIMIT_DEFAULT,
112
-					$cursor,
113
-					$route,
114
-					$routeParameters
115
-				)
116
-			)
117
-		);
118
-	}
119
-
120
-	protected function getRouteInformation(string $url): array {
121
-		$routeStr = '';
122
-		$parameters = [];
123
-
124
-		if ($url !== '') {
125
-			$urlParts = parse_url($url);
126
-
127
-			try {
128
-				$parameters = $this->router->findMatchingRoute($urlParts['path']);
129
-
130
-				// contacts.PageController.index => contacts.Page.index
131
-				$route = $parameters['caller'];
132
-				if (substr($route[1], -10) === 'Controller') {
133
-					$route[1] = substr($route[1], 0, -10);
134
-				}
135
-				$routeStr = implode('.', $route);
136
-
137
-				// cleanup
138
-				unset($parameters['_route'], $parameters['action'], $parameters['caller']);
139
-			} catch (ResourceNotFoundException $exception) {
140
-			}
141
-
142
-			if (isset($urlParts['query'])) {
143
-				parse_str($urlParts['query'], $queryParameters);
144
-				$parameters = array_merge($parameters, $queryParameters);
145
-			}
146
-		}
147
-
148
-		return [
149
-			$routeStr,
150
-			$parameters,
151
-		];
152
-	}
44
+    /** @var SearchComposer */
45
+    private $composer;
46
+
47
+    /** @var IUserSession */
48
+    private $userSession;
49
+
50
+    /** @var IRouter */
51
+    private $router;
52
+
53
+    public function __construct(IRequest $request,
54
+                                IUserSession $userSession,
55
+                                SearchComposer $composer,
56
+                                IRouter $router) {
57
+        parent::__construct('core', $request);
58
+
59
+        $this->composer = $composer;
60
+        $this->userSession = $userSession;
61
+        $this->router = $router;
62
+    }
63
+
64
+    /**
65
+     * @NoAdminRequired
66
+     * @NoCSRFRequired
67
+     *
68
+     * @param string $from the url the user is currently at
69
+     *
70
+     * @return DataResponse
71
+     */
72
+    public function getProviders(string $from = ''): DataResponse {
73
+        [$route, $parameters] = $this->getRouteInformation($from);
74
+
75
+        return new DataResponse(
76
+            $this->composer->getProviders($route, $parameters)
77
+        );
78
+    }
79
+
80
+    /**
81
+     * @NoAdminRequired
82
+     * @NoCSRFRequired
83
+     *
84
+     * @param string $providerId
85
+     * @param string $term
86
+     * @param int|null $sortOrder
87
+     * @param int|null $limit
88
+     * @param int|string|null $cursor
89
+     * @param string $from
90
+     *
91
+     * @return DataResponse
92
+     */
93
+    public function search(string $providerId,
94
+                            string $term = '',
95
+                           ?int $sortOrder = null,
96
+                           ?int $limit = null,
97
+                            $cursor = null,
98
+                            string $from = ''): DataResponse {
99
+        if (empty(trim($term))) {
100
+            return new DataResponse(null, Http::STATUS_BAD_REQUEST);
101
+        }
102
+        [$route, $routeParameters] = $this->getRouteInformation($from);
103
+
104
+        return new DataResponse(
105
+            $this->composer->search(
106
+                $this->userSession->getUser(),
107
+                $providerId,
108
+                new SearchQuery(
109
+                    $term,
110
+                    $sortOrder ?? ISearchQuery::SORT_DATE_DESC,
111
+                    $limit ?? SearchQuery::LIMIT_DEFAULT,
112
+                    $cursor,
113
+                    $route,
114
+                    $routeParameters
115
+                )
116
+            )
117
+        );
118
+    }
119
+
120
+    protected function getRouteInformation(string $url): array {
121
+        $routeStr = '';
122
+        $parameters = [];
123
+
124
+        if ($url !== '') {
125
+            $urlParts = parse_url($url);
126
+
127
+            try {
128
+                $parameters = $this->router->findMatchingRoute($urlParts['path']);
129
+
130
+                // contacts.PageController.index => contacts.Page.index
131
+                $route = $parameters['caller'];
132
+                if (substr($route[1], -10) === 'Controller') {
133
+                    $route[1] = substr($route[1], 0, -10);
134
+                }
135
+                $routeStr = implode('.', $route);
136
+
137
+                // cleanup
138
+                unset($parameters['_route'], $parameters['action'], $parameters['caller']);
139
+            } catch (ResourceNotFoundException $exception) {
140
+            }
141
+
142
+            if (isset($urlParts['query'])) {
143
+                parse_str($urlParts['query'], $queryParameters);
144
+                $parameters = array_merge($parameters, $queryParameters);
145
+            }
146
+        }
147
+
148
+        return [
149
+            $routeStr,
150
+            $parameters,
151
+        ];
152
+    }
153 153
 }
Please login to merge, or discard this patch.