Test Failed
Pull Request — master (#245)
by Roberto
02:32
created

Keys::build()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 34

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 3.0015

Importance

Changes 0
Metric Value
dl 0
loc 34
ccs 17
cts 18
cp 0.9444
rs 9.376
c 0
b 0
f 0
cc 3
nc 4
nop 9
crap 3.0015

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
namespace NFePHP\Common;
4
5
/**
6
 * Class to create and validate the identification keys of electronic documents
7
 * from SPED
8
 * NT 2018.001 Emitente com CPF e IE
9
 * @category   NFePHP
10
 * @package    NFePHP\Common\Keys
11
 * @copyright  Copyright (c) 2008-2018
12
 * @license    http://www.gnu.org/licenses/lesser.html LGPL v3
13
 * @author     Roberto L. Machado <linux dot rlm at gmail dot com>
14
 * @link       http://github.com/nfephp-org/sped-common for the canonical source repository
15
 */
16
17
class Keys
18
{
19
    /**
20
     * Build 44 digits keys to NFe, NFCe, CTe and MDFe
21
     * @param string $cUF UF number
22
     * @param string $ano year
23
     * @param string $mes month
24
     * @param string $cnpj or CPF
25
     * @param string $mod model of document 55, 65, 57 etc
26
     * @param string $serie
27
     * @param string $numero document number
28
     * @param string $tpEmis emission type
29
     * @param string $codigo random number or document number
30
     * @return string
31
     */
32 2
    public static function build(
33
        $cUF,
34
        $ano,
35
        $mes,
36
        $cnpj,
37
        $mod,
38
        $serie,
39
        $numero,
40
        $tpEmis,
41
        $codigo = null
42
    ) {
43 2
        if (empty($codigo)) {
44
            $codigo = self::random();
45
        }
46
        //if a cpf with 11 digits is passed then complete with leading zeros
47
        //up to the 14 digits
48 2
        if (strlen($cnpj) < 14) {
49 1
            $cnpj = str_pad($cnpj, 14, '0', STR_PAD_LEFT);
50
        }
51 2
        $format = "%02d%02d%02d%s%02d%03d%09d%01d%08d";
52 2
        $key = sprintf(
53 2
            $format,
54 2
            $cUF,
55 2
            $ano,
56 2
            $mes,
57 2
            $cnpj,
58 2
            $mod,
59 2
            $serie,
60 2
            $numero,
61 2
            $tpEmis,
62 2
            $codigo
63
        );
64 2
        return $key . self::verifyingDigit($key);
65
    }
66
    
67
    /**
68
     * Verifies that the key provided is valid
69
     * @param string $key
70
     * @return boolean
71
     */
72 2
    public static function isValid($key)
73
    {
74 2
        if (strlen($key) != 44) {
75
            return false;
76
        }
77 2
        $cDV = substr($key, -1);
78 2
        $calcDV = self::verifyingDigit(substr($key, 0, 43));
79 2
        if ($cDV === $calcDV) {
80 1
            return true;
81
        }
82 1
        return false;
83
    }
84
    
85
    /**
86
     * This method calculates verifying digit
87
     * @param string $key
88
     * @return string
89
     */
90 6
    public static function verifyingDigit($key)
91
    {
92 6
        if (strlen($key) != 43) {
93 1
            return '';
94
        }
95 5
        $multipliers = [2, 3, 4, 5, 6, 7, 8, 9];
96 5
        $iCount = 42;
97 5
        $weightedSum = 0;
98 5
        while ($iCount >= 0) {
99 5
            for ($mCount = 0; $mCount < 8 && $iCount >= 0; $mCount++) {
100 5
                $weightedSum += (substr($key, $iCount, 1) * $multipliers[$mCount]);
101 5
                $iCount--;
102
            }
103
        }
104 5
        $vdigit = 11 - ($weightedSum % 11);
105 5
        if ($vdigit > 9) {
106 3
            $vdigit = 0;
107
        }
108 5
        return (string) $vdigit;
109
    }
110
    
111
    /**
112
     * Generate and return a 8 digits random number
113
     * for cNF tag
114
     * @param string|null $nnf
115
     * @return string
116
     */
117
    public static function random($nnf = null)
118
    {
119
        $loop = true;
120
        while ($loop) {
121
            $cnf = str_pad(mt_rand(0, 99999999), 8, '0', STR_PAD_LEFT);
122
            $loop = !self::cNFIsValid($cnf);
123
            if (!empty($nnf)) {
124
                if (intval($cnf) === intval($nnf)) {
125
                    $loop = true;
126
                }
127
            }
128
        }
129
        return $cnf;
0 ignored issues
show
Bug introduced by
The variable $cnf does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
130
    }
131
    
132
    /**
133
     * Verify if cNF number is valid NT2019.001
134
     * @param string $cnf
135
     */
136
    public static function cNFIsValid($cnf)
137
    {
138
        $defs = [
139
            '00000000', '11111111', '22222222', '33333333', '44444444',
140
            '55555555', '66666666', '77777777', '88888888', '99999999',
141
            '12345678', '23456789', '34567890', '45678901', '56789012',
142
            '67890123', '78901234', '89012345', '90123456', '01234567'
143
        ];
144
        return !in_array($cnf, $defs);
145
    }
146
}
147