Jul 23

usbcard: pendrive en forma de targeta de crèdit

Reading time: 1 – 2 minutes

A finals de la setmana passada vaig dinar amb el Benja que em va regalar una targeta flash com les que veieu a la foto. En tenia dues una de 2Gb i una de 4Gb, després de preguntar-li d’on les havia tret em va regalar de 2Gb, així que ja tinc una targeta la mar de xula per posar a la cartera i poder-la treure en aquelles situacions on sempre resulta que no portes el pendrive. Si en voleu una les ha tret de Freecom.

usbcard1.png

Com es veu en la foto la mida és identica a la d’una targeta de crèdit, potser un pèl més gruixuda però molt i molt primeta també.

usbcard2.png
Jun 24

Validador de targetes de crèdit pel symfony

Reading time: 3 – 5 minutes

symfony.gifMalgrat 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