Code snippets for symfony 1.x

Navigation

Refine Tags

Snippets tagged "validator creditcard"

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