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
Pull Request — master (#1018)
by Henrique
04:13
created

CreditCard::verifyBrand()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 1
dl 0
loc 9
ccs 5
cts 5
cp 1
crap 2
rs 9.6666
c 0
b 0
f 0
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
declare(strict_types=1);
13
14
namespace Respect\Validation\Rules;
15
16
use Respect\Validation\Exceptions\ComponentException;
17
use function array_keys;
18
use function implode;
19
use function is_scalar;
20
use function preg_match;
21
use function preg_replace;
22
23
/**
24
 * Validates whether the input is a credit card number.
25
 *
26
 * @author Andy Snell <[email protected]>
27
 * @author Henrique Moody <[email protected]>
28
 * @author Jean Pimentel <[email protected]>
29
 * @author Alexander <[email protected]>
30
 * @author Nick Lombard <[email protected]>
31
 * @author William Espindola <[email protected]>
32
 */
33
final class CreditCard extends AbstractRule
34
{
35
    /**
36
     * @var string
37
     */
38
    public const ANY = 'Any';
39
40
    /**
41
     * @var string
42
     */
43
    public const AMERICAN_EXPRESS = 'American Express';
44
45
    /**
46
     * @var string
47
     */
48
    public const DINERS_CLUB = 'Diners Club';
49
50
    /**
51
     * @var string
52
     */
53
    public const DISCOVER = 'Discover';
54
55
    /**
56
     * @var string
57
     */
58
    public const JCB = 'JCB';
59
60
    /**
61
     * @var string
62
     */
63
    public const MASTERCARD = 'MasterCard';
64
65
    /**
66
     * @var string
67
     */
68
    public const VISA = 'Visa';
69
70
    /**
71
     * @var array
72
     */
73
    private const BRAND_REGEX_LIST = [
74
        self::ANY => '/^[0-9]+$/',
75
        self::AMERICAN_EXPRESS => '/^3[47]\d{13}$/',
76
        self::DINERS_CLUB => '/^3(?:0[0-5]|[68]\d)\d{11}$/',
77
        self::DISCOVER => '/^6(?:011|5\d{2})\d{12}$/',
78
        self::JCB => '/^(?:2131|1800|35\d{3})\d{11}$/',
79
        self::MASTERCARD => '/(5[1-5]|2[2-7])\d{14}$/',
80
        self::VISA => '/^4\d{12}(?:\d{3})?$/',
81
    ];
82
83
    /**
84
     * @var string
85
     */
86
    private $brand;
87
88
    /**
89
     * Initializes the rule.
90
     *
91
     * @param string $brand
92
     *
93
     * @throws ComponentException
94
     */
95 2
    public function __construct(string $brand = self::ANY)
96
    {
97 2
        if (!isset(self::BRAND_REGEX_LIST[$brand])) {
98 1
            throw new ComponentException(
99 1
                sprintf(
100 1
                    '"%s" is not a valid credit card brand (Available: %s)',
101 1
                    $brand,
102 1
                    implode(', ', array_keys(self::BRAND_REGEX_LIST))
103
                )
104
            );
105
        }
106
107 1
        $this->brand = $brand;
108 1
    }
109
110
    /**
111
     * {@inheritdoc}
112
     */
113 30
    public function validate($input): bool
114
    {
115 30
        if (!is_scalar($input)) {
116 1
            return false;
117
        }
118
119 29
        $input = preg_replace('/[ .-]/', '', (string) $input);
120 29
        if (!(new Luhn())->validate($input)) {
121 5
            return false;
122
        }
123
124 24
        return preg_match(self::BRAND_REGEX_LIST[$this->brand], $input) > 0;
125
    }
126
}
127