Reading time: 3 – 5 minutes
Malgrat els molts validadors de camps de formularis que inclou el famework symfony no n’inclou un de força important. El validador dels codis de les targetes de crèdit. Com segur que sabeu, els codi d’una targeta de crèdit és autoverificable. És a dir compleix un algoritme matemàtic entre els seus grups de 4 números. Doncs bé com que no tenia cap ganes d’implementar el que ja esta implementat moltes vegades, vaig trobar que a phpclasses.org un tal Harish Chauhan havia penjat una classe programada en PHP4 que implementava un validador de força tipus de targetes de crèdit (VISA, MASTERCARD, DISCOVER, AMEX, DINERS, JCB, Australian Bankcard, EnRoute i Switch Solo). Així doncs, vaig decidir integrar aquesta classe amb el sistema de validador de camps de formularis del symfony.
El primer que vaig fer va ser declarar els mètodes orginals com a privats i després extendre la classe sfValidator que és la usada pels validadors de symfony. Creant un parell de mètodes públics estàndards pels validadors, bàsicament serveixen per instanciar el mètode del validador real i per capturar els paràmetres rebuts des del fitxer yml corresponent.
Doncs bé si voleu consultar el codi de la classe i un exemple d’ús a part de poder-ho consultar en la part extesa d’aques article podeu mirar als snippets de symfony, concretament a Credit Card validator.
Codi del validador:
getParameterHolder()->get('num'); $num = $this->getContext()->getRequest()->getParameter($num_param); $tipo_param = $this->getParameterHolder()->get('tipo'); $tipo = $this->getContext()->getRequest()->getParameter($tipo_param); // Lanzamos la validación $validada=$this->_isVAlidCreditCard($num,$tipo,false); // Informamos de como ha ido la validación sfContext::getInstance()->getLogger()->info("CCVAL.class.php: Tipo: ".$tipo." Num: ".$num." Validada: ".$validada); if ($validada==false) { $error = $this->getParameterHolder()->get('error'); return false; } return true; } public function initialize ($context, $parameters = null) { // initialize parent parent::initialize($context); $this->getParameterHolder()->add($parameters); return true; } /** * Testing checksum * * @param integer $ccnum * @return boolean */ private function _checkSum($ccnum) { $checksum = 0; for ($i=(2-(strlen($ccnum) % 2)); $i<=strlen($ccnum); $i+=2) { $checksum += (int)($ccnum{$i-1}); } // Analyze odd digits in even length strings or even digits in odd length strings. for ($i=(strlen($ccnum)% 2) + 1; $i< 10) { $checksum += $digit; } else { $checksum += ($digit-9); } } if (($checksum % 10) == 0) return true; else return false; } /** * Launch validation * * @param integer $ccnum * @param string $type * @param boolean $returnobj * @return boolean */ private function _isVAlidCreditCard($ccnum,$type="",$returnobj=false) { $creditcard=array( "visa"=>"/^4d{3}-?d{4}-?d{4}-?d{4}$/", "mastercard"=>"/^5[1-5]d{2}-?d{4}-?d{4}-?d{4}$/", "discover"=>"/^6011-?d{4}-?d{4}-?d{4}$/", "amex"=>"/^3[4,7]d{13}$/", "diners"=>"/^3[0,6,8]d{12}$/", "bankcard"=>"/^5610-?d{4}-?d{4}-?d{4}$/", "jcb"=>"/^[3088|3096|3112|3158|3337|3528]d{12}$/", "enroute"=>"/^[2014|2149]d{11}$/", "switch"=>"/^[4903|4911|4936|5641|6333|6759|6334|6767]d{12}$/"); if(empty($type)) { $match=false; foreach($creditcard as $type=>$pattern) if(preg_match($pattern,$ccnum)==1) { $match=true; break; } if(!$match) return false; else { if($returnobj) { $return=new stdclass; $return->valid=$this->_checkSum($ccnum); $return->ccnum=$ccnum; $return->type=$type; return $return; } else return $this->_checkSum($ccnum); } } else { if(@preg_match($creditcard[strtolower(trim($type))],$ccnum)==0) return false; else { if($returnobj) { $return=new stdclass; $return->valid=$this->_checkSum($ccnum); $return->ccnum=$ccnum; $return->type=$type; return $return; } else return $this->_checkSum($ccnum); } } } } ?>
Un exemple de com es crida el validador des dels fitxers yml de configuració al directori validate:
methods: post: [ntarjeta] names: ntarjeta: required: Yes required_msg: Credit Card number is required validators: validarCC validarCC: class: CCVAL param: num: ntarjeta tipo: tipoCC error: Your credit card number is invalid