Completed
Push — master ( ddc006...1cef55 )
by Milan
01:50
created

Ares::xmlValue()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 2
1
<?php declare(strict_types=1);
2
3
namespace h4kuna\Ares;
4
5
use h4kuna\Ares\Exceptions\ConnectionException;
6
use h4kuna\Ares\Exceptions\IdentificationNumberNotFoundException;
7
use h4kuna\Ares\Exceptions\UnexpectedXmlStructureException;
8
9
class Ares
10
{
11
12
	public const URL = 'https://wwwinfo.mfcr.cz/cgi-bin/ares/darv_bas.cgi';
13
14
	/** @var IFactory */
15
	private $factory;
16
17
	/** @var DataProvider */
18
	private $dataProvider;
19
20
21
	public function __construct(IFactory $factory = null)
22
	{
23
		if ($factory === null) {
24
			$factory = new Factory();
25
		}
26
		$this->factory = $factory;
27
	}
28
29
30
	/**
31
	 * Load fresh data.
32
	 * @throws IdentificationNumberNotFoundException
33
	 */
34
	public function loadData(string $in, array $options = []): Data
35
	{
36
		$this->loadXML($in, $options);
37
		return $this->getData();
38
	}
39
40
41
	/**
42
	 * Get temporary data.
43
	 */
44
	public function getData(): Data
45
	{
46
		return $this->getDataProvider()->getData();
47
	}
48
49
50
	/**
51
	 * Load XML and fill Data object
52
	 * @throws IdentificationNumberNotFoundException
53
	 */
54
	private function loadXML(string $in, array $options)
55
	{
56
		$client = $this->factory->createGuzzleClient($options);
57
		try {
58
			$xmlSource = $client->request('GET', $this->createUrl($in))->getBody()->getContents();
59
		} catch (\Throwable $e) {
60
			throw new ConnectionException($e->getMessage(), $e->getCode(), $e);
61
		}
62
		$xml = @simplexml_load_string($xmlSource);
63
		if (!$xml) {
64
			throw new ConnectionException();
65
		}
66
67
		$ns = $xml->getDocNamespaces();
68
		$answer = $xml->children($ns['are'])->children($ns['D']);
69
		$this->parseErrorAnswer($xml, $in);
70
		$this->processXml($answer->VBAS, $this->getDataProvider()->prepareData());
71
	}
72
73
74
	protected function processXml(\SimpleXMLElement $xml, DataProvider $dataProvider): void
75
	{
76
		$dataProvider->setIN((string) $xml->ICO)
77
			->setTIN((string) $xml->DIC)
78
			->setCompany((string) $xml->OF)
79
			->setZip(self::exists($xml->AA, 'PSC'))
80
			->setStreet(self::exists($xml->AA, 'NU'))
81
			->setCity(self::exists($xml->AA, 'N'))
82
			->setHouseNumber(self::exists($xml->AA, 'CD'), self::exists($xml->AA, 'CO'))
83
			->setCityPost(self::exists($xml->AA, 'NMC'))
84
			->setCityDistrict(self::exists($xml->AA, 'NCO'))
85
			->setIsPerson(self::exists($xml->PF, 'KPF'))
86
			->setCreated((string) $xml->DV)
87
			->setNace(self::existsArray($xml->Nace, 'NACE'));
88
89
		$dataProvider->setDissolved(isset($xml->DZ) ? (string) $xml->DZ : null);
90
91
		if (isset($xml->ROR)) {
92
			$dataProvider
93
				->setFileNumber((string) $xml->ROR->SZ->OV)
94
				->setCourt((string) $xml->ROR->SZ->SD->T);
95
		} else {
96
			$dataProvider
97
				->setFileNumber('')
98
				->setCourt('');
99
		}
100
	}
101
102
103
	private function createUrl(string $inn): string
104
	{
105
		$parameters = [
106
			'ico' => $inn,
107
			'aktivni' => 'false',
108
		];
109
		return self::URL . '?' . http_build_query($parameters);
110
	}
111
112
113
	private function getDataProvider(): DataProvider
114
	{
115
		if ($this->dataProvider === null) {
116
			$this->dataProvider = $this->factory->createDataProvider();
117
		}
118
		return $this->dataProvider;
119
	}
120
121
122
	private static function exists(\SimpleXMLElement $element, string $property): string
123
	{
124
		return isset($element->{$property}) ? ((string) $element->{$property}) : '';
125
	}
126
	
127
	
128
	private static function existsArray(\SimpleXMLElement $element, string $property): array
129
	{
130
		return isset($element->{$property}) ? ((array) $element->{$property}) : [];
131
	}
132
133
134
	private function parseErrorAnswer(\SimpleXMLElement $answer, string $in): void
135
	{
136
		$errorMessage = self::xmlValue($answer, '//D:ET[1]');
137
		$errorCode = self::xmlValue($answer, '//D:EK[1]');
138
		if ($errorMessage === null && $errorCode === null) {
139
			return;
140
		}
141
142
		// 61 - subject disappeared
143
		// 71 - not exists
144
		if (empty($errorMessage)) {
145
			throw new ConnectionException();
146
		}
147
		throw new IdentificationNumberNotFoundException(sprintf('IN "%s". %s', $in, $errorMessage), (int) $errorCode);
148
	}
149
150
151
	private static function xmlValue(\SimpleXMLElement $xml, string $xpath): ?string
152
	{
153
		$result = $xml->xpath($xpath);
154
		if ($result === []) {
155
			return null;
156
		}
157
		return trim((string) $result[0]);
158
	}
159
160
}
161