4 * Defines how to read a complex value from an HTTP request.
6 * Most HTTP parameters are simple (like strings or integers) but some
7 * parameters accept more complex values (like lists of users or project names).
9 * This class handles reading simple and complex values from a request,
10 * performing any required parsing or lookups, and returning a result in a
13 * @task read Reading Values from a Request
14 * @task info Information About the Type
15 * @task util Parsing Utilities
16 * @task impl Implementation
18 abstract class AphrontHTTPParameterType
extends Phobject
{
24 /* -( Reading Values from a Request )-------------------------------------- */
28 * Set the current viewer.
30 * Some parameter types perform complex parsing involving lookups. For
31 * example, a type might lookup usernames or project names. These types need
32 * to use the current viewer to execute queries.
34 * @param PhabricatorUser Current viewer.
38 final public function setViewer(PhabricatorUser
$viewer) {
39 $this->viewer
= $viewer;
45 * Get the current viewer.
47 * @return PhabricatorUser Current viewer.
50 final public function getViewer() {
52 throw new PhutilInvalidStateException('setViewer');
59 * Test if a value is present in a request.
61 * @param AphrontRequest The incoming request.
62 * @param string The key to examine.
63 * @return bool True if a readable value is present in the request.
66 final public function getExists(AphrontRequest
$request, $key) {
67 return $this->getParameterExists($request, $key);
72 * Read a value from a request.
74 * If the value is not present, a default value is returned (usually `null`).
75 * Use @{method:getExists} to test if a value is present.
77 * @param AphrontRequest The incoming request.
78 * @param string The key to examine.
79 * @return wild Value, or default if value is not present.
82 final public function getValue(AphrontRequest
$request, $key) {
84 if (!$this->getExists($request, $key)) {
85 return $this->getParameterDefault();
88 return $this->getParameterValue($request, $key);
93 * Get the default value for this parameter type.
95 * @return wild Default value for this type.
98 final public function getDefaultValue() {
99 return $this->getParameterDefault();
103 /* -( Information About the Type )----------------------------------------- */
107 * Get a short name for this type, like `string` or `list<phid>`.
109 * @return string Short type name.
112 final public function getTypeName() {
113 return $this->getParameterTypeName();
118 * Get a list of human-readable descriptions of acceptable formats for this
121 * For example, a type might return strings like these:
123 * > Any positive integer.
124 * > A comma-separated list of PHIDs.
126 * This is used to explain to users how to specify a type when generating
129 * @return list<string> Human-readable list of acceptable formats.
132 final public function getFormatDescriptions() {
133 return $this->getParameterFormatDescriptions();
138 * Get a list of human-readable examples of how to format this type as an
139 * HTTP GET parameter.
141 * For example, a type might return strings like these:
146 * This is used to show users how to specify parameters of this type in
147 * generated documentation.
149 * @return list<string> Human-readable list of format examples.
152 final public function getExamples() {
153 return $this->getParameterExamples();
157 /* -( Utilities )---------------------------------------------------------- */
161 * Call another type's existence check.
163 * This method allows a type to reuse the existence behavior of a different
164 * type. For example, a "list of users" type may have the same basic
165 * existence check that a simpler "list of strings" type has, and can just
166 * call the simpler type to reuse its behavior.
168 * @param AphrontHTTPParameterType The other type.
169 * @param AphrontRequest Incoming request.
170 * @param string Key to examine.
171 * @return bool True if the parameter exists.
174 final protected function getExistsWithType(
175 AphrontHTTPParameterType
$type,
176 AphrontRequest
$request,
179 $type->setViewer($this->getViewer());
181 return $type->getParameterExists($request, $key);
186 * Call another type's value parser.
188 * This method allows a type to reuse the parsing behavior of a different
189 * type. For example, a "list of users" type may start by running the same
190 * basic parsing that a simpler "list of strings" type does.
192 * @param AphrontHTTPParameterType The other type.
193 * @param AphrontRequest Incoming request.
194 * @param string Key to examine.
195 * @return wild Parsed value.
198 final protected function getValueWithType(
199 AphrontHTTPParameterType
$type,
200 AphrontRequest
$request,
203 $type->setViewer($this->getViewer());
205 return $type->getValue($request, $key);
210 * Get a list of all available parameter types.
212 * @return list<AphrontHTTPParameterType> List of all available types.
215 final public static function getAllTypes() {
216 return id(new PhutilClassMapQuery())
217 ->setAncestorClass(__CLASS__
)
218 ->setUniqueMethod('getTypeName')
219 ->setSortMethod('getTypeName')
224 /* -( Implementation )----------------------------------------------------- */
228 * Test if a parameter exists in a request.
230 * See @{method:getExists}. By default, this method tests if the key is
231 * present in the request.
233 * To call another type's behavior in order to perform this check, use
234 * @{method:getExistsWithType}.
236 * @param AphrontRequest The incoming request.
237 * @param string The key to examine.
238 * @return bool True if a readable value is present in the request.
241 protected function getParameterExists(AphrontRequest
$request, $key) {
242 return $request->getExists($key);
247 * Parse a value from a request.
249 * See @{method:getValue}. This method will //only// be called if this type
250 * has already asserted that the value exists with
251 * @{method:getParameterExists}.
253 * To call another type's behavior in order to parse a value, use
254 * @{method:getValueWithType}.
256 * @param AphrontRequest The incoming request.
257 * @param string The key to examine.
258 * @return wild Parsed value.
261 abstract protected function getParameterValue(AphrontRequest
$request, $key);
265 * Return a simple type name string, like "string" or "list<phid>".
267 * See @{method:getTypeName}.
269 * @return string Short type name.
272 abstract protected function getParameterTypeName();
276 * Return a human-readable list of format descriptions.
278 * See @{method:getFormatDescriptions}.
280 * @return list<string> Human-readable list of acceptable formats.
283 abstract protected function getParameterFormatDescriptions();
287 * Return a human-readable list of examples.
289 * See @{method:getExamples}.
291 * @return list<string> Human-readable list of format examples.
294 abstract protected function getParameterExamples();
298 * Return the default value for this parameter type.
300 * See @{method:getDefaultValue}. If unspecified, the default is `null`.
302 * @return wild Default value.
305 protected function getParameterDefault() {