@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Allow typeaheads to pass nonscalar data to datasources

Summary:
Ref T13250. Currently, datasources have a `setParameters(...)` method. This method accepts a dictionary and adds the key/value pairs to the raw HTTP request to the datasource endpoint.

Since D20049, this no longer works. Since D20116, it fatals explicitly.

In general, the datasource endpoint accepts other values (like `query`, `offset`, and `limit`), and even before these changes, using secret reserved keys in `setParameters(...)` would silently cause program misbehavior.

To deal with this, pass parameters as a JSON string named "parameters". This fixes the HTTP query issue (the more pressing issue affecting users today) and prevents the "shadowing reserved keys" issue (a theoretical issue which might affect users some day).

(I may revisit the `phutil_build_http_querystring()` behavior and possibly let it make this work again, but I think avoiding the duplicate key issue makes this change desirable even if the querystring behavior changes.)

Test Plan:
- Used "Land Revision", selected branches.
- Configured a custom Maniphest "users" field, used the search typeahead, selected users.
- Manually browsed to `/typeahead/class/PhabricatorPeopleDatasource/?query=hi&parameters=xyz` to see the JSON decode exception.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13250

Differential Revision: https://secure.phabricator.com/D20134

+34 -3
+20 -1
src/applications/typeahead/controller/PhabricatorTypeaheadModularDatasourceController.php
··· 35 35 36 36 if (isset($sources[$class])) { 37 37 $source = $sources[$class]; 38 - $source->setParameters($request->getRequestData()); 38 + 39 + $parameters = array(); 40 + 41 + $raw_parameters = $request->getStr('parameters'); 42 + if (strlen($raw_parameters)) { 43 + try { 44 + $parameters = phutil_json_decode($raw_parameters); 45 + } catch (PhutilJSONParserException $ex) { 46 + return $this->newDialog() 47 + ->setTitle(pht('Invalid Parameters')) 48 + ->appendParagraph( 49 + pht( 50 + 'The HTTP parameter named "parameters" for this request is '. 51 + 'not a valid JSON parameter. JSON is required. Exception: %s', 52 + $ex->getMessage())) 53 + ->addCancelButton('/'); 54 + } 55 + } 56 + 57 + $source->setParameters($parameters); 39 58 $source->setViewer($viewer); 40 59 41 60 // NOTE: Wrapping the source in a Composite datasource ensures we perform
+14 -2
src/applications/typeahead/datasource/PhabricatorTypeaheadDatasource.php
··· 100 100 101 101 public function getDatasourceURI() { 102 102 $uri = new PhutilURI('/typeahead/class/'.get_class($this).'/'); 103 - $uri->setQueryParams($this->parameters); 103 + $uri->setQueryParams($this->newURIParameters()); 104 104 return (string)$uri; 105 105 } 106 106 ··· 110 110 } 111 111 112 112 $uri = new PhutilURI('/typeahead/browse/'.get_class($this).'/'); 113 - $uri->setQueryParams($this->parameters); 113 + $uri->setQueryParams($this->newURIParameters()); 114 114 return (string)$uri; 115 + } 116 + 117 + private function newURIParameters() { 118 + if (!$this->parameters) { 119 + return array(); 120 + } 121 + 122 + $map = array( 123 + 'parameters' => phutil_json_encode($this->parameters), 124 + ); 125 + 126 + return $map; 115 127 } 116 128 117 129 abstract public function getPlaceholderText();