Isbn   A
last analyzed

Complexity

Total Complexity 11

Size/Duplication

Total Lines 66
Duplicated Lines 0 %

Test Coverage

Coverage 92.86%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 21
c 1
b 0
f 0
dl 0
loc 66
ccs 13
cts 14
cp 0.9286
rs 10
wmc 11

4 Methods

Rating   Name   Duplication   Size   Complexity  
A check() 0 18 5
A fillParameters() 0 7 2
A shortChecksumMatches() 0 3 1
A getShortChecksum() 0 12 3
1
<?php
2
3
/**
4
 * This file is part of Dimtrovich/Validation.
5
 *
6
 * (c) 2023 Dimitri Sitchet Tomkeu <[email protected]>
7
 *
8
 * For the full copyright and license information, please view
9
 * the LICENSE file that was distributed with this source code.
10
 */
11
12
namespace Dimtrovich\Validation\Rules;
13
14
use Rakit\Validation\Rule;
15
16
class Isbn extends Ean
17
{
18
    /**
19
     * {@inheritDoc}
20
     */
21
    public function fillParameters(array $params): Rule
22
    {
23
        if (empty($params)) {
24 2
            $params = [10, 13];
25
        }
26
27 2
        return parent::fillParameters($params);
28
    }
29
30
    /**
31
     * Check if the current value is a valid International Standard Book Number (ISBN).
32
     *
33
     * @see https://en.wikipedia.org/wiki/International_Standard_Book_Number
34
     *
35
     * @credit <a href="https://github.com/Intervention/validation">Intervention/validation - \Intervention\Validation\Rules\Isbn</a>
36
     *
37
     * @param mixed $value
38
     */
39
    public function check($value): bool
40
    {
41
        // normalize value
42 2
        $value = preg_replace('/[^0-9x]/i', '', $value);
43
44
        if (! $this->hasAllowedLength($value)) {
45 2
            return false;
46
        }
47
48
        switch (strlen($value)) {
49
            case 10:
50 2
                return $this->shortChecksumMatches($value);
51
52
            case 13: // isbn-13 is a subset of ean-13
53 2
                return preg_match('/^(978|979)/', $value) && parent::checksumMatches($value);
54
        }
55
56
        return false;
57
    }
58
59
    /**
60
     * Determine if checksum for ISBN-10 numbers is valid
61
     */
62
    private function shortChecksumMatches(string $value): bool
63
    {
64 2
        return $this->getShortChecksum($value) % 11 === 0;
65
    }
66
67
    /**
68
     * Calculate checksum of short ISBN numbers
69
     */
70
    private function getShortChecksum(string $value): int
71
    {
72 2
        $checksum   = 0;
73 2
        $multiplier = 10;
74
75
        foreach (str_split($value) as $digit) {
76 2
            $digit = strtolower($digit) === 'x' ? 10 : (int) $digit;
77 2
            $checksum += $digit * $multiplier;
78 2
            $multiplier--;
79
        }
80
81 2
        return $checksum;
82
    }
83
}
84