@@ -8218,74 +8218,223 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface
82188218 use Psr \Http \Message \ResponseInterface ;
82198219 use Psr \Http \Message \ServerRequestInterface ;
82208220 use Psr \Http \Server \RequestHandlerInterface ;
8221- use Tqdev \PhpCrudApi \Column \Reflection \ReflectedTable ;
82228221 use Tqdev \PhpCrudApi \Column \ReflectionService ;
8222+ use Tqdev \PhpCrudApi \Column \Reflection \ReflectedTable ;
82238223 use Tqdev \PhpCrudApi \Controller \Responder ;
82248224 use Tqdev \PhpCrudApi \Middleware \Base \Middleware ;
82258225 use Tqdev \PhpCrudApi \Middleware \Router \Router ;
82268226 use Tqdev \PhpCrudApi \Record \ErrorCode ;
82278227 use Tqdev \PhpCrudApi \RequestUtils ;
82288228
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+ }
82898438 }
82908439}
82918440
0 commit comments