@@ -8218,74 +8218,223 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface
8218
8218
use Psr \Http \Message \ResponseInterface ;
8219
8219
use Psr \Http \Message \ServerRequestInterface ;
8220
8220
use Psr \Http \Server \RequestHandlerInterface ;
8221
- use Tqdev \PhpCrudApi \Column \Reflection \ReflectedTable ;
8222
8221
use Tqdev \PhpCrudApi \Column \ReflectionService ;
8222
+ use Tqdev \PhpCrudApi \Column \Reflection \ReflectedTable ;
8223
8223
use Tqdev \PhpCrudApi \Controller \Responder ;
8224
8224
use Tqdev \PhpCrudApi \Middleware \Base \Middleware ;
8225
8225
use Tqdev \PhpCrudApi \Middleware \Router \Router ;
8226
8226
use Tqdev \PhpCrudApi \Record \ErrorCode ;
8227
8227
use Tqdev \PhpCrudApi \RequestUtils ;
8228
8228
8229
- class ValidationMiddleware extends Middleware
8230
- {
8231
- private $ reflection ;
8232
-
8233
- public function __construct (Router $ router , Responder $ responder , array $ properties , ReflectionService $ reflection )
8234
- {
8235
- parent ::__construct ($ router , $ responder , $ properties );
8236
- $ this ->reflection = $ reflection ;
8237
- }
8238
-
8239
- private function callHandler ($ handler , $ record , string $ operation , ReflectedTable $ table ) /*: ResponseInterface?*/
8240
- {
8241
- $ context = (array ) $ record ;
8242
- $ details = array ();
8243
- $ tableName = $ table ->getName ();
8244
- foreach ($ context as $ columnName => $ value ) {
8245
- if ($ table ->hasColumn ($ columnName )) {
8246
- $ column = $ table ->getColumn ($ columnName );
8247
- $ valid = call_user_func ($ handler , $ operation , $ tableName , $ column ->serialize (), $ value , $ context );
8248
- if ($ valid !== true && $ valid !== '' ) {
8249
- $ details [$ columnName ] = $ valid ;
8250
- }
8251
- }
8252
- }
8253
- if (count ($ details ) > 0 ) {
8254
- return $ this ->responder ->error (ErrorCode::INPUT_VALIDATION_FAILED , $ tableName , $ details );
8255
- }
8256
- return null ;
8257
- }
8258
-
8259
- public function process (ServerRequestInterface $ request , RequestHandlerInterface $ next ): ResponseInterface
8260
- {
8261
- $ operation = RequestUtils::getOperation ($ request );
8262
- if (in_array ($ operation , ['create ' , 'update ' , 'increment ' ])) {
8263
- $ tableName = RequestUtils::getPathSegment ($ request , 2 );
8264
- if ($ this ->reflection ->hasTable ($ tableName )) {
8265
- $ record = $ request ->getParsedBody ();
8266
- if ($ record !== null ) {
8267
- $ handler = $ this ->getProperty ('handler ' , '' );
8268
- if ($ handler !== '' ) {
8269
- $ table = $ this ->reflection ->getTable ($ tableName );
8270
- if (is_array ($ record )) {
8271
- foreach ($ record as $ r ) {
8272
- $ response = $ this ->callHandler ($ handler , $ r , $ operation , $ table );
8273
- if ($ response !== null ) {
8274
- return $ response ;
8275
- }
8276
- }
8277
- } else {
8278
- $ response = $ this ->callHandler ($ handler , $ record , $ operation , $ table );
8279
- if ($ response !== null ) {
8280
- return $ response ;
8281
- }
8282
- }
8283
- }
8284
- }
8285
- }
8286
- }
8287
- return $ next ->handle ($ request );
8288
- }
8229
+ class ValidationMiddleware extends Middleware {
8230
+ private $ reflection ;
8231
+ private $ typesToValidate ;
8232
+
8233
+ public function __construct (Router $ router , Responder $ responder , array $ properties , ReflectionService $ reflection ) {
8234
+ parent ::__construct ($ router , $ responder , $ properties );
8235
+ $ this ->reflection = $ reflection ;
8236
+ $ typesStr = $ this ->getProperty ('types ' , 'all ' );
8237
+ if (is_null ($ typesStr )) {
8238
+ $ typesStr = 'all ' ;
8239
+ }
8240
+ if (strlen ($ typesStr ) == 0 ) {
8241
+ $ typesStr = 'none ' ;
8242
+ }
8243
+ $ this ->typesToValidate = explode (', ' , $ typesStr );
8244
+ if (is_null ($ this ->typesToValidate ) || count ($ this ->typesToValidate ) == 0 ) {
8245
+ $ this ->typesToValidate = ['all ' ];
8246
+ }
8247
+ }
8248
+
8249
+ private function callHandler ($ handler , $ record , string $ operation , ReflectedTable $ table ) /*: ResponseInterface?*/ {
8250
+ $ context = (array ) $ record ;
8251
+ $ details = array ();
8252
+ $ tableName = $ table ->getName ();
8253
+ foreach ($ context as $ columnName => $ value ) {
8254
+ if ($ table ->hasColumn ($ columnName )) {
8255
+ $ column = $ table ->getColumn ($ columnName );
8256
+ $ valid = call_user_func ($ handler , $ operation , $ tableName , $ column ->serialize (), $ value , $ context );
8257
+ if ($ valid || $ valid == '' ) {
8258
+ $ valid = $ this ->validateType ($ column ->serialize (), $ value );
8259
+ }
8260
+ if ($ valid !== true && $ valid !== '' ) {
8261
+ $ details [$ columnName ] = $ valid ;
8262
+ }
8263
+ }
8264
+ }
8265
+ if (count ($ details ) > 0 ) {
8266
+ return $ this ->responder ->error (ErrorCode::INPUT_VALIDATION_FAILED , $ tableName , $ details );
8267
+ }
8268
+ return null ;
8269
+ }
8270
+
8271
+ private function validateType ($ column , $ value ) {
8272
+ if ($ this ->typesToValidate [0 ] == 'none ' ) {
8273
+ return (true );
8274
+ }
8275
+ if ($ this ->typesToValidate [0 ] != 'all ' ) {
8276
+ if (!in_array ($ column ['type ' ], $ this ->typesToValidate )) {
8277
+ return (true );
8278
+ }
8279
+ }
8280
+ if (is_null ($ value )) {
8281
+ return ($ column ["nullable " ] ? true : "cannot be null " );
8282
+ }
8283
+ switch ($ column ['type ' ]) {
8284
+ case 'integer ' :
8285
+ if (!is_numeric ($ value )) {
8286
+ return ('must be numeric ' );
8287
+ }
8288
+
8289
+ if (strlen ($ value ) > 20 ) {
8290
+ return ('exceeds range ' );
8291
+ }
8292
+
8293
+ break ;
8294
+ case 'bigint ' :
8295
+ if (!is_numeric ($ value )) {
8296
+ return ('must be numeric ' );
8297
+ }
8298
+
8299
+ if (strlen ($ value ) > 20 ) {
8300
+ return ('exceeds range ' );
8301
+ }
8302
+
8303
+ break ;
8304
+ case 'varchar ' :
8305
+ if (strlen ($ value ) > $ column ['length ' ]) {
8306
+ return ('too long ' );
8307
+ }
8308
+
8309
+ break ;
8310
+ case 'decimal ' :
8311
+ if (!is_float ($ value ) && !is_numeric ($ value )) {
8312
+ return ('not a float ' );
8313
+ }
8314
+
8315
+ break ;
8316
+ case 'float ' :
8317
+ if (!is_float ($ value ) && !is_numeric ($ value )) {
8318
+ return ('not a float ' );
8319
+ }
8320
+
8321
+ break ;
8322
+ case 'double ' :
8323
+ if (!is_float ($ value ) && !is_numeric ($ value )) {
8324
+ return ('not a float ' );
8325
+ }
8326
+
8327
+ break ;
8328
+ case 'boolean ' :
8329
+ if ($ value != 0 && $ value != 1 ) {
8330
+ return ('not a valid boolean ' );
8331
+ }
8332
+
8333
+ break ;
8334
+ case 'date ' :
8335
+ $ date_array = explode ('- ' , $ value );
8336
+ if (count ($ date_array ) != 3 ) {
8337
+ return ('invalid date format use yyyy-mm-dd ' );
8338
+ }
8339
+
8340
+ if (!@checkdate ($ date_array [1 ], $ date_array [2 ], $ date_array [0 ])) {
8341
+ return ('not a valid date ' );
8342
+ }
8343
+
8344
+ break ;
8345
+ case 'time ' :
8346
+ $ time_array = explode (': ' , $ value );
8347
+ if (count ($ time_array ) != 3 ) {
8348
+ return ('invalid time format use hh:mm:ss ' );
8349
+ }
8350
+
8351
+ foreach ($ time_array as $ t ) {
8352
+ if (!is_numeric ($ t )) {
8353
+ return ('non-numeric time value ' );
8354
+ }
8355
+ }
8356
+
8357
+ if ($ time_array [1 ] < 0 || $ time_array [2 ] < 0 || $ time_array [0 ] < -838 || $ time_array [1 ] > 59 || $ time_array [2 ] > 59 || $ time_array [0 ] > 838 ) {
8358
+ return ('not a valid time ' );
8359
+ }
8360
+
8361
+ break ;
8362
+ case 'timestamp ' :
8363
+ $ split_timestamp = explode (' ' , $ value );
8364
+ if (count ($ split_timestamp ) != 2 ) {
8365
+ return ('invalid timestamp format use yyyy-mm-dd hh:mm:ss ' );
8366
+ }
8367
+
8368
+ $ date_array = explode ('- ' , $ split_timestamp [0 ]);
8369
+ if (count ($ date_array ) != 3 ) {
8370
+ return ('invalid date format use yyyy-mm-dd ' );
8371
+ }
8372
+
8373
+ if (!@checkdate ($ date_array [1 ], $ date_array [2 ], $ date_array [0 ])) {
8374
+ return ('not a valid date ' );
8375
+ }
8376
+
8377
+ $ time_array = explode (': ' , $ split_timestamp [1 ]);
8378
+ if (count ($ time_array ) != 3 ) {
8379
+ return ('invalid time format use hh:mm:ss ' );
8380
+ }
8381
+
8382
+ foreach ($ time_array as $ t ) {
8383
+ if (!is_numeric ($ t )) {
8384
+ return ('non-numeric time value ' );
8385
+ }
8386
+ }
8387
+
8388
+ if ($ time_array [1 ] < 0 || $ time_array [2 ] < 0 || $ time_array [0 ] < 0 || $ time_array [1 ] > 59 || $ time_array [2 ] > 59 || $ time_array [0 ] > 23 ) {
8389
+ return ('not a valid time ' );
8390
+ }
8391
+
8392
+ break ;
8393
+ case 'clob ' :
8394
+ break ;
8395
+ case 'blob ' :
8396
+ break ;
8397
+ case 'varbinary ' :
8398
+ if (((strlen ($ value ) * 3 / 4 ) - substr_count (substr ($ value , -2 ), '= ' )) > $ column ['length ' ]) {
8399
+ return ('too long ' );
8400
+ }
8401
+
8402
+ break ;
8403
+ case 'geometry ' :
8404
+ break ;
8405
+ }
8406
+ return (true );
8407
+ }
8408
+
8409
+ public function process (ServerRequestInterface $ request , RequestHandlerInterface $ next ): ResponseInterface {
8410
+ $ operation = RequestUtils::getOperation ($ request );
8411
+ if (in_array ($ operation , ['create ' , 'update ' , 'increment ' ])) {
8412
+ $ tableName = RequestUtils::getPathSegment ($ request , 2 );
8413
+ if ($ this ->reflection ->hasTable ($ tableName )) {
8414
+ $ record = $ request ->getParsedBody ();
8415
+ if ($ record !== null ) {
8416
+ $ handler = $ this ->getProperty ('handler ' , '' );
8417
+ if ($ handler !== '' ) {
8418
+ $ table = $ this ->reflection ->getTable ($ tableName );
8419
+ if (is_array ($ record )) {
8420
+ foreach ($ record as $ r ) {
8421
+ $ response = $ this ->callHandler ($ handler , $ r , $ operation , $ table );
8422
+ if ($ response !== null ) {
8423
+ return $ response ;
8424
+ }
8425
+ }
8426
+ } else {
8427
+ $ response = $ this ->callHandler ($ handler , $ record , $ operation , $ table );
8428
+ if ($ response !== null ) {
8429
+ return $ response ;
8430
+ }
8431
+ }
8432
+ }
8433
+ }
8434
+ }
8435
+ }
8436
+ return $ next ->handle ($ request );
8437
+ }
8289
8438
}
8290
8439
}
8291
8440
0 commit comments