Completed
Branch master (ff989f)
by Dennis
01:07
created

Ares::setBalancer()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 6
ccs 0
cts 5
cp 0
rs 9.4285
cc 1
eloc 3
nc 1
nop 1
crap 2
1
<?php
2
3
namespace Defr;
4
5
use Defr\Ares\AresException;
6
use Defr\Ares\AresRecord;
7
use Defr\Ares\AresRecords;
8
use Defr\Ares\TaxRecord;
9
use InvalidArgumentException;
10
11
/**
12
 * Class Ares.
13
 *
14
 * @author Dennis Fridrich <[email protected]>
15
 */
16
class Ares
17
{
18
    const URL_BAS = 'http://wwwinfo.mfcr.cz/cgi-bin/ares/darv_bas.cgi?ico=%s';
19
    const URL_RES = 'http://wwwinfo.mfcr.cz/cgi-bin/ares/darv_res.cgi?ICO=%s';
20
    const URL_TAX = 'http://wwwinfo.mfcr.cz/cgi-bin/ares/ares_es.cgi?ico=%s&filtr=0';
21
    const URL_FIND = 'http://wwwinfo.mfcr.cz/cgi-bin/ares/ares_es.cgi?obch_jm=%s&obec=%s&filtr=0';
22
23
    /**
24
     * @var string
25
     */
26
    private $cacheStrategy = 'YW';
27
28
    /**
29
     * @var string
30
     */
31
    private $cacheDir = null;
32
33
    /**
34
     * @var bool
35
     */
36
    private $debug;
37
38
    /**
39
     * @var string
40
     */
41
    private $balancer = null;
42
43
    /**
44
     * @var array
45
     */
46
    private $contextOptions = [
47
        'ssl' => [
48
            'verify_peer' => false,
49
            'verify_peer_name' => false,
50
        ],
51
    ];
52
53
    /**
54
     * @var string
55
     */
56
    private $lastUrl;
57
58
    /**
59
     * @param null $cacheDir
60
     * @param bool $debug
61
     */
62
    public function __construct($cacheDir = null, $debug = false, $balancer = null)
63
    {
64
        if (null === $cacheDir) {
65
            $cacheDir = sys_get_temp_dir();
66
        }
67
68
        if (null !== $balancer) {
69
            $this->balancer = $balancer;
70
        }
71
72
        $this->cacheDir = $cacheDir.'/defr/ares';
73
        $this->debug = $debug;
74
75
        // Create cache dirs if they doesn't exist
76
        if (!is_dir($this->cacheDir)) {
77
            mkdir($this->cacheDir, 0777, true);
78
        }
79
    }
80
81
    /**
82
     * @param $balancer
83
     *
84
     * @return $this
85
     */
86
    public function setBalancer($balancer)
87
    {
88
        $this->balancer = $balancer;
89
90
        return $this;
91
    }
92
93
    /**
94
     * @param $url
95
     *
96
     * @return mixed
97
     */
98
    private function wrapUrl($url)
99
    {
100
        if ($this->balancer) {
101
            $url = sprintf('%s?url=%s', $this->balancer, urlencode($url));
102
        }
103
104
        $this->lastUrl = $url;
105
106
        return $url;
107
    }
108
109
    /**
110
     * @return string
111
     */
112
    public function getLastUrl()
113
    {
114
        return $this->lastUrl;
115
    }
116
117
    /**
118
     * @param $id
119
     *
120
     * @throws InvalidArgumentException
121
     * @throws Ares\AresException
122
     *
123
     * @return AresRecord
124
     */
125
    public function findByIdentificationNumber($id)
126
    {
127
        $id = Lib::toInteger($id);
128
        $this->ensureIdIsInteger($id);
129
130
        $cachedFileName = $id.'_'.date($this->cacheStrategy).'.php';
131
        $cachedFile = $this->cacheDir.'/bas_'.$cachedFileName;
132
        $cachedRawFile = $this->cacheDir.'/bas_raw_'.$cachedFileName;
133
134
        if (is_file($cachedFile)) {
135
            return unserialize(file_get_contents($cachedFile));
136
        }
137
138
        // Sestaveni URL
139
        $url = $this->wrapUrl(sprintf(self::URL_BAS, $id));
140
141
        try {
142
            $aresRequest = file_get_contents($url, null, stream_context_create($this->contextOptions));
143
            if ($this->debug) {
144
                file_put_contents($cachedRawFile, $aresRequest);
145
            }
146
            $aresResponse = simplexml_load_string($aresRequest);
147
148
            if ($aresResponse) {
149
                $ns = $aresResponse->getDocNamespaces();
150
                $data = $aresResponse->children($ns['are']);
151
                $elements = $data->children($ns['D'])->VBAS;
0 ignored issues
show
Bug introduced by
The property VBAS does not seem to exist in SimpleXMLElement.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
152
153
                $ico = (int) $elements->ICO;
154
                if ($ico !== $id) {
155
                    throw new AresException('IČ firmy nebylo nalezeno.');
156
                }
157
158
                $record = new AresRecord();
159
160
                $record->setCompanyId($id);
161
                $record->setTaxId(strval($elements->DIC));
162
                $record->setCompanyName(strval($elements->OF));
163
                $record->setStreet(strval($elements->AA->NU));
164
165
                if (strval($elements->AA->CO)) {
166
                    $record->setStreetHouseNumber(strval($elements->AA->CD));
167
                    $record->setStreetOrientationNumber(strval($elements->AA->CO));
168
                } else {
169
                    $record->setStreetHouseNumber(strval($elements->AA->CD));
170
                }
171
                
172
                if (strval($elements->AA->N) == "Praha") { //Praha
173
                    $record->setTown(strval($elements->AA->NMC) ." - ". strval($elements->AA->NCO));
174
                } elseif(strval($elements->AA->NCO) != strval($elements->AA->N)) { //Ostrava
175
                    $record->setTown(strval($elements->AA->N) ." - ". strval($elements->AA->NCO));
176
                } else {
177
                    $record->setTown(strval($elements->AA->N));
178
                }
179
180
                $record->setZip(strval($elements->AA->PSC));
181
            } else {
182
                throw new AresException('Databáze ARES není dostupná.');
183
            }
184
        } catch (\Exception $e) {
185
            throw new AresException($e->getMessage());
186
        }
187
188
        file_put_contents($cachedFile, serialize($record));
189
190
        return $record;
191
    }
192
193
    /**
194
     * @param $id
195
     *
196
     * @throws InvalidArgumentException
197
     * @throws Ares\AresException
198
     *
199
     * @return AresRecord
200
     */
201
    public function findInResById($id)
202
    {
203
        $id = Lib::toInteger($id);
204
        $this->ensureIdIsInteger($id);
205
206
        // Sestaveni URL
207
        $url = $this->wrapUrl(sprintf(self::URL_RES, $id));
208
209
        $cachedFileName = $id.'_'.date($this->cacheStrategy).'.php';
210
        $cachedFile = $this->cacheDir.'/res_'.$cachedFileName;
211
        $cachedRawFile = $this->cacheDir.'/res_raw_'.$cachedFileName;
212
213
        if (is_file($cachedFile)) {
214
            return unserialize(file_get_contents($cachedFile));
215
        }
216
217
        try {
218
            $aresRequest = file_get_contents($url, null, stream_context_create($this->contextOptions));
219
            if ($this->debug) {
220
                file_put_contents($cachedRawFile, $aresRequest);
221
            }
222
            $aresResponse = simplexml_load_string($aresRequest);
223
224
            if ($aresResponse) {
225
                $ns = $aresResponse->getDocNamespaces();
226
                $data = $aresResponse->children($ns['are']);
227
                $elements = $data->children($ns['D'])->Vypis_RES;
0 ignored issues
show
Bug introduced by
The property Vypis_RES does not seem to exist in SimpleXMLElement.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
228
229
                if (strval($elements->ZAU->ICO) === $id) {
0 ignored issues
show
Unused Code Bug introduced by
The strict comparison === seems to always evaluate to false as the types of strval($elements->ZAU->ICO) (string) and $id (integer) can never be identical. Maybe you want to use a loose comparison == instead?
Loading history...
230
                    $record = new AresRecord();
231
                    $record->setCompanyId(strval($id));
232
                    $record->setTaxId($this->findVatById($id));
233
                    $record->setCompanyName(strval($elements->ZAU->OF));
234
                    $record->setStreet(strval($elements->SI->NU));
235
                    $record->setStreetHouseNumber(strval($elements->SI->CD));
236
                    $record->setStreetOrientationNumber(strval($elements->SI->CO));
237
                    $record->setTown(strval($elements->SI->N));
238
                    $record->setZip(strval($elements->SI->PSC));
239
                } else {
240
                    throw new AresException('IČ firmy nebylo nalezeno.');
241
                }
242
            } else {
243
                throw new AresException('Databáze ARES není dostupná.');
244
            }
245
        } catch (\Exception $e) {
246
            throw new AresException($e->getMessage());
247
        }
248
        file_put_contents($cachedFile, serialize($record));
249
250
        return $record;
251
    }
252
253
    /**
254
     * @param $id
255
     *
256
     * @throws InvalidArgumentException
257
     * @throws \Exception
258
     *
259
     * @return TaxRecord|mixed
260
     */
261
    public function findVatById($id)
262
    {
263
        $id = Lib::toInteger($id);
264
265
        $this->ensureIdIsInteger($id);
266
267
        // Sestaveni URL
268
        $url = $this->wrapUrl(sprintf(self::URL_TAX, $id));
269
270
        $cachedFileName = $id.'_'.date($this->cacheStrategy).'.php';
271
        $cachedFile = $this->cacheDir.'/tax_'.$cachedFileName;
272
        $cachedRawFile = $this->cacheDir.'/tax_raw_'.$cachedFileName;
273
274
        if (is_file($cachedFile)) {
275
            return unserialize(file_get_contents($cachedFile));
276
        }
277
278
        try {
279
            $vatRequest = file_get_contents($url, null, stream_context_create($this->contextOptions));
280
            if ($this->debug) {
281
                file_put_contents($cachedRawFile, $vatRequest);
282
            }
283
            $vatResponse = simplexml_load_string($vatRequest);
284
285
            if ($vatResponse) {
286
                $record = new TaxRecord();
0 ignored issues
show
Bug introduced by
The call to TaxRecord::__construct() misses a required argument $taxId.

This check looks for function calls that miss required arguments.

Loading history...
287
                $ns = $vatResponse->getDocNamespaces();
288
                $data = $vatResponse->children($ns['are']);
289
                $elements = $data->children($ns['dtt'])->V->S;
290
291
                if (strval($elements->ico) === $id) {
0 ignored issues
show
Unused Code Bug introduced by
The strict comparison === seems to always evaluate to false as the types of strval($elements->ico) (string) and $id (integer) can never be identical. Maybe you want to use a loose comparison == instead?
Loading history...
292
                    $record->setTaxId(str_replace('dic=', 'CZ', strval($elements->p_dph)));
0 ignored issues
show
Bug introduced by
The method setTaxId() does not seem to exist on object<Defr\Ares\TaxRecord>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
293
                } else {
294
                    throw new AresException('DIČ firmy nebylo nalezeno.');
295
                }
296
            } else {
297
                throw new AresException('Databáze MFČR není dostupná.');
298
            }
299
        } catch (\Exception $e) {
300
            throw new \Exception($e->getMessage());
301
        }
302
        file_put_contents($cachedFile, serialize($record));
303
304
        return $record;
305
    }
306
307
    /**
308
     * @param $name
309
     * @param null $city
310
     *
311
     * @throws InvalidArgumentException
312
     * @throws \Exception
313
     *
314
     * @return array|AresRecord[]|AresRecords
315
     */
316
    public function findByName($name, $city = null)
317
    {
318
        if (strlen($name) < 3) {
319
            throw new InvalidArgumentException('Zadejte minimálně 3 znaky pro hledání.');
320
        }
321
322
        $url = $this->wrapUrl(sprintf(
323
            self::URL_FIND,
324
            urlencode(Lib::stripDiacritics($name)),
325
            urlencode(Lib::stripDiacritics($city))
326
        ));
327
328
        $cachedFileName = date($this->cacheStrategy).'_'.md5($name.$city).'.php';
329
        $cachedFile = $this->cacheDir.'/find_'.$cachedFileName;
330
        $cachedRawFile = $this->cacheDir.'/find_raw_'.$cachedFileName;
331
332
        if (is_file($cachedFile)) {
333
            return unserialize(file_get_contents($cachedFile));
334
        }
335
336
        $aresRequest = file_get_contents($url, null, stream_context_create($this->contextOptions));
337
        if ($this->debug) {
338
            file_put_contents($cachedRawFile, $aresRequest);
339
        }
340
        $aresResponse = simplexml_load_string($aresRequest);
341
        if (!$aresResponse) {
342
            throw new AresException('Databáze ARES není dostupná.');
343
        }
344
345
        $ns = $aresResponse->getDocNamespaces();
346
        $data = $aresResponse->children($ns['are']);
347
        $elements = $data->children($ns['dtt'])->V->S;
348
349
        if (!count($elements)) {
350
            throw new AresException('Nic nebylo nalezeno.');
351
        }
352
353
        $records = new AresRecords();
354
        foreach ($elements as $element) {
355
            $record = new AresRecord();
356
            $record->setCompanyId(strval($element->ico));
357
            $record->setTaxId(
358
                ($element->dph ? str_replace('dic=', 'CZ', strval($element->p_dph)) : '')
359
            );
360
            $record->setCompanyName(strval($element->ojm));
361
            //'adresa' => strval($element->jmn));
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
362
            $records[] = $record;
363
        }
364
        file_put_contents($cachedFile, serialize($records));
365
366
        return $records;
367
    }
368
369
    /**
370
     * @param string $cacheStrategy
371
     */
372
    public function setCacheStrategy($cacheStrategy)
373
    {
374
        $this->cacheStrategy = $cacheStrategy;
375
    }
376
377
    /**
378
     * @param bool $debug
379
     */
380
    public function setDebug($debug)
381
    {
382
        $this->debug = $debug;
383
    }
384
385
    /**
386
     * @param mixed $id
387
     */
388
    private function ensureIdIsInteger($id)
389
    {
390
        if (!is_int($id)) {
391
            throw new InvalidArgumentException('IČ firmy musí být číslo.');
392
        }
393
    }
394
}
395