Skip to content

Commit 19be393

Browse files
committed
added support for loose attribute validation
1 parent ba23bfe commit 19be393

2 files changed

Lines changed: 64 additions & 49 deletions

File tree

app/V1Module/presenters/base/BasePresenter.php

Lines changed: 62 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
use App\Helpers\MetaFormats\FormatCache;
2525
use App\Helpers\MetaFormats\MetaFormat;
2626
use App\Helpers\MetaFormats\MetaRequest;
27+
use App\Helpers\MetaFormats\RequestParamData;
2728
use App\Helpers\MetaFormats\RequestParamType;
2829
use App\Responses\StorageFileResponse;
2930
use App\Responses\ZipFilesResponse;
@@ -207,22 +208,59 @@ protected function isInScope(string $scope): bool
207208

208209
public function getMetaRequest(): MetaRequest|null
209210
{
211+
if ($this->requestFormatInstance === null) {
212+
throw new InternalServerException(
213+
"getMetaRequest() cannot be used without a format class defined for the endpoint."
214+
);
215+
}
216+
210217
$request = parent::getRequest();
211218
return new MetaRequest($request, $this->requestFormatInstance);
212219
}
213220

214221
private function processParams(ReflectionMethod $reflection)
215222
{
223+
$this->logger->log(var_export(MetaFormatHelper::debugGetAttributes($reflection), true), ILogger::DEBUG);
224+
225+
// use a method specialized for formats if there is a format available
216226
$format = MetaFormatHelper::extractFormatFromAttribute($reflection);
227+
if ($format !== null) {
228+
$this->processParamsFormat($format);
229+
return;
230+
}
217231

218-
$this->logger->log(var_export(MetaFormatHelper::debugGetAttributes($reflection), true), ILogger::DEBUG);
232+
// otherwise use a method for loose parameters
233+
$paramData = MetaFormatHelper::extractRequestParamData($reflection);
234+
$this->processParamsLoose($paramData);
235+
}
219236

237+
private function processParamsLoose(array $paramData)
238+
{
239+
// validate each param
240+
foreach ($paramData as $param) {
241+
$paramValue = $this->getValueFromParamData($param);
242+
243+
// check if null
244+
if ($paramValue === null) {
245+
if ($param->required) {
246+
throw new InvalidArgumentException($param->name, "The parameter is required and cannot be null.");
247+
}
248+
249+
// only non null values should be validated
250+
continue;
251+
}
220252

221-
// ignore request that do not yet have the attribute
222-
if ($format === null) {
223-
return;
253+
// use every provided validator
254+
foreach ($param->validators as $validator) {
255+
if (!$validator->validate($paramValue)) {
256+
throw new InvalidArgumentException($param->name);
257+
}
258+
}
224259
}
260+
}
225261

262+
private function processParamsFormat(string $format)
263+
{
226264
// get the parsed attribute data from the format fields
227265
$formatToFieldDefinitionsMap = FormatCache::getFormatToFieldDefinitionsMap();
228266
if (!array_key_exists($format, $formatToFieldDefinitionsMap)) {
@@ -236,19 +274,9 @@ private function processParams(ReflectionMethod $reflection)
236274
$formatInstance = MetaFormatHelper::createFormatInstance($format);
237275
foreach ($nameToFieldDefinitionsMap as $fieldName => $fieldData) {
238276
$requestParamData = $fieldData->requestData;
239-
$this->logger->log(var_export($requestParamData, true), ILogger::DEBUG);
240-
241-
$value = null;
242-
switch ($requestParamData->type) {
243-
case RequestParamType::Post:
244-
$value = $this->getPostField($fieldName, required: $requestParamData->required);
245-
break;
246-
case RequestParamType::Query:
247-
$value = $this->getQueryField($fieldName, required: $requestParamData->required);
248-
break;
249-
default:
250-
throw new InternalServerException("Unknown parameter type: {$requestParamData->type}");
251-
}
277+
//$this->logger->log(var_export($requestParamData, true), ILogger::DEBUG);
278+
279+
$value = $this->getValueFromParamData($requestParamData);
252280

253281
if (!$formatInstance->checkedAssign($fieldName, $value)) {
254282
///TODO: it would be nice to give a more detailed error message here
@@ -262,38 +290,24 @@ private function processParams(ReflectionMethod $reflection)
262290
}
263291

264292
$this->requestFormatInstance = $formatInstance;
293+
}
265294

266-
// $annotations = AnnotationsParser::getAll($reflection);
267-
// $requiredFields = Arrays::get($annotations, "Param", []);
268-
269-
// $this->logger->log(var_export($annotations, true), ILogger::DEBUG);
270-
// $this->logger->log(var_export($requiredFields, true), ILogger::DEBUG);
271-
272-
// foreach ($requiredFields as $field) {
273-
// $type = strtolower($field->type);
274-
// $name = $field->name;
275-
// $validationRule = isset($field->validation) ? $field->validation : null;
276-
// $msg = isset($field->msg) ? $field->msg : null;
277-
// $required = isset($field->required) ? $field->required : true;
278-
279-
// $this->logger->log("test", ILogger::DEBUG);
280-
281-
// $value = null;
282-
// switch ($type) {
283-
// case "post":
284-
// $value = $this->getPostField($name, $required);
285-
// break;
286-
// case "query":
287-
// $value = $this->getQueryField($name, $required);
288-
// break;
289-
// default:
290-
// throw new InternalServerException("Unknown parameter type '$type'");
291-
// }
292-
293-
// if ($validationRule !== null && $value !== null) {
294-
// $value = $this->validateValue($name, $value, $validationRule, $msg);
295-
// }
296-
// }
295+
/**
296+
* Calls either getPostField or getQueryField based on the provided metadata.
297+
* @param \App\Helpers\MetaFormats\RequestParamData $paramData Metadata of the request parameter.
298+
* @throws \App\Exceptions\InternalServerException Thrown when an unexpected parameter location was set.
299+
* @return mixed Returns the value from the request.
300+
*/
301+
private function getValueFromParamData(RequestParamData $paramData): mixed
302+
{
303+
switch ($paramData->type) {
304+
case RequestParamType::Post:
305+
return $this->getPostField($paramData->name, required: $paramData->required);
306+
case RequestParamType::Query:
307+
return $this->getQueryField($paramData->name, required: $paramData->required);
308+
default:
309+
throw new InternalServerException("Unknown parameter type: {$paramData->type->name}");
310+
}
297311
}
298312

299313
private function getPostField($param, $required = true)

app/helpers/MetaFormats/MetaFormatHelper.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,11 +120,12 @@ public static function extractRequestAttributeData(
120120
}
121121

122122
$requestArguments = $requestAttribute[0]->getArguments();
123+
$name = $reflectionObject->name;
123124
$type = $requestArguments["type"];
124125
$description = array_key_exists("description", $requestArguments) ? $requestArguments["description"] : "";
125126
$required = array_key_exists("required", $requestArguments) ? $requestArguments["required"] : true;
126127

127-
return new RequestParamData($type, "TODO_IMPLEMENT_FOR_FormatParameterAttribute", $description, $required);
128+
return new RequestParamData($type, $name, $description, $required);
128129
}
129130

130131
/**

0 commit comments

Comments
 (0)