16
16
/**
17
17
* @see https://www.rfc-editor.org/rfc/rfc9651.html#section-3.3
18
18
*
19
+ * @phpstan-import-type SfType from StructuredField
19
20
* @phpstan-import-type SfItemInput from StructuredField
20
21
* @phpstan-import-type SfItemPair from StructuredField
21
22
* @phpstan-import-type SfTypeInput from StructuredField
@@ -243,9 +244,19 @@ public static function false(): self
243
244
244
245
/**
245
246
* Returns the underlying value.
247
+ * If a validation rule is provided, an exception will be thrown
248
+ * if the validtion rules does not return null.
249
+ *
250
+ * @param ?Closure(SfType): ?string $validate
251
+ *
252
+ * @throws ValidationError
246
253
*/
247
- public function value (): ByteSequence |Token |DisplayString |DateTimeImmutable |string |int |float |bool
254
+ public function value (? Closure $ validate = null ): ByteSequence |Token |DisplayString |DateTimeImmutable |string |int |float |bool
248
255
{
256
+ (null === $ validate )
257
+ || (null === ($ exceptionMessage = $ validate ($ this ->value ->value )))
258
+ || throw new ValidationError ($ exceptionMessage );
259
+
249
260
return $ this ->value ->value ;
250
261
}
251
262
@@ -259,25 +270,61 @@ public function parameters(): Parameters
259
270
return $ this ->parameters ;
260
271
}
261
272
262
- public function parameter (string $ key ): ByteSequence |Token |DisplayString |DateTimeImmutable |string |int |float |bool |null
263
- {
264
- try {
265
- return $ this ->parameters ->get ($ key )->value ();
266
- } catch (StructuredFieldError ) {
267
- return null ;
273
+ /**
274
+ * @param ?Closure(SfType): ?string $validate
275
+ * @param ?SfType $default
276
+ *
277
+ * @throws ValidationError
278
+ *
279
+ * @return SfType|null
280
+ */
281
+ public function parameter (
282
+ string $ key ,
283
+ ?Closure $ validate = null ,
284
+ bool $ required = false ,
285
+ ByteSequence |Token |DisplayString |DateTimeImmutable |string |int |float |bool |null $ default = null
286
+ ): ByteSequence |Token |DisplayString |DateTimeImmutable |string |int |float |bool |null {
287
+ if (!$ this ->parameters ->has ($ key )) {
288
+ !$ required || throw new ValidationError ("The parameter ' $ key' does not exist and is required. " );
289
+
290
+ return $ default ;
268
291
}
292
+
293
+ $ value = $ this ->parameters ->get ($ key )->value ();
294
+ if (null === $ validate ) {
295
+ return $ value ;
296
+ }
297
+
298
+ null === ($ exceptionMessage = $ validate ($ value )) || throw new ValidationError ($ exceptionMessage );
299
+
300
+ return $ value ;
269
301
}
270
302
271
303
/**
272
- * @return array{0:string, 1:Token|ByteSequence|DisplayString|DateTimeImmutable|int|float|string|bool}|array{}
304
+ * @param ?Closure(SfType, string): ?string $validate
305
+ *
306
+ * @throws ValidationError
307
+ *
308
+ * @return array{0:string, 1:SfType}|array{}
273
309
*/
274
- public function parameterByIndex (int $ index ): array
310
+ public function parameterByIndex (int $ index, ? Closure $ validate = null , bool $ required = false ): array
275
311
{
276
312
try {
277
313
$ tuple = $ this ->parameters ->pair ($ index );
314
+ if (null === $ validate ) {
315
+ return [$ tuple [0 ], $ tuple [1 ]->value ()];
316
+ }
317
+
318
+ null === ($ exceptionMessage = $ validate ($ tuple [1 ]->value (), $ tuple [0 ])) || throw new ValidationError ($ exceptionMessage );
278
319
279
320
return [$ tuple [0 ], $ tuple [1 ]->value ()];
280
- } catch (StructuredFieldError ) {
321
+ } catch (StructuredFieldError $ exception ) {
322
+ if ($ exception instanceof ValidationError) {
323
+ throw $ exception ;
324
+ }
325
+
326
+ !$ required || throw new ValidationError ("The parameter at position ' $ index' does not exist and is required. " );
327
+
281
328
return [];
282
329
}
283
330
}
0 commit comments