Completed
Push — master ( 28360b...e6d6d0 )
by Roberto
06:06 queued 10s
created

Make   A

Complexity

Total Complexity 27

Size/Duplication

Total Lines 208
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 27
lcom 1
cbo 1
dl 0
loc 208
ccs 0
cts 109
cp 0
rs 10
c 0
b 0
f 0

13 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 9 1
A __toString() 0 7 2
A getChave() 0 4 1
A getXML() 0 4 1
A setToAscii() 0 7 3
parse() 0 1 ?
A __call() 0 24 5
A loadTagClass() 0 10 2
A createProperty() 0 4 1
A removeTagPrefix() 0 4 1
A createEmptyProperties() 0 13 3
B validateDataObjects() 0 21 6
A hashCSRT() 0 4 1
1
<?php
2
3
namespace NFePHP\BPe\Common;
4
5
/**
6
 * Abstract class to build Make::class
7
 */
8
use NFePHP\Common\DOMImproved as Dom;
9
use NFePHP\Common\Keys;
10
use NFePHP\BPe\Factories\TagInterface;
11
use \DOMElement;
12
13
abstract class Make
14
{
15
    /**
16
     * @var array
17
     */
18
    public $errors = [];
19
    /**
20
     * @var string
21
     */
22
    public $chave;
23
    /**
24
     * @var NFePHP\Common\DOMImproved
25
     */
26
    protected $dom;
27
    /**
28
     * @var \DOMElement
29
     */
30
    protected $root;
31
32
    /**
33
     * @var string
34
     */
35
    protected $id;
36
37
    /**
38
     * @var string
39
     */
40
    protected $xmlns = 'http://www.portalfiscal.inf.br/bpe';
41
42
    /**
43
     * @var bool
44
     */
45
    protected $onlyAscii = false;
46
47
    /**
48
     * @var array
49
     */
50
    protected $available = [];
51
    /**
52
     * @var string
53
     */
54
    protected $xml;
55
    
56
    /**
57
     * Constructor
58
     */
59
    public function __construct()
60
    {
61
        $this->dom = new Dom('1.0', 'UTF-8');
0 ignored issues
show
Documentation Bug introduced by
It seems like new \NFePHP\Common\DOMImproved('1.0', 'UTF-8') of type object<NFePHP\Common\DOMImproved> is incompatible with the declared type object<NFePHP\BPe\Common...PHP\Common\DOMImproved> of property $dom.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
62
        $this->dom->preserveWhiteSpace = false;
63
        $this->dom->formatOutput = false;
64
        $rootname = 'BPe';
65
        $this->$rootname = $this->dom->createElement($rootname);
66
        $this->$rootname->setAttribute("xmlns", $this->xmlns);
67
    }
68
69
    public function __toString()
70
    {
71
        if (empty($this->xml)) {
72
            $this->parse();
73
        }
74
        return $this->xml;
75
    }
76
    
77
    /**
78
     * Return document key
79
     * @return type
80
     */
81
    public function getChave()
82
    {
83
        return $this->chave;
84
    }
85
    
86
    /**
87
     * Returns XML
88
     * @return type
89
     */
90
    public function getXML()
91
    {
92
        return $this->xml;
93
    }
94
95
    /**
96
     * To force convertion strings to ASCII
97
     * @param bool $flag
98
     * @return bool
99
     */
100
    public function setToAscii($flag = null)
101
    {
102
        if (isset($flag) && is_bool($flag)) {
103
            $this->onlyAscii = $flag;
104
        }
105
        return $this->onlyAscii;
106
    }
107
108
    /**
109
     * Abstract function to convert Tag::classes into DOM objects
110
     */
111
    abstract public function parse();
112
113
    /**
114
     * Call classes to build each element for XML
115
     * @param string $name
116
     * @param array $arguments [std]
117
     * @return object|array
118
     * @throws \Exception
119
     */
120
    public function __call($name, $arguments)
121
    {
122
        $name = str_replace('-', '', strtolower($name));
123
        $realname = $name;
124
        $arguments[0]->onlyAscii = $this->onlyAscii;
125
        if (!array_key_exists($realname, $this->available)) {
126
            throw new \Exception("Não encontrada referencia ao método $name.");
127
        }
128
        $className = $this->available[$realname]['class'];
129
        if (empty($arguments[0])) {
130
            throw new \Exception("Sem dados passados para o método [$name].");
131
        }
132
        $propname = str_replace('tag', '', $name);
133
        $c = $this->loadTagClass($className, $arguments);
134
        if ($this->available[$realname]['type'] == 'multiple') {
135
            if (!isset($this->$propname)) {
136
                $this->createProperty($propname, []);
0 ignored issues
show
Documentation introduced by
array() is of type array, but the function expects a object<NFePHP\BPe\Factories\TagInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
137
            }
138
            array_push($this->$propname, $c);
139
        } else {
140
            $this->createProperty($propname, $c);
141
        }
142
        return $this->$propname;
143
    }
144
145
    /**
146
     * Load Tag::class
147
     * @param string $className
148
     * @param array $arguments
149
     * @return \NFePHP\BPe\Tags\className
150
     */
151
    protected function loadTagClass($className, $arguments)
152
    {
153
        $c = new $className($this->dom);
154
        $c->setToASCII($this->onlyAscii);
155
        $c->loadParameters($arguments[0]);
156
        if (!empty($c->errors)) {
157
            array_push($this->errors, $c->errors);
158
        }
159
        return $c;
160
    }
161
162
    /**
163
     * Create properties
164
     * @param string $name
165
     * @param TagInterface $value
166
     */
167
    public function createProperty($name, TagInterface $value)
168
    {
169
        $this->{$name} = $value;
170
    }
171
172
    private function removeTagPrefix($string)
173
    {
174
        return strtolower(str_replace('tag', '', $string));
175
    }
176
177
    protected function createEmptyProperties()
178
    {
179
        $nodes = array_keys($this->available);
180
        $nodes = array_map([$this, 'removeTagPrefix'], $nodes);
181
        foreach ($nodes as $node) {
182
            $type = $this->available["tag{$node}"]['type'];
183
            if ($type == 'single') {
184
                $this->{$node} = null;
185
            } else {
186
                $this->{$node} = [];
187
            }
188
        }
189
    }
190
    
191
    /**
192
     * Validate all objects
193
     */
194
    protected function validateDataObjects()
195
    {
196
        $nodes = array_keys($this->available);
197
        $nodes = array_map([$this, 'removeTagPrefix'], $nodes);
198
        foreach ($nodes as $node) {
199
            $occur = $this->available["tag{$node}"]['occurrence'];
200
            if ($occur[0] == 1 && empty($this->$node)) {
201
                //o objeto é obrigatório e não foi instanciado
202
                $this->errors[] = "O objeto [tag{$node}] é obrigatório e "
203
                    . "não foi instanciado!";
204
            }
205
            if (is_array($this->$node)) {
206
                $n = count($this->$node);
207
                if ($n >  $occur[1]) {
208
                    //existem mais objetos que o permitido
209
                    $this->errors[] = "Existem mais objetos [tag{$node}: $n] "
210
                        . "que o limite permitido [max: {$occur[1]}]!";
211
                }
212
            }
213
        }
214
    }
215
    
216
    protected function hashCSRT($csrt, $chave)
217
    {
218
        return strtoupper(base64_encode(sha1($csrt . $chave, true)));
219
    }
220
}
221