Issues (3)

src/Pohoda.php (1 issue)

Labels
Severity
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\ListStock     createListStock(array $data = [])
31
 * @method Pohoda\Offer         createOffer(array $data = [])
32
 * @method Pohoda\Order         createOrder(array $data = [])
33
 * @method Pohoda\PrintRequest  createPrintRequest(array $data = [])
34
 * @method Pohoda\Receipt       createReceipt(array $data = [])
35
 * @method Pohoda\Stock         createStock(array $data = [])
36
 * @method Pohoda\StockTransfer createStockTransfer(array $data = [])
37
 * @method Pohoda\Storage       createStorage(array $data = [])
38
 * @method Pohoda\Supplier      createSupplier(array $data = [])
39
 * @method Pohoda\UserList      createUserList(array $data = [])
40
 * @method Pohoda\Voucher       createVoucher(array $data = [])
41
 * @method \bool loadAddressBook(string $filename)
42
 * @method \bool loadBank(string $filename)
43
 * @method \bool loadCashSlip(string $filename)
44
 * @method \bool loadCategory(string $filename)
45
 * @method \bool loadContract(string $filename)
46
 * @method \bool loadIntDoc(string $filename)
47
 * @method \bool loadIntParam(string $filename)
48
 * @method \bool loadInvoice(string $filename)
49
 * @method \bool loadIssueSlip(string $filename)
50
 * @method \bool loadListRequest(string $filename)
51
 * @method \bool loadListStock(string $filename)
52
 * @method \bool loadOffer(string $filename)
53
 * @method \bool loadOrder(string $filename)
54
 * @method \bool loadPrintRequest(string $filename)
55
 * @method \bool loadReceipt(string $filename)
56
 * @method \bool loadStock(string $filename)
57
 * @method \bool loadStockTransfer(string $filename)
58
 * @method \bool loadStorage(string $filename)
59
 * @method \bool loadSupplier(string $filename)
60
 * @method \bool loadUserList(string $filename)
61
 * @method \bool loadVoucher(string $filename)
62
 *
63
 * @link https://www.stormware.cz/pohoda/xml/seznamschemat/   schemas
64
 */
65
class Pohoda
66
{
67
68
    protected string $application = 'Pohoda connector';
69
70
    protected bool $isInMemory;
71
72
    protected \XMLWriter $xmlWriter;
73
74
    protected \XMLReader $xmlReader;
75
76
    protected Pohoda\AgendaFactory $agendaFactory;
77
    protected Pohoda\Common\NamespacesPaths $namespacesPaths;
78
79
    protected string $elementName;
80
81
    protected bool $importRecursive = false;
82
83 17
    public function __construct(
84
        protected readonly string $companyRegistrationNumber,
85
        protected Pohoda\ValueTransformer\SanitizeEncoding $sanitizeEncoding = new Pohoda\ValueTransformer\SanitizeEncoding(new Pohoda\ValueTransformer\Listing())
86
    )
87
    {
88 17
        $this->namespacesPaths = new Pohoda\Common\NamespacesPaths();
89 17
        $this->agendaFactory = new Pohoda\AgendaFactory($this->namespacesPaths, $this->sanitizeEncoding, $this->companyRegistrationNumber);
90
    }
91
92
    /**
93
     * Set the name of the application.
94
     *
95
     * @param string $name
96
     *
97
     * @return void
98
     */
99 1
    public function setApplicationName(string $name): void
100
    {
101 1
        $this->application = $name;
102
    }
103
104
    /**
105
     * Get class listing transformers for content serialization
106
     *
107
     * @return Pohoda\ValueTransformer\Listing
108
     */
109 2
    public function getTransformerListing(): Pohoda\ValueTransformer\Listing
110
    {
111 2
        return $this->sanitizeEncoding->getListing();
112
    }
113
114
    /**
115
     * Create and return instance of requested agenda.
116
     *
117
     * @param string              $name
118
     * @param array<string,mixed> $data
119
     *
120
     * @return AbstractAgenda
121
     */
122 3
    public function create(string $name, array $data = []): AbstractAgenda
123
    {
124 3
        return $this->agendaFactory->getAgenda($name, $data);
125
    }
126
127
    /**
128
     * Open new XML file for writing.
129
     *
130
     * @param string|null $filename path to output file or null for memory
131
     * @param string      $id
132
     * @param string      $note
133
     *
134
     * @return bool
135
     */
136 4
    public function open(?string $filename, string $id, string $note = ''): bool
137
    {
138 4
        $this->xmlWriter = new \XMLWriter();
139
140 4
        if (is_null($filename)) {
141 3
            $this->isInMemory = true;
142 3
            $this->xmlWriter->openMemory();
143
        } else {
144 1
            $this->isInMemory = false;
145
146 1
            if (!$this->xmlWriter->openUri($filename)) {
147
                // @codeCoverageIgnoreStart
148
                // I cannot test this, because it needs source file somewhere online
149
                return false;
150
            }
151
            // @codeCoverageIgnoreEnd
152
        }
153
154 4
        $this->xmlWriter->startDocument('1.0', $this->sanitizeEncoding->getEncoding());
155 4
        $this->xmlWriter->startElementNs('dat', 'dataPack', null);
156
157 4
        $this->xmlWriter->writeAttribute('id', $id);
158 4
        $this->xmlWriter->writeAttribute('ico', $this->companyRegistrationNumber);
159 4
        $this->xmlWriter->writeAttribute('application', $this->application);
160 4
        $this->xmlWriter->writeAttribute('version', '2.0');
161 4
        $this->xmlWriter->writeAttribute('note', $note);
162
163 4
        foreach ($this->namespacesPaths->allNamespaces() as $k => $v) {
164
            // put all known namespaces into base element attributes
165 4
            $this->xmlWriter->writeAttributeNs('xmlns', $k, null, $v);
166
        }
167
168 4
        return true;
169
    }
170
171
    /**
172
     * Add item.
173
     *
174
     * @param string $id
175
     * @param AbstractAgenda $agenda
176
     *
177
     * @return void
178
     */
179 4
    public function addItem(string $id, AbstractAgenda $agenda): void
180
    {
181 4
        $this->xmlWriter->startElementNs('dat', 'dataPackItem', null);
182
183 4
        $this->xmlWriter->writeAttribute('id', $id);
184 4
        $this->xmlWriter->writeAttribute('version', '2.0');
185 4
        $this->xmlWriter->writeRaw((string) $agenda->getXML()->asXML());
186 4
        $this->xmlWriter->endElement();
187
188 4
        if (!$this->isInMemory) {
189 1
            $this->xmlWriter->flush();
190
        }
191
    }
192
193
    /**
194
     * End and close XML file.
195
     *
196
     * @return int|string written bytes for file or XML string for memory
197
     */
198 8
    public function close(): int|string
199
    {
200 8
        $this->xmlWriter->endElement();
201
202 8
        return $this->xmlWriter->flush();
203
    }
204
205
    /**
206
     * Load XML file.
207
     *
208
     * @param string $name
209
     * @param string $filename
210
     *
211
     * @return bool
212
     */
213 3
    public function load(string $name, string $filename): bool
214
    {
215 3
        $this->xmlReader = new \XMLReader();
216
217 3
        if (!@$this->xmlReader->open($filename)) {
218 1
            return false;
219
        }
220
221 2
        $class = $this->agendaFactory->getAgenda($name, [], false);
222 2
        $this->elementName = $class->getImportRoot() ?? throw new \DomainException('Not allowed entity: ' . $name);
0 ignored issues
show
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...
223 2
        $this->importRecursive = $class->canImportRecursive();
224
225 2
        return true;
226
    }
227
228
    /**
229
     * Get next item in loaded file.
230
     *
231
     * @return \SimpleXMLElement|null
232
     */
233 2
    public function next(): ?\SimpleXMLElement
234
    {
235 2
        while (\XMLReader::ELEMENT != $this->xmlReader->nodeType || $this->xmlReader->name !== $this->elementName) {
236 2
            if (!$this->xmlReader->read()) {
237 2
                return null;
238
            }
239
        }
240
241 2
        $xml = new \SimpleXMLElement($this->xmlReader->readOuterXml());
242 2
        $this->importRecursive ? $this->xmlReader->next() : $this->xmlReader->read();
243
244 2
        return $xml;
245
    }
246
247
    /**
248
     * Handle dynamic method calls.
249
     *
250
     * @param string  $method
251
     * @param mixed[] $arguments
252
     *
253
     * @return mixed
254
     */
255 5
    public function __call(string $method, array $arguments)
256
    {
257
        // create<Agenda> method
258 5
        if (\preg_match('/create([A-Z][a-zA-Z0-9]*)/', $method, $matches)) {
259 1
            return \call_user_func([$this, 'create'], $matches[1], $arguments[0] ?? []);
260
        }
261
262
        // load<Agenda> method
263 4
        if (\preg_match('/load([A-Z][a-zA-Z0-9]*)/', $method, $matches)) {
264 3
            if (!isset($arguments[0])) {
265 1
                throw new \DomainException('Filename not set.');
266
            }
267
268 2
            return \call_user_func([$this, 'load'], $matches[1], $arguments[0]);
269
        }
270
271 1
        throw new \BadMethodCallException('Unknown method: ' . $method);
272
    }
273
}
274