Passed
Pull Request — master (#1)
by Silvan
06:17
created

NovaSearchServicesMethod::searchServices()   A

Complexity

Conditions 2
Paths 4

Size

Total Lines 19
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 2.0438

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 9
c 1
b 0
f 0
nc 4
nop 1
dl 0
loc 19
ccs 7
cts 9
cp 0.7778
crap 2.0438
rs 9.9666
1
<?php
2
3
namespace OrcaServices\NovaApi\Method;
4
5
use DOMDocument;
6
use DOMElement;
7
use Exception;
8
use OrcaServices\NovaApi\Parameter\NovaSearchServicesParameter;
9
use OrcaServices\NovaApi\Parser\NovaApiErrorParser;
10
use OrcaServices\NovaApi\Parser\NovaMessageParser;
11
use OrcaServices\NovaApi\Result\NovaSearchServicesResult;
12
use OrcaServices\NovaApi\Result\NovaService;
13
use OrcaServices\NovaApi\Soap\NovaApiSoapAction;
14
use OrcaServices\NovaApi\Xml\XmlDocument;
15
16
/**
17
 * SOAP method.
18
 */
19
final class NovaSearchServicesMethod implements NovaMethod
20
{
21
    /**
22
     * @var NovaApiSoapAction
23
     */
24
    private $novaSoapAction;
25
26
    /**
27
     * @var NovaApiErrorParser
28
     */
29
    private $novaErrorParser;
30
31
    /**
32
     * @var NovaMessageParser
33
     */
34
    private $novaMessageParser;
35
36
    /**
37
     * NovaSearchPartnerMethod constructor.
38
     *
39
     * @param NovaApiSoapAction $novaSoapAction The novaSoapAction
40
     * @param NovaApiErrorParser $novaErrorParser The novaErrorParser
41
     * @param NovaMessageParser $novaMessageParser The message parser
42
     */
43 10
    public function __construct(
44
        NovaApiSoapAction $novaSoapAction,
45
        NovaApiErrorParser $novaErrorParser,
46
        NovaMessageParser $novaMessageParser
47
    ) {
48 10
        $this->novaSoapAction = $novaSoapAction;
49 10
        $this->novaErrorParser = $novaErrorParser;
50 10
        $this->novaMessageParser = $novaMessageParser;
51 10
    }
52
53
    /**
54
     * Search NOVA services (customer) for a customer.
55
     *
56
     * https://confluence-ext.sbb.ch/display/NOVAUG/sucheLeistungen
57
     *
58
     * @param NovaSearchServicesParameter $parameter The parameters
59
     *
60
     * @return NovaSearchServicesResult the services matching the search parameter
61
     * @throws Exception if an error occurs
62
     *
63
     */
64 1
    public function searchServices(NovaSearchServicesParameter $parameter): NovaSearchServicesResult
65
    {
66
        // The SOAP endpoint url
67
        // https://echo-api.3scale.net/novagp/geschaeftspartner/public/MAJOR.MINOR/GeschaeftspartnerService
68 1
        $url = $this->novaSoapAction->getNovaSalesServiceUrl();
69
70
        // The SOAP action (http header)
71 1
        $soapAction = $this->novaSoapAction->getSoapAction('geschaeftspartner', 'sucheLeistungen');
72
73
        // The SOAP content (http body)
74 1
        $body = $this->createRequestBody($parameter);
75
76
        try {
77 1
            $xmlContent = $this->novaSoapAction->invokeSoapRequest($url, $soapAction, $body);
78 1
            $xml = XmlDocument::createFromXmlString($xmlContent);
79
80 1
            return $this->createResult($xml);
81
        } catch (Exception $exception) {
82
            throw $this->novaErrorParser->createGeneralException($exception);
83
        }
84
    }
85
86
    /**
87
     * Create SOAP body XML content.
88
     *
89
     * @param NovaSearchServicesParameter $parameter The parameters
90
     *
91
     * @return string The xml content
92
     */
93 1
    private function createRequestBody(NovaSearchServicesParameter $parameter): string
94
    {
95 1
        $dom = new DOMDocument('1.0', 'utf-8');
96 1
        $dom->formatOutput = true;
97
98 1
        $dom->appendChild($dom->createComment(' powered by Barakuda '));
99
100 1
        $envelope = $dom->createElement('soapenv:Envelope');
101 1
        $dom->appendChild($envelope);
102 1
        $envelope->setAttribute('xmlns:soapenv', 'http://schemas.xmlsoap.org/soap/envelope/');
103
104 1
        $soapHeader = $dom->createElement('soapenv:Header');
105 1
        $envelope->appendChild($soapHeader);
106
107 1
        $body = $dom->createElement('soapenv:Body');
108 1
        $envelope->appendChild($body);
109
110 1
        $method = $dom->createElement('sucheLeistungen');
111 1
        $body->appendChild($method);
112
113 1
        $searchQuery = $dom->createElement('leistungsSuchRequest');
114 1
        $this->novaSoapAction->appendDomClientIdentifier($dom, $searchQuery, $parameter, '');
115 1
        $this->novaSoapAction->appendDomCorrelationContext($dom, $searchQuery, $parameter, '');
116
117 1
        $service = $dom->createElement('leistung');
118 1
        $tkid = $dom->createElement('tkid');
119 1
        $tkid->appendChild($dom->createTextNode($parameter->tkId));
120 1
        $service->appendChild($tkid);
121 1
        $searchQuery->appendChild($service);
122 1
        $method->appendChild($searchQuery);
123
124 1
        $this->novaSoapAction->appendMethodNamespaces($method);
125
126 1
        return (string)$dom->saveXML();
127
    }
128
129
    /**
130
     * Create result object.
131
     *
132
     * @param XmlDocument $xml The xml document
133
     *
134
     * @return NovaSearchServicesResult The mapped result
135
     */
136 1
    private function createResult(XmlDocument $xml): NovaSearchServicesResult
137
    {
138 1
        $result = new NovaSearchServicesResult();
139
140 1
        $xml = $xml->withoutNamespaces();
141
142
        // Find and append all messages
143 1
        foreach ($this->novaMessageParser->findNovaMessages($xml) as $message) {
144
            $result->addMessage($message);
145
        }
146
147
        // Root node
148 1
        $responseNode = $xml->queryFirstNode('/Envelope/Body/sucheLeistungenResponse/leistungsSuchResponse');
149 1
        $serviceNodes = $xml->queryNodes('leistungsSuchErgebnis/leistung', $responseNode);
150
151
        /** @var DOMElement $serviceNode */
152 1
        foreach ($serviceNodes as $serviceNode) {
153 1
            $result->addService($this->createService($serviceNode, $xml));
154
        }
155
156 1
        return $result;
157
    }
158
159
    /**
160
     * Map partner node to NovaPartner object.
161
     *
162
     * @param DOMElement $serviceNode The partnerNode
163
     * @param XmlDocument $xml The xml document
164
     *
165
     * @return NovaService The new NovaService instance
166
     */
167 1
    private function createService(DOMElement $serviceNode, XmlDocument $xml): NovaService
168
    {
169 1
        $service = new NovaService();
170
171 1
        $service->tkId = $xml->findNodeValue('verkaufsParameter/wert/tkid', $serviceNode);
172 1
        $service->validFrom = $xml->createChronosFromXsDateTime(
173 1
            $xml->findAttributeValue('nutzungsInfo/nutzungsZeitraum/tarifierbarerZeitraum/@von', $serviceNode)
0 ignored issues
show
Bug introduced by
It seems like $xml->findAttributeValue...um/@von', $serviceNode) can also be of type null; however, parameter $dateTime of OrcaServices\NovaApi\Xml...ChronosFromXsDateTime() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

173
            /** @scrutinizer ignore-type */ $xml->findAttributeValue('nutzungsInfo/nutzungsZeitraum/tarifierbarerZeitraum/@von', $serviceNode)
Loading history...
174
        );
175 1
        $service->validTo = $xml->createChronosFromXsDateTime(
176 1
            $xml->findAttributeValue('nutzungsInfo/nutzungsZeitraum/tarifierbarerZeitraum/@bis', $serviceNode)
177
        );
178
179 1
        $service->productNumber = $xml->findAttributeValue('@produktNummer', $serviceNode);
180
181 1
        $allZones = $xml->findAttributeValue('geltungsBereich/zonenGeltungsBereich/zonenBuendel/@alleZonen', $serviceNode) === 'true';
182
183 1
        if ($allZones) {
184 1
            $service->zones[] = 'all';
185
186 1
            return $service;
187
        }
188
189 1
        foreach ($xml->queryNodes('geltungsBereich/zonenGeltungsBereich/zonenBuendel/zonen', $serviceNode) as $zone) {
190 1
            $service->zones[] = $xml->findNodeValue('code', $zone);
191
        }
192
193 1
        return $service;
194
    }
195
}
196