Completed
Push — master ( dc2999...fcbf9e )
by Dennis
05:34
created

Ares::setBalancer()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 6
ccs 3
cts 3
cp 1
rs 9.4285
cc 1
eloc 3
nc 1
nop 1
crap 1
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 5
    public function __construct($cacheDir = null, $debug = false, $balancer = null)
63
    {
64 5
        if (null === $cacheDir) {
65 5
            $cacheDir = sys_get_temp_dir();
66 5
        }
67
68 5
        if (null !== $balancer) {
69
            $this->balancer = $balancer;
70
        }
71
72 5
        $this->cacheDir = $cacheDir.'/defr/ares';
73 5
        $this->debug = $debug;
74
75
        // Create cache dirs if they doesn't exist
76 5
        if (!is_dir($this->cacheDir)) {
77 1
            mkdir($this->cacheDir, 0777, true);
78 1
        }
79 5
    }
80
81
    /**
82
     * @param string $balancer
83
     *
84
     * @return $this
85
     */
86 1
    public function setBalancer($balancer)
87
    {
88 1
        $this->balancer = $balancer;
89
90 1
        return $this;
91
    }
92
93
    /**
94
     * @param string $url
95
     *
96
     * @return string
97
     */
98 3
    private function wrapUrl($url)
99
    {
100 3
        if ($this->balancer) {
101 1
            $url = sprintf('%s?url=%s', $this->balancer, urlencode($url));
102 1
        }
103
104 3
        $this->lastUrl = $url;
105
106 3
        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 5
    public function findByIdentificationNumber($id)
126
    {
127 5
        $id = Lib::toInteger($id);
128 5
        $this->ensureIdIsInteger($id);
129
130 5
        if (empty($id)) {
131 2
            throw new AresException('IČ firmy musí být zadáno.');
132
        }
133
134 3
        $cachedFileName = $id.'_'.date($this->cacheStrategy).'.php';
135 3
        $cachedFile = $this->cacheDir.'/bas_'.$cachedFileName;
136 3
        $cachedRawFile = $this->cacheDir.'/bas_raw_'.$cachedFileName;
137
138 3
        if (is_file($cachedFile)) {
139
            return unserialize(file_get_contents($cachedFile));
140
        }
141
142
        // Sestaveni URL
143 3
        $url = $this->wrapUrl(sprintf(self::URL_BAS, $id));
144
145
        try {
146 3
            $aresRequest = file_get_contents($url, null, stream_context_create($this->contextOptions));
147 2
            if ($this->debug) {
148
                file_put_contents($cachedRawFile, $aresRequest);
149
            }
150 2
            $aresResponse = simplexml_load_string($aresRequest);
151
152 2
            if ($aresResponse) {
153 2
                $ns = $aresResponse->getDocNamespaces();
154 2
                $data = $aresResponse->children($ns['are']);
155 2
                $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...
156
157 2
                $ico = (int) $elements->ICO;
158 2
                if ($ico !== $id) {
159
                    throw new AresException('IČ firmy nebylo nalezeno.');
160
                }
161
162 2
                $record = new AresRecord();
163
164 2
                $record->setCompanyId(strval($elements->ICO));
165 2
                $record->setTaxId(strval($elements->DIC));
166 2
                $record->setCompanyName(strval($elements->OF));
167 2
                $record->setStreet(strval($elements->AA->NU));
168
169 2
                if (strval($elements->AA->CO)) {
170 1
                    $record->setStreetHouseNumber(strval($elements->AA->CD));
171 1
                    $record->setStreetOrientationNumber(strval($elements->AA->CO));
172 1
                } else {
173 1
                    $record->setStreetHouseNumber(strval($elements->AA->CD));
174
                }
175
176 2
                if (strval($elements->AA->N) === 'Praha') { //Praha
177 1
                    $record->setTown(strval($elements->AA->NMC).' - '.strval($elements->AA->NCO));
178 2
                } elseif (strval($elements->AA->NCO) !== strval($elements->AA->N)) { //Ostrava
179 1
                    $record->setTown(strval($elements->AA->N).' - '.strval($elements->AA->NCO));
180 1
                } else {
181
                    $record->setTown(strval($elements->AA->N));
182
                }
183
184 2
                $record->setZip(strval($elements->AA->PSC));
185 2
            } else {
186
                throw new AresException('Databáze ARES není dostupná.');
187
            }
188 3
        } catch (\Exception $e) {
189 1
            throw new AresException($e->getMessage());
190
        }
191
192 2
        file_put_contents($cachedFile, serialize($record));
193
194 2
        return $record;
195
    }
196
197
    /**
198
     * @param $id
199
     *
200
     * @throws InvalidArgumentException
201
     * @throws Ares\AresException
202
     *
203
     * @return AresRecord
204
     */
205
    public function findInResById($id)
206
    {
207
        $id = Lib::toInteger($id);
208
        $this->ensureIdIsInteger($id);
209
210
        // Sestaveni URL
211
        $url = $this->wrapUrl(sprintf(self::URL_RES, $id));
212
213
        $cachedFileName = $id.'_'.date($this->cacheStrategy).'.php';
214
        $cachedFile = $this->cacheDir.'/res_'.$cachedFileName;
215
        $cachedRawFile = $this->cacheDir.'/res_raw_'.$cachedFileName;
216
217
        if (is_file($cachedFile)) {
218
            return unserialize(file_get_contents($cachedFile));
219
        }
220
221
        try {
222
            $aresRequest = file_get_contents($url, null, stream_context_create($this->contextOptions));
223
            if ($this->debug) {
224
                file_put_contents($cachedRawFile, $aresRequest);
225
            }
226
            $aresResponse = simplexml_load_string($aresRequest);
227
228
            if ($aresResponse) {
229
                $ns = $aresResponse->getDocNamespaces();
230
                $data = $aresResponse->children($ns['are']);
231
                $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...
232
233
                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...
234
                    $record = new AresRecord();
235
                    $record->setCompanyId(strval($id));
236
                    $record->setTaxId($this->findVatById($id));
237
                    $record->setCompanyName(strval($elements->ZAU->OF));
238
                    $record->setStreet(strval($elements->SI->NU));
239
                    $record->setStreetHouseNumber(strval($elements->SI->CD));
240
                    $record->setStreetOrientationNumber(strval($elements->SI->CO));
241
                    $record->setTown(strval($elements->SI->N));
242
                    $record->setZip(strval($elements->SI->PSC));
243
                } else {
244
                    throw new AresException('IČ firmy nebylo nalezeno.');
245
                }
246
            } else {
247
                throw new AresException('Databáze ARES není dostupná.');
248
            }
249
        } catch (\Exception $e) {
250
            throw new AresException($e->getMessage());
251
        }
252
        file_put_contents($cachedFile, serialize($record));
253
254
        return $record;
255
    }
256
257
    /**
258
     * @param $id
259
     *
260
     * @throws InvalidArgumentException
261
     * @throws \Exception
262
     *
263
     * @return string
264
     */
265
    public function findVatById($id)
266
    {
267
        $id = Lib::toInteger($id);
268
269
        $this->ensureIdIsInteger($id);
270
271
        // Sestaveni URL
272
        $url = $this->wrapUrl(sprintf(self::URL_TAX, $id));
273
274
        $cachedFileName = $id.'_'.date($this->cacheStrategy).'.php';
275
        $cachedFile = $this->cacheDir.'/tax_'.$cachedFileName;
276
        $cachedRawFile = $this->cacheDir.'/tax_raw_'.$cachedFileName;
277
278
        if (is_file($cachedFile)) {
279
            return unserialize(file_get_contents($cachedFile));
280
        }
281
282
        try {
283
            $vatRequest = file_get_contents($url, null, stream_context_create($this->contextOptions));
284
            if ($this->debug) {
285
                file_put_contents($cachedRawFile, $vatRequest);
286
            }
287
            $vatResponse = simplexml_load_string($vatRequest);
288
289
            if ($vatResponse) {
290
                $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...
291
                $ns = $vatResponse->getDocNamespaces();
292
                $data = $vatResponse->children($ns['are']);
293
                $elements = $data->children($ns['dtt'])->V->S;
294
295
                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...
296
                    $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...
297
                } else {
298
                    throw new AresException('DIČ firmy nebylo nalezeno.');
299
                }
300
            } else {
301
                throw new AresException('Databáze MFČR není dostupná.');
302
            }
303
        } catch (\Exception $e) {
304
            throw new \Exception($e->getMessage());
305
        }
306
        file_put_contents($cachedFile, serialize($record));
307
308
        return $record;
309
    }
310
311
    /**
312
     * @param $name
313
     * @param null $city
314
     *
315
     * @throws InvalidArgumentException
316
     * @throws \Exception
317
     *
318
     * @return array|AresRecord[]|AresRecords
319
     */
320
    public function findByName($name, $city = null)
321
    {
322
        if (strlen($name) < 3) {
323
            throw new InvalidArgumentException('Zadejte minimálně 3 znaky pro hledání.');
324
        }
325
326
        $url = $this->wrapUrl(sprintf(
327
            self::URL_FIND,
328
            urlencode(Lib::stripDiacritics($name)),
329
            urlencode(Lib::stripDiacritics($city))
330
        ));
331
332
        $cachedFileName = date($this->cacheStrategy).'_'.md5($name.$city).'.php';
333
        $cachedFile = $this->cacheDir.'/find_'.$cachedFileName;
334
        $cachedRawFile = $this->cacheDir.'/find_raw_'.$cachedFileName;
335
336
        if (is_file($cachedFile)) {
337
            return unserialize(file_get_contents($cachedFile));
338
        }
339
340
        $aresRequest = file_get_contents($url, null, stream_context_create($this->contextOptions));
341
        if ($this->debug) {
342
            file_put_contents($cachedRawFile, $aresRequest);
343
        }
344
        $aresResponse = simplexml_load_string($aresRequest);
345
        if (!$aresResponse) {
346
            throw new AresException('Databáze ARES není dostupná.');
347
        }
348
349
        $ns = $aresResponse->getDocNamespaces();
350
        $data = $aresResponse->children($ns['are']);
351
        $elements = $data->children($ns['dtt'])->V->S;
352
353
        if (!count($elements)) {
354
            throw new AresException('Nic nebylo nalezeno.');
355
        }
356
357
        $records = new AresRecords();
358
        foreach ($elements as $element) {
359
            $record = new AresRecord();
360
            $record->setCompanyId(strval($element->ico));
361
            $record->setTaxId(
362
                ($element->dph ? str_replace('dic=', 'CZ', strval($element->p_dph)) : '')
363
            );
364
            $record->setCompanyName(strval($element->ojm));
365
            //'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...
366
            $records[] = $record;
367
        }
368
        file_put_contents($cachedFile, serialize($records));
369
370
        return $records;
371
    }
372
373
    /**
374
     * @param string $cacheStrategy
375
     */
376
    public function setCacheStrategy($cacheStrategy)
377
    {
378
        $this->cacheStrategy = $cacheStrategy;
379
    }
380
381
    /**
382
     * @param bool $debug
383
     */
384
    public function setDebug($debug)
385
    {
386
        $this->debug = $debug;
387
    }
388
389
    /**
390
     * @param int $id
391
     */
392 5
    private function ensureIdIsInteger($id)
393
    {
394 5
        if (!is_int($id)) {
395
            throw new InvalidArgumentException('IČ firmy musí být číslo.');
396
        }
397 5
    }
398
}
399