@@ -904,6 +904,116 @@ public static function unzip($zip_file, $extract_path = null) {
904904 } return false ;
905905 }
906906
907+ public static function format_phone ($ input ) {
908+ $ clean_input = substr (preg_replace ('/\D+/i ' , '' , $ input ), -10 );
909+ if (preg_match ('/^(\d{3})(\d{3})(\d{4})$/ ' , $ clean_input , $ matches )) {
910+ $ result = '+1 ( ' .$ matches [1 ].') ' .$ matches [2 ].'- ' .$ matches [3 ];
911+ return $ result ;
912+ }
913+
914+ return $ input ;
915+ }
916+
917+ /**
918+ * Obtain a brand constant from a PAN
919+ * https://stackoverflow.com/a/21617574/3685987
920+ *
921+ * @param type $pan Credit card number
922+ * @param type $include_sub_types Include detection of sub visa brands
923+ * @return string
924+ */
925+ public static function get_card_type ($ pan , $ include_sub_types = false ) {
926+ $ pan = preg_replace ('/\D/i ' , '' , $ pan );
927+ //maximum length is not fixed now, there are growing number of CCs has more numbers in length, limiting can give false negatives atm
928+
929+ //these regexps accept not whole cc numbers too
930+ //visa
931+ $ visa_regex = '/^4[0-9]{0,}$/ ' ;
932+ $ vpreca_regex = '/^428485[0-9]{0,}$/ ' ;
933+ $ postepay_regex = '/^(402360|402361|403035|417631|529948){0,}$/ ' ;
934+ $ cartasi_regex = '/^(432917|432930|453998)[0-9]{0,}$/ ' ;
935+ $ entropay_regex = '/^(406742|410162|431380|459061|533844|522093)[0-9]{0,}$/ ' ;
936+ $ o2money_regex = '/^(422793|475743)[0-9]{0,}$/ ' ;
937+
938+ // MasterCard
939+ $ mastercard_regex = '/^(5[1-5]|222[1-9]|22[3-9]|2[3-6]|27[01]|2720)[0-9]{0,}$/ ' ;
940+ $ maestro_regex = '/^(5[06789]|6)[0-9]{0,}$/ ' ;
941+ $ kukuruza_regex = '/^525477[0-9]{0,}$/ ' ;
942+ $ yunacard_regex = '/^541275[0-9]{0,}$/ ' ;
943+
944+ // American Express
945+ $ amex_regex = '/^3[47][0-9]{0,}$/ ' ;
946+
947+ // Diners Club
948+ $ diners_regex = '/^3(?:0[0-59]{1}|[689])[0-9]{0,}$/ ' ;
949+
950+ //Discover
951+ $ discover_regex = '/^(6011|65|64[4-9]|62212[6-9]|6221[3-9]|622[2-8]|6229[01]|62292[0-5])[0-9]{0,}$/ ' ;
952+
953+ //JCB
954+ $ jcb_regex = '/^(?:2131|1800|35)[0-9]{0,}$/ ' ;
955+
956+ //ordering matter in detection, otherwise can give false results in rare cases
957+ if (preg_match ($ jcb_regex , $ pan )) {
958+ return 'jcb ' ;
959+ }
960+
961+ if (preg_match ($ amex_regex , $ pan )) {
962+ return 'amex ' ;
963+ }
964+
965+ if (preg_match ($ diners_regex , $ pan )) {
966+ return 'diners_club ' ;
967+ }
968+
969+ //sub visa/mastercard cards
970+ if ($ include_sub_types ) {
971+ if (preg_match ($ vpreca_regex , $ pan )) {
972+ return 'v-preca ' ;
973+ }
974+ if (preg_match ($ postepay_regex , $ pan )) {
975+ return 'postepay ' ;
976+ }
977+ if (preg_match ($ cartasi_regex , $ pan )) {
978+ return 'cartasi ' ;
979+ }
980+ if (preg_match ($ entropay_regex , $ pan )) {
981+ return 'entropay ' ;
982+ }
983+ if (preg_match ($ o2money_regex , $ pan )) {
984+ return 'o2money ' ;
985+ }
986+ if (preg_match ($ kukuruza_regex , $ pan )) {
987+ return 'kukuruza ' ;
988+ }
989+ if (preg_match ($ yunacard_regex , $ pan )) {
990+ return 'yunacard ' ;
991+ }
992+ }
993+
994+ if (preg_match ($ visa_regex , $ pan )) {
995+ return 'visa ' ;
996+ }
997+
998+ if (preg_match ($ mastercard_regex , $ pan )) {
999+ return 'mastercard ' ;
1000+ }
1001+
1002+ if (preg_match ($ discover_regex , $ pan )) {
1003+ return 'discover ' ;
1004+ }
1005+
1006+ if (preg_match ($ maestro_regex , $ pan )) {
1007+ if ($ pan [0 ] == '5 ' ) {//started 5 must be mastercard
1008+ return 'mastercard ' ;
1009+ }
1010+ return 'maestro ' ; //maestro is all 60-69 which is not something else, thats why this condition in the end
1011+
1012+ }
1013+
1014+ return 'unknown ' ; //unknown for this system
1015+ }
1016+
9071017 /**
9081018 * Create a compressed zip file
9091019 * @param array $files files (filename => file_location)
0 commit comments