Passed
Push — master ( 362ec5...c42e48 )
by Petr
05:09
created

Pohoda   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 207
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 7
Bugs 0 Features 1
Metric Value
wmc 22
eloc 61
dl 0
loc 207
ccs 60
cts 60
cp 1
rs 10
c 7
b 0
f 1

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
A close() 0 5 1
A getTransformerListing() 0 3 1
A open() 0 33 4
A setApplicationName() 0 3 1
A create() 0 3 1
A next() 0 12 5
A __call() 0 17 4
A addItem() 0 11 2
A load() 0 13 2
1
<?php
2
/**
3
 * This file is part of riesenia/pohoda package.
4
 *
5
 * Licensed under the MIT License
6
 * (c) RIESENIA.com
7
 */
8
9
declare(strict_types=1);
10
11
namespace Riesenia;
12
13
14
use Riesenia\Pohoda\AbstractAgenda;
15
16
17
/**
18
 * Factory for Pohoda objects.
19
 *
20
 * @method Pohoda\AddressBook   createAddressBook(array $data = [])
21
 * @method Pohoda\Bank          createBank(array $data = [])
22
 * @method Pohoda\CashSlip      createCashSlip(array $data = [])
23
 * @method Pohoda\Category      createCategory(array $data = [])
24
 * @method Pohoda\Contract      createContract(array $data = [])
25
 * @method Pohoda\IntDoc        createIntDoc(array $data = [])
26
 * @method Pohoda\IntParam      createIntParam(array $data = [])
27
 * @method Pohoda\Invoice       createInvoice(array $data = [])
28
 * @method Pohoda\IssueSlip     createIssueSlip(array $data = [])
29
 * @method Pohoda\ListRequest   createListRequest(array $data = [])
30
 * @method Pohoda\Offer         createOffer(array $data = [])
31
 * @method Pohoda\Order         createOrder(array $data = [])
32
 * @method Pohoda\PrintRequest  createPrintRequest(array $data = [])
33
 * @method Pohoda\Receipt       createReceipt(array $data = [])
34
 * @method Pohoda\Stock         createStock(array $data = [])
35
 * @method Pohoda\StockTransfer createStockTransfer(array $data = [])
36
 * @method Pohoda\Storage       createStorage(array $data = [])
37
 * @method Pohoda\Supplier      createSupplier(array $data = [])
38
 * @method Pohoda\UserList      createUserList(array $data = [])
39
 * @method Pohoda\Voucher       createVoucher(array $data = [])
40
 * @method \bool loadAddressBook(string $filename)
41
 * @method \bool loadBank(string $filename)
42
 * @method \bool loadCashSlip(string $filename)
43
 * @method \bool loadCategory(string $filename)
44
 * @method \bool loadContract(string $filename)
45
 * @method \bool loadIntDoc(string $filename)
46
 * @method \bool loadIntParam(string $filename)
47
 * @method \bool loadInvoice(string $filename)
48
 * @method \bool loadIssueSlip(string $filename)
49
 * @method \bool loadListRequest(string $filename)
50
 * @method \bool loadOffer(string $filename)
51
 * @method \bool loadOrder(string $filename)
52
 * @method \bool loadPrintRequest(string $filename)
53
 * @method \bool loadReceipt(string $filename)
54
 * @method \bool loadStock(string $filename)
55
 * @method \bool loadStockTransfer(string $filename)
56
 * @method \bool loadStorage(string $filename)
57
 * @method \bool loadSupplier(string $filename)
58
 * @method \bool loadUserList(string $filename)
59
 * @method \bool loadVoucher(string $filename)
60
 *
61
 * @link https://www.stormware.cz/pohoda/xml/seznamschemat/   schemas
62
 */
63
class Pohoda
64
{
65
66
    protected string $application = 'Pohoda connector';
67
68
    protected bool $isInMemory;
69
70
    protected \XMLWriter $xmlWriter;
71
72
    protected \XMLReader $xmlReader;
73
74
    protected Pohoda\AgendaFactory $agendaFactory;
75
    protected Pohoda\Common\NamespacesPaths $namespacesPaths;
76
77
    protected string $elementName;
78
79
    protected bool $importRecursive = false;
80
81 13
    public function __construct(
82
        protected readonly string $companyRegistrationNumber,
83
        protected Pohoda\ValueTransformer\SanitizeEncoding $sanitizeEncoding = new Pohoda\ValueTransformer\SanitizeEncoding(new Pohoda\ValueTransformer\Listing())
84
    )
85
    {
86 13
        $this->namespacesPaths = new Pohoda\Common\NamespacesPaths();
87 13
        $this->agendaFactory = new Pohoda\AgendaFactory($this->namespacesPaths, $this->sanitizeEncoding, $this->companyRegistrationNumber);
88
    }
89
90
    /**
91
     * Set the name of the application.
92
     *
93
     * @param string $name
94
     *
95
     * @return void
96
     */
97 1
    public function setApplicationName(string $name): void
98
    {
99 1
        $this->application = $name;
100
    }
101
102
    /**
103
     * Get class listing transformers for content serialization
104
     *
105
     * @return Pohoda\ValueTransformer\Listing
106
     */
107 1
    public function getTransformerListing(): Pohoda\ValueTransformer\Listing
108
    {
109 1
        return $this->sanitizeEncoding->getListing();
110
    }
111
112
    /**
113
     * Create and return instance of requested agenda.
114
     *
115
     * @param string              $name
116
     * @param array<string,mixed> $data
117
     *
118
     * @return AbstractAgenda
119
     */
120 3
    public function create(string $name, array $data = []): AbstractAgenda
121
    {
122 3
        return $this->agendaFactory->getAgenda($name, $data);
123
    }
124
125
    /**
126
     * Open new XML file for writing.
127
     *
128
     * @param string|null $filename path to output file or null for memory
129
     * @param string      $id
130
     * @param string      $note
131
     *
132
     * @return bool
133
     */
134 4
    public function open(?string $filename, string $id, string $note = ''): bool
135
    {
136 4
        $this->xmlWriter = new \XMLWriter();
137
138 4
        if (is_null($filename)) {
139 3
            $this->isInMemory = true;
140 3
            $this->xmlWriter->openMemory();
141
        } else {
142 1
            $this->isInMemory = false;
143
144 1
            if (!$this->xmlWriter->openUri($filename)) {
145
                // @codeCoverageIgnoreStart
146
                // I cannot test this, because it needs source file somewhere online
147
                return false;
148
            }
149
            // @codeCoverageIgnoreEnd
150
        }
151
152 4
        $this->xmlWriter->startDocument('1.0', $this->sanitizeEncoding->getEncoding());
153 4
        $this->xmlWriter->startElementNs('dat', 'dataPack', null);
154
155 4
        $this->xmlWriter->writeAttribute('id', $id);
156 4
        $this->xmlWriter->writeAttribute('ico', $this->companyRegistrationNumber);
157 4
        $this->xmlWriter->writeAttribute('application', $this->application);
158 4
        $this->xmlWriter->writeAttribute('version', '2.0');
159 4
        $this->xmlWriter->writeAttribute('note', $note);
160
161 4
        foreach ($this->namespacesPaths->allNamespaces() as $k => $v) {
162
            // put all known namespaces into base element attributes
163 4
            $this->xmlWriter->writeAttributeNs('xmlns', $k, null, $v);
164
        }
165
166 4
        return true;
167
    }
168
169
    /**
170
     * Add item.
171
     *
172
     * @param string $id
173
     * @param AbstractAgenda $agenda
174
     *
175
     * @return void
176
     */
177 4
    public function addItem(string $id, AbstractAgenda $agenda): void
178
    {
179 4
        $this->xmlWriter->startElementNs('dat', 'dataPackItem', null);
180
181 4
        $this->xmlWriter->writeAttribute('id', $id);
182 4
        $this->xmlWriter->writeAttribute('version', '2.0');
183 4
        $this->xmlWriter->writeRaw((string) $agenda->getXML()->asXML());
184 4
        $this->xmlWriter->endElement();
185
186 4
        if (!$this->isInMemory) {
187 1
            $this->xmlWriter->flush();
188
        }
189
    }
190
191
    /**
192
     * End and close XML file.
193
     *
194
     * @return int|string written bytes for file or XML string for memory
195
     */
196 4
    public function close(): int|string
197
    {
198 4
        $this->xmlWriter->endElement();
199
200 4
        return $this->xmlWriter->flush();
201
    }
202
203
    /**
204
     * Load XML file.
205
     *
206
     * @param string $name
207
     * @param string $filename
208
     *
209
     * @return bool
210
     */
211 3
    public function load(string $name, string $filename): bool
212
    {
213 3
        $this->xmlReader = new \XMLReader();
214
215 3
        if (!@$this->xmlReader->open($filename)) {
216 1
            return false;
217
        }
218
219 2
        $class = $this->agendaFactory->getAgenda($name, [], false);
220 2
        $this->elementName = $class->getImportRoot() ?? throw new \DomainException('Not allowed entity: ' . $name);
0 ignored issues
show
Bug introduced by
Are you sure the usage of $class->getImportRoot() targeting Riesenia\Pohoda\AbstractAgenda::getImportRoot() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
221 2
        $this->importRecursive = $class->canImportRecursive();
222
223 2
        return true;
224
    }
225
226
    /**
227
     * Get next item in loaded file.
228
     *
229
     * @return \SimpleXMLElement|null
230
     */
231 2
    public function next(): ?\SimpleXMLElement
232
    {
233 2
        while (\XMLReader::ELEMENT != $this->xmlReader->nodeType || $this->xmlReader->name !== $this->elementName) {
234 2
            if (!$this->xmlReader->read()) {
235 2
                return null;
236
            }
237
        }
238
239 2
        $xml = new \SimpleXMLElement($this->xmlReader->readOuterXml());
240 2
        $this->importRecursive ? $this->xmlReader->next() : $this->xmlReader->read();
241
242 2
        return $xml;
243
    }
244
245
    /**
246
     * Handle dynamic method calls.
247
     *
248
     * @param string  $method
249
     * @param mixed[] $arguments
250
     *
251
     * @return mixed
252
     */
253 5
    public function __call(string $method, array $arguments)
254
    {
255
        // create<Agenda> method
256 5
        if (\preg_match('/create([A-Z][a-zA-Z0-9]*)/', $method, $matches)) {
257 1
            return \call_user_func([$this, 'create'], $matches[1], $arguments[0] ?? []);
258
        }
259
260
        // load<Agenda> method
261 4
        if (\preg_match('/load([A-Z][a-zA-Z0-9]*)/', $method, $matches)) {
262 3
            if (!isset($arguments[0])) {
263 1
                throw new \DomainException('Filename not set.');
264
            }
265
266 2
            return \call_user_func([$this, 'load'], $matches[1], $arguments[0]);
267
        }
268
269 1
        throw new \BadMethodCallException('Unknown method: ' . $method);
270
    }
271
}
272