Scrutinizer GitHub App not installed

We could not synchronize checks via GitHub's checks API since Scrutinizer's GitHub App is not installed for this repository.

Install GitHub App

Completed
Push — master ( 7a907e...46541c )
by Henrique
05:14
created

CreditCard::__construct()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 10
ccs 7
cts 7
cp 1
rs 9.4285
cc 3
eloc 6
nc 2
nop 1
crap 3
1
<?php
2
3
/*
4
 * This file is part of Respect/Validation.
5
 *
6
 * (c) Alexandre Gomes Gaigalas <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the "LICENSE.md"
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Respect\Validation\Rules;
13
14
use Respect\Validation\Exceptions\ComponentException;
15
16
class CreditCard extends AbstractRule
17
{
18
    const AMERICAN_EXPRESS = 'American Express';
19
    const DINERS_CLUB = 'Diners Club';
20
    const DISCOVER = 'Discover';
21
    const JCB = 'JCB';
22
    const MASTERCARD = 'MasterCard';
23
    const VISA = 'Visa';
24
25
    /**
26
     * @var string
27
     */
28
    public $brand;
29
30
    /**
31
     * @var array
32
     */
33
    private $brands = [
34
        self::AMERICAN_EXPRESS => '/^3[47]\d{13}$/',
35
        self::DINERS_CLUB => '/^3(?:0[0-5]|[68]\d)\d{11}$/',
36
        self::DISCOVER => '/^6(?:011|5\d{2})\d{12}$/',
37
        self::JCB => '/^(?:2131|1800|35\d{3})\d{11}$/',
38
        self::MASTERCARD => '/^5[1-5]\d{14}$/',
39
        self::VISA => '/^4\d{12}(?:\d{3})?$/',
40
    ];
41
42
    /**
43
     * @param string $brand Optional credit card brand.
44
     */
45 3
    public function __construct($brand = null)
46
    {
47 3
        if (null !== $brand && !isset($this->brands[$brand])) {
48 1
            $brands = implode(', ', array_keys($this->brands));
49 1
            $message = sprintf('"%s" is not a valid credit card brand (Available: %s).', $brand, $brands);
50 1
            throw new ComponentException($message);
51
        }
52
53 2
        $this->brand = $brand;
54 2
    }
55
56
    /**
57
     * {@inheritdoc}
58
     */
59 26
    public function validate($input)
60
    {
61 26
        $input = preg_replace('([^0-9])', '', $input);
62
63 26
        if (empty($input)) {
64 3
            return false;
65
        }
66
67 23
        if (!$this->verifyMod10($input)) {
68 3
            return false;
69
        }
70
71 20
        return $this->verifyBrand($input);
72
    }
73
74
    /**
75
     * Returns whether the input matches the Luhn algorithm or not.
76
     *
77
     * @param string $input
78
     *
79
     * @return bool
80
     */
81 23
    private function verifyMod10($input)
82
    {
83 23
        $sum = 0;
84 23
        $input = strrev($input);
85 23
        for ($i = 0; $i < strlen($input); ++$i) {
86 23
            $current = substr($input, $i, 1);
87 23
            if ($i % 2 == 1) {
88 22
                $current *= 2;
89 22
                if ($current > 9) {
90 19
                    $firstDigit = $current % 10;
91 19
                    $secondDigit = ($current - $firstDigit) / 10;
92 19
                    $current = $firstDigit + $secondDigit;
93 19
                }
94 22
            }
95 23
            $sum += $current;
96 23
        }
97
98 23
        return $sum % 10 == 0;
99
    }
100
101
    /**
102
     * Returns whether the input matches the defined credit card brand or not.
103
     *
104
     * @param string $input
105
     *
106
     * @return bool
107
     */
108 20
    private function verifyBrand($input)
109
    {
110 20
        if (null === $this->brand) {
111 7
            return true;
112
        }
113
114 13
        $pattern = $this->brands[$this->brand];
115
116 13
        return preg_match($pattern, $input) > 0;
117
    }
118
}
119