Code snippets for symfony 1.x

Navigation

Refine Tags

Snippets tagged "validator cc"

Credit Card Validator II

Here is another variation on the credit card validator. In your validate/[action].yml file, you can implement this helper like so:

fields:
  cc_type:
    required:
      msg:      Please select a card type
    sfStringValidator:
      values:       [Visa, MasterCard, Discover, American Express]
      values_error: Please select a credit card type
      insensitive:  true
 
  cc_number:
    required:
      msg:      Please provide a credit card number
    myCreditCardValidator:
      card_name: cc_type    # refers to field name in form that contains card type, like Visa, MasteCard, etc.

Place this file, myCreditCardValidator.class.php, in you application's /lib directory and clear the cache.

<?php
 
/**
 * This class has been converted to a Symfony Validator from original code
 * created by John Gardner, 4th January 2005. 
 * http://www.braemoor.co.uk/software/index.shtml
 *
 * Symfony conversion by Scott Meves, Stereo Interactive & Design, 2007
 * http://www.stereointeractive.com
 * 
 * This routine checks the credit card number. The following checks are made:
 * 
 * 1. A number has been provided
 * 2. The number is a right length for the card
 * 3. The number has an appropriate prefix for the card
 * 4. The number has a valid modulus 10 number check digit if required
 * 
 **/
 
class myCreditCardValidator extends sfValidator
{    
 
    static protected $CARDS = array (
        array ('name'           => 'American Express', 
            'length'            => '15', 
            'prefixes'      => '34,37',
            'checkdigit'    => true
    ),
        array ('name'           => 'Carte Blanche', 
               'length'         => '14', 
               'prefixes'   => '300,301,302,303,304,305,36,38',
               'checkdigit' => true
        ),
        array ('name'       => 'Diners Club', 
               'length'         => '14',
               'prefixes'   => '300,301,302,303,304,305,36,38',
               'checkdigit' => true
    ),
        array ('name'       => 'Discover', 
               'length'         => '16', 
               'prefixes'   => '6011',
               'checkdigit' => true
    ),
        array ('name'       => 'Enroute', 
               'length'         => '15', 
               'prefixes'   => '2014,2149',
               'checkdigit' => true
    ),
        array ('name'       => 'JCB', 
               'length'         => '15,16', 
               'prefixes'   => '3,1800,2131',
               'checkdigit' => true
    ),
        array ('name'       => 'Maestro', 
               'length'         => '16', 
               'prefixes'   => '5020,6',
               'checkdigit' => true
    ),
        array ('name'       => 'MasterCard', 
               'length'         => '16', 
               'prefixes'   => '51,52,53,54,55',
               'checkdigit' => true
    ),
        array ('name'       => 'Solo', 
               'length'         => '16,18,19', 
               'prefixes'   => '6334, 6767',
               'checkdigit' => true
    ),
        array ('name'       => 'Switch', 
               'length'         => '16,18,19', 
               'prefixes'   => '4903,4905,4911,4936,564182,633110,6333,6759',
               'checkdigit' => true
    ),
        array ('name'       => 'Visa', 
               'length'         => '13,16', 
               'prefixes'   => '4',
               'checkdigit' => true
    ),
        array ('name'       => 'Visa Electron', 
               'length'         => '16', 
               'prefixes'   => '417500,4917,4913',
               'checkdigit' => true
        )
  );
 
  public function initialize($context, $parameters = null)
  {
    // initialize parent
    parent::initialize($context);
 
    // set defaults
    $parameterHolder = $this->getParameterHolder();
    $parameterHolder->set('cc_error_type',      'Unknown card type');
    $parameterHolder->set('cc_error_missing', 'No card number provided');
    $parameterHolder->set('cc_error_format',    'Credit card number has invalid format');
    $parameterHolder->set('cc_error_number',    'Credit card number is invalid');
    $parameterHolder->set('cc_error_length',    'Credit card number is wrong length');
 
    $this->getParameterHolder()->add($parameters);
 
    return true;
  }
 
  public function execute(&$value, &$error)
  {
    $cardName = $this->getParameterHolder()->get('card_name');
    $cardName = $this->getContext()->getRequest()->getParameter($cardName);
 
    $cardNumber = $value;
 
      // Establish card type
      $cardType = -1;
      for ($i=0; $i<sizeof(self::$CARDS); $i++) 
        {   // See if it is this card (ignoring the case of the string)
        if (strtolower($cardName) == strtolower(self::$CARDS[$i]['name']))
            {
          $cardType = $i;
          break;
        }
      }
 
      // If card type not found, report an error
      if ($cardType == -1) 
        {
            $error = $this->getParameterHolder()->get('cc_error_type');
        return false; 
      }
 
      // Ensure that the user has provided a credit card number
      if (strlen($cardNumber) == 0)
        {
         $error = $this->getParameterHolder()->get('cc_error_missing');
         return false; 
      }
 
      // Remove any non-digits   from the credit card number
      $cardNo = preg_replace('/[^0-9]/', '', $cardNumber);
 
      // Check that the number is numeric and of the right sort of length.
      if (!eregi('^[0-9]{13,19}$',$cardNo))
        {
         $error = $this->getParameterHolder()->get('cc_error_format');
         return false; 
      }
 
      // Now check the modulus 10 check digit - if required
      if (self::$CARDS[$cardType]['checkdigit'])
        {
        $checksum = 0;   // running checksum total
        $mychar = "";    // next char to process
        $j = 1;          // takes value of 1 or 2
 
        // Process each digit one by one starting at the right
        for ($i = strlen($cardNo) - 1; $i >= 0; $i--) 
            {
          // Extract the next digit and multiply by 1 or 2 on alternative digits.      
          $calc = $cardNo{$i} * $j;
 
          // If the result is in two digits add 1 to the checksum total
          if ($calc > 9) {
            $checksum = $checksum + 1;
            $calc = $calc - 10;
          }
 
          // Add the units element to the checksum total
          $checksum = $checksum + $calc;
 
          // Switch the value of j
          if ($j ==1) {$j = 2;} else {$j = 1;};
        } 
 
        // All done - if checksum is divisible by 10, it is a valid modulus 10.
        // If not, report an error.
        if ($checksum % 10 != 0)
            {
            $error = $this->getParameterHolder()->get('cc_error_number');
            return false; 
        }
      }  
 
      // The following are the card-specific checks we undertake.
 
      // Load an array with the valid prefixes for this card
      $prefix = split(',',self::$CARDS[$cardType]['prefixes']);
 
      // Now see if any of them match what we have in the card number  
      $prefixValid = false; 
      for ($i=0; $i<sizeof($prefix); $i++)
        {
        $exp = '^' . $prefix[$i];
        if (ereg($exp,$cardNo))
            {
          $prefixValid = true;
          break;
        }
      }
 
      // If it isn't a valid prefix there's no point at looking at the length
      if (!$prefixValid)
        {
         $error = $this->getParameterHolder()->get('cc_error_number');
         return false; 
      }
 
      // See if the length is valid for this card
      $lengthValid = false;
      $lengths = split(',',self::$CARDS[$cardType]['length']);
      for ($j=0; $j<sizeof($lengths); $j++)
        {
        if (strlen($cardNo) == $lengths[$j])
            {
          $lengthValid = true;
          break;
        }
      }
 
      // See if all is OK by seeing if the length was valid. 
      if (!$lengthValid)
        {
         $error = $this->getParameterHolder()->get('cc_error_length');
         return false; 
      };   
 
      // The credit card is in the required format.
      return true;
  }
}
by scott meves on 2007-04-08, tagged cc  creditcard  validation  validator 

Credit Card validator

sfValidator extension based on Credit Card Validator code by Harish Chauhan (from phpclasses.org). With this extension you can validate this type of credit cards: VISA, MASTERCARD, DISCOVER, AMEX, DINERS,JCB, Australian Bankcard, EnRoute And Switch Solo.

IMHO isn't a bad idea to include anything like this in standard sfValidator code. While here you have the source code of my adaptation of credit cards validator.

<?php
 
/*
 
Symfony integration as sfValidator of CCVAL
Date - Jun 17, 2006
Author - Oriol Rius (oriol@joor.net)
 
Credit CArd Validator
Date - Jan 14, 2005
Author - Harish Chauhan
 
 
ABOUT
This PHP script will calidate credit cards by checking there length
and pattern and checksum using mod 10.
 
Supported credit cards are VISA, MASTERCARD, DISCOVER, AMEX, DINERS,
JCB, Australian Bankcard, EnRoute And Switch Solo.
*/
 
class CCVAL extends sfValidator
{
 
    public function execute (&$value, &$error)
    {       
        // Recuperamos parámetros validar
        $num_param = $this->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<strlen($ccnum); $i+=2)
        {
            $digit = (int)($ccnum{$i-1}) * 2;
            if ($digit < 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"=>"/^4\d{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);
            }
        }
    }
}
?>

An example of how you can call CCVAL validator from validate yml file:

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

Sorry for my poor english.

by Oriol Rius on 2006-06-24, tagged cc  validation  validator