source: trunk/library/Zend/Validate/CreditCard.php @ 4456

Revision 4456, 9.9 KB checked in by airton, 13 years ago (diff)

Ticket #1991 - Parametrizacao das buscas LDAP no Expresso Mail - Adicionando arquivos e bibliotecas

  • Property svn:executable set to *
Line 
1<?php
2/**
3 * Zend Framework
4 *
5 * LICENSE
6 *
7 * This source file is subject to the new BSD license that is bundled
8 * with this package in the file LICENSE.txt.
9 * It is also available through the world-wide-web at this URL:
10 * http://framework.zend.com/license/new-bsd
11 * If you did not receive a copy of the license and are unable to
12 * obtain it through the world-wide-web, please send an email
13 * to license@zend.com so we can send you a copy immediately.
14 *
15 * @category   Zend
16 * @package    Zend_Validate
17 * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
18 * @license    http://framework.zend.com/license/new-bsd     New BSD License
19 * @version    $Id: CreditCard.php 22668 2010-07-25 14:50:46Z thomas $
20 */
21
22/**
23 * @see Zend_Validate_Abstract
24 */
25require_once 'Zend/Validate/Abstract.php';
26
27/**
28 * @category   Zend
29 * @package    Zend_Validate
30 * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
31 * @license    http://framework.zend.com/license/new-bsd     New BSD License
32 */
33class Zend_Validate_CreditCard extends Zend_Validate_Abstract
34{
35    /**
36     * Detected CCI list
37     *
38     * @var string
39     */
40    const ALL              = 'All';
41    const AMERICAN_EXPRESS = 'American_Express';
42    const UNIONPAY         = 'Unionpay';
43    const DINERS_CLUB      = 'Diners_Club';
44    const DINERS_CLUB_US   = 'Diners_Club_US';
45    const DISCOVER         = 'Discover';
46    const JCB              = 'JCB';
47    const LASER            = 'Laser';
48    const MAESTRO          = 'Maestro';
49    const MASTERCARD       = 'Mastercard';
50    const SOLO             = 'Solo';
51    const VISA             = 'Visa';
52
53    const CHECKSUM       = 'creditcardChecksum';
54    const CONTENT        = 'creditcardContent';
55    const INVALID        = 'creditcardInvalid';
56    const LENGTH         = 'creditcardLength';
57    const PREFIX         = 'creditcardPrefix';
58    const SERVICE        = 'creditcardService';
59    const SERVICEFAILURE = 'creditcardServiceFailure';
60
61    /**
62     * Validation failure message template definitions
63     *
64     * @var array
65     */
66    protected $_messageTemplates = array(
67        self::CHECKSUM       => "'%value%' seems to contain an invalid checksum",
68        self::CONTENT        => "'%value%' must contain only digits",
69        self::INVALID        => "Invalid type given. String expected",
70        self::LENGTH         => "'%value%' contains an invalid amount of digits",
71        self::PREFIX         => "'%value%' is not from an allowed institute",
72        self::SERVICE        => "'%value%' seems to be an invalid creditcard number",
73        self::SERVICEFAILURE => "An exception has been raised while validating '%value%'",
74    );
75
76    /**
77     * List of allowed CCV lengths
78     *
79     * @var array
80     */
81    protected $_cardLength = array(
82        self::AMERICAN_EXPRESS => array(15),
83        self::DINERS_CLUB      => array(14),
84        self::DINERS_CLUB_US   => array(16),
85        self::DISCOVER         => array(16),
86        self::JCB              => array(16),
87        self::LASER            => array(16, 17, 18, 19),
88        self::MAESTRO          => array(12, 13, 14, 15, 16, 17, 18, 19),
89        self::MASTERCARD       => array(16),
90        self::SOLO             => array(16, 18, 19),
91        self::UNIONPAY         => array(16, 17, 18, 19),
92        self::VISA             => array(16),
93    );
94
95    /**
96     * List of accepted CCV provider tags
97     *
98     * @var array
99     */
100    protected $_cardType = array(
101        self::AMERICAN_EXPRESS => array('34', '37'),
102        self::DINERS_CLUB      => array('300', '301', '302', '303', '304', '305', '36'),
103        self::DINERS_CLUB_US   => array('54', '55'),
104        self::DISCOVER         => array('6011', '622126', '622127', '622128', '622129', '62213',
105                                        '62214', '62215', '62216', '62217', '62218', '62219',
106                                        '6222', '6223', '6224', '6225', '6226', '6227', '6228',
107                                        '62290', '62291', '622920', '622921', '622922', '622923',
108                                        '622924', '622925', '644', '645', '646', '647', '648',
109                                        '649', '65'),
110        self::JCB              => array('3528', '3529', '353', '354', '355', '356', '357', '358'),
111        self::LASER            => array('6304', '6706', '6771', '6709'),
112        self::MAESTRO          => array('5018', '5020', '5038', '6304', '6759', '6761', '6763'),
113        self::MASTERCARD       => array('51', '52', '53', '54', '55'),
114        self::SOLO             => array('6334', '6767'),
115        self::UNIONPAY         => array('622126', '622127', '622128', '622129', '62213', '62214',
116                                        '62215', '62216', '62217', '62218', '62219', '6222', '6223',
117                                        '6224', '6225', '6226', '6227', '6228', '62290', '62291',
118                                        '622920', '622921', '622922', '622923', '622924', '622925'),
119        self::VISA             => array('4'),
120    );
121
122    /**
123     * CCIs which are accepted by validation
124     *
125     * @var array
126     */
127    protected $_type = array();
128
129    /**
130     * Service callback for additional validation
131     *
132     * @var callback
133     */
134    protected $_service;
135
136    /**
137     * Constructor
138     *
139     * @param string|array $type OPTIONAL Type of CCI to allow
140     */
141    public function __construct($options = array())
142    {
143        if ($options instanceof Zend_Config) {
144            $options = $options->toArray();
145        } else if (!is_array($options)) {
146            $options = func_get_args();
147            $temp['type'] = array_shift($options);
148            if (!empty($options)) {
149                $temp['service'] = array_shift($options);
150            }
151
152            $options = $temp;
153        }
154
155        if (!array_key_exists('type', $options)) {
156            $options['type'] = self::ALL;
157        }
158
159        $this->setType($options['type']);
160        if (array_key_exists('service', $options)) {
161            $this->setService($options['service']);
162        }
163    }
164
165    /**
166     * Returns a list of accepted CCIs
167     *
168     * @return array
169     */
170    public function getType()
171    {
172        return $this->_type;
173    }
174
175    /**
176     * Sets CCIs which are accepted by validation
177     *
178     * @param string|array $type Type to allow for validation
179     * @return Zend_Validate_CreditCard Provides a fluid interface
180     */
181    public function setType($type)
182    {
183        $this->_type = array();
184        return $this->addType($type);
185    }
186
187    /**
188     * Adds a CCI to be accepted by validation
189     *
190     * @param string|array $type Type to allow for validation
191     * @return Zend_Validate_CreditCard Provides a fluid interface
192     */
193    public function addType($type)
194    {
195        if (is_string($type)) {
196            $type = array($type);
197        }
198
199        foreach($type as $typ) {
200            if (defined('self::' . strtoupper($typ)) && !in_array($typ, $this->_type)) {
201                $this->_type[] = $typ;
202            }
203
204            if (($typ == self::ALL)) {
205                $this->_type = array_keys($this->_cardLength);
206            }
207        }
208
209        return $this;
210    }
211
212    /**
213     * Returns the actual set service
214     *
215     * @return callback
216     */
217    public function getService()
218    {
219        return $this->_service;
220    }
221
222    /**
223     * Sets a new callback for service validation
224     *
225     * @param unknown_type $service
226     */
227    public function setService($service)
228    {
229        if (!is_callable($service)) {
230            require_once 'Zend/Validate/Exception.php';
231            throw new Zend_Validate_Exception('Invalid callback given');
232        }
233
234        $this->_service = $service;
235        return $this;
236    }
237
238    /**
239     * Defined by Zend_Validate_Interface
240     *
241     * Returns true if and only if $value follows the Luhn algorithm (mod-10 checksum)
242     *
243     * @param  string $value
244     * @return boolean
245     */
246    public function isValid($value)
247    {
248        $this->_setValue($value);
249
250        if (!is_string($value)) {
251            $this->_error(self::INVALID, $value);
252            return false;
253        }
254
255        if (!ctype_digit($value)) {
256            $this->_error(self::CONTENT, $value);
257            return false;
258        }
259
260        $length = strlen($value);
261        $types  = $this->getType();
262        $foundp = false;
263        $foundl = false;
264        foreach ($types as $type) {
265            foreach ($this->_cardType[$type] as $prefix) {
266                if (substr($value, 0, strlen($prefix)) == $prefix) {
267                    $foundp = true;
268                    if (in_array($length, $this->_cardLength[$type])) {
269                        $foundl = true;
270                        break 2;
271                    }
272                }
273            }
274        }
275
276        if ($foundp == false){
277            $this->_error(self::PREFIX, $value);
278            return false;
279        }
280
281        if ($foundl == false) {
282            $this->_error(self::LENGTH, $value);
283            return false;
284        }
285
286        $sum    = 0;
287        $weight = 2;
288
289        for ($i = $length - 2; $i >= 0; $i--) {
290            $digit = $weight * $value[$i];
291            $sum += floor($digit / 10) + $digit % 10;
292            $weight = $weight % 2 + 1;
293        }
294
295        if ((10 - $sum % 10) % 10 != $value[$length - 1]) {
296            $this->_error(self::CHECKSUM, $value);
297            return false;
298        }
299
300        if (!empty($this->_service)) {
301            try {
302                require_once 'Zend/Validate/Callback.php';
303                $callback = new Zend_Validate_Callback($this->_service);
304                $callback->setOptions($this->_type);
305                if (!$callback->isValid($value)) {
306                    $this->_error(self::SERVICE, $value);
307                    return false;
308                }
309            } catch (Zend_Exception $e) {
310                $this->_error(self::SERVICEFAILURE, $value);
311                return false;
312            }
313        }
314
315        return true;
316    }
317}
Note: See TracBrowser for help on using the repository browser.