@@ -278,6 +278,9 @@ private function handleCast(Dot $dotArray, string $key, string $cast)
278278 } else if (str_starts_with ($ cast , 'setNullIfValue== ' ) === true ) {
279279 $ setNullIfValue = substr ($ cast , 16 );
280280 $ cast = 'setNullIfValue ' ;
281+ } else if (str_starts_with ($ cast , 'castStrToTypeIf== ' ) === true ) {
282+ $ castStrToTypeIf = substr ($ cast , 17 );
283+ $ cast = 'castStrToTypeIf ' ;
281284 } else if (str_starts_with ($ cast , 'countValue: ' ) === true ) {
282285 $ countValue = substr ($ cast , 11 );
283286 $ cast = 'countValue ' ;
@@ -385,12 +388,40 @@ private function handleCast(Dot $dotArray, string $key, string $cast)
385388 $ value = null ;
386389 }
387390 break ;
391+ case 'castStrToTypeIf ' :
392+ if (isset ($ castStrToTypeIf ) === true ) {
393+ // Parse the comma-separated type casting options
394+ $ castIfTypes = explode (", " , $ castStrToTypeIf );
395+ if (is_numeric ($ value ) === true ) {
396+ // First check if it's a BSN number
397+ if (in_array ('bsn ' , $ castIfTypes ) && $ this ->isValidBsn ((string )$ value )) {
398+ // Keep BSN as string to preserve leading zeros and format
399+ $ value = (string ) $ value ;
400+ break ;
401+ }
402+
403+ // If not a BSN, check if integer casting is requested
404+ if (in_array ('int ' , $ castIfTypes ) || in_array ('integer ' , $ castIfTypes )) {
405+ $ value = (int ) $ value ;
406+ break ;
407+ }
408+ }
409+
410+ // Handle boolean casting when value is already a boolean
411+ if ((in_array ('bool ' , $ castIfTypes ) || in_array ('boolean ' , $ castIfTypes )) && is_bool ($ value ) === true ) {
412+ // Explicitly cast to ensure it's a proper boolean type
413+ $ value = (bool ) $ value ;
414+ break ;
415+ }
416+ }
417+ break ;
388418 case 'countValue ' :
389419 if (isset ($ countValue ) === true
390420 && empty ($ countValue ) === false
391421 && $ dotArray ->has ($ countValue ) === true
392422 && is_countable ($ dotArray ->get ($ countValue )) === true
393423 ) {
424+ // Count the number of items in the specified array
394425 $ value = count ($ dotArray ->get ($ countValue ));
395426 }
396427 break ;
@@ -471,4 +502,33 @@ public function coordinateStringToArray(string $coordinates): array
471502 return $ coordinateArray ;
472503
473504 }//end coordinateStringToArray()
505+
506+ /**
507+ * Checks if a string is a valid BSN number using the "11-proof" check.
508+ *
509+ * @param string $bsn The BSN number to validate
510+ *
511+ * @return bool True if BSN is valid, false otherwise
512+ */
513+ private function isValidBsn (string $ bsn ): bool
514+ {
515+ // BSN must be 8 or 9 digits
516+ if (preg_match ('/^\d{8,9}$/ ' , $ bsn ) === false ) {
517+ return false ;
518+ }
519+
520+ // Pad 8-digit BSNs with leading zero to make it 9 digits
521+ $ bsn = str_pad ($ bsn , 9 , '0 ' , STR_PAD_LEFT );
522+
523+ // Calculate weighted sum according to 11-proof
524+ $ sum = 0 ;
525+ for ($ i = 0 ; $ i < 8 ; $ i ++) {
526+ $ sum += (int )$ bsn [$ i ] * (9 - $ i );
527+ }
528+ // Last digit has weight -1
529+ $ sum -= (int )$ bsn [8 ];
530+
531+ // Valid BSN if sum is divisible by 11
532+ return ($ sum % 11 ) === 0 ;
533+ }
474534}//end class
0 commit comments