NovaSearchPartnerMethod::createRequestBody()   A
last analyzed

Complexity

Conditions 2
Paths 1

Size

Total Lines 51
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 35
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 34
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 51
ccs 35
cts 35
cp 1
crap 2
rs 9.376

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace OrcaServices\NovaApi\Method;
4
5
use Cake\Chronos\Chronos;
6
use DOMDocument;
7
use DOMElement;
8
use Exception;
9
use OrcaServices\NovaApi\Parameter\NovaSearchPartnerParameter;
10
use OrcaServices\NovaApi\Parser\NovaApiErrorParser;
11
use OrcaServices\NovaApi\Parser\NovaMessageParser;
12
use OrcaServices\NovaApi\Result\NovaPartner;
13
use OrcaServices\NovaApi\Result\NovaSearchPartnerResult;
14
use OrcaServices\NovaApi\Soap\NovaApiSoapAction;
15
use OrcaServices\NovaApi\Soap\NovaParameterMap;
16
use OrcaServices\NovaApi\Soap\NovaParameterWriter;
17
use OrcaServices\NovaApi\Type\GenderType;
18
use OrcaServices\NovaApi\Xml\XmlDocument;
19
20
/**
21
 * SOAP method.
22
 */
23
final class NovaSearchPartnerMethod implements NovaMethod
24
{
25
    /**
26
     * @var NovaApiSoapAction
27
     */
28
    private $novaSoapAction;
29
30
    /**
31
     * @var NovaApiErrorParser
32
     */
33
    private $novaErrorParser;
34
35
    /**
36
     * @var NovaMessageParser
37
     */
38
    private $novaMessageParser;
39
40
    /**
41
     * NovaSearchPartnerMethod constructor.
42
     *
43
     * @param NovaApiSoapAction $novaSoapAction The novaSoapAction
44
     * @param NovaApiErrorParser $novaErrorParser The novaErrorParser
45
     * @param NovaMessageParser $novaMessageParser The message parser
46
     */
47 13
    public function __construct(
48
        NovaApiSoapAction $novaSoapAction,
49
        NovaApiErrorParser $novaErrorParser,
50
        NovaMessageParser $novaMessageParser
51
    ) {
52 13
        $this->novaSoapAction = $novaSoapAction;
53 13
        $this->novaErrorParser = $novaErrorParser;
54 13
        $this->novaMessageParser = $novaMessageParser;
55 13
    }
56
57
    /**
58
     * Search a NOVA partner (customer).
59
     *
60
     * https://confluence-ext.sbb.ch/display/NOVAUG/suchePartner
61
     *
62
     * @param NovaSearchPartnerParameter $parameter The parameters
63
     *
64
     * @throws Exception
65
     *
66
     * @return NovaSearchPartnerResult The partners matching the search parameter
67
     */
68 3
    public function searchPartner(NovaSearchPartnerParameter $parameter): NovaSearchPartnerResult
69
    {
70
        // The SOAP endpoint url
71
        // https://echo-api.3scale.net/novagp/geschaeftspartner/public/MAJOR.MINOR/GeschaeftspartnerService
72 3
        $url = $this->novaSoapAction->getNovaBusinessPartnerServiceUrl();
73
74
        // The SOAP action (http header)
75 3
        $soapAction = $this->novaSoapAction->getSoapAction('geschaeftspartner', 'suchePartner');
76
77
        // The SOAP content (http body)
78 3
        $body = $this->createRequestBody($parameter);
79
80
        try {
81 3
            $xmlContent = $this->novaSoapAction->invokeSoapRequest($url, $soapAction, $body);
82 3
            $xml = XmlDocument::createFromXmlString($xmlContent);
83
84 3
            return $this->createResult($xml);
85
        } catch (Exception $exception) {
86
            throw $this->novaErrorParser->createGeneralException($exception);
87
        }
88
    }
89
90
    /**
91
     * Create SOAP body XML content.
92
     *
93
     * @param NovaSearchPartnerParameter $parameter The parameters
94
     *
95
     * @return string The xml content
96
     */
97 3
    private function createRequestBody(NovaSearchPartnerParameter $parameter): string
98
    {
99 3
        $dom = new DOMDocument('1.0', 'utf-8');
100 3
        $dom->formatOutput = true;
101
102 3
        $dom->appendChild($dom->createComment(' powered by Barakuda '));
103
104 3
        $envelope = $dom->createElement('soapenv:Envelope');
105 3
        $dom->appendChild($envelope);
106 3
        $envelope->setAttribute('xmlns:soapenv', 'http://schemas.xmlsoap.org/soap/envelope/');
107
108 3
        $soapHeader = $dom->createElement('soapenv:Header');
109 3
        $envelope->appendChild($soapHeader);
110
111 3
        $body = $dom->createElement('soapenv:Body');
112 3
        $envelope->appendChild($body);
113
114 3
        $method = $dom->createElement('novagp:suchePartner');
115 3
        $body->appendChild($method);
116
117 3
        $this->novaSoapAction->appendMethodNamespaces($method);
118 3
        $this->novaSoapAction->appendDomClientIdentifier($dom, $method, $parameter, 'novagp:');
119 3
        $this->novaSoapAction->appendDomCorrelationContext($dom, $method, $parameter, 'novagp:');
120
121 3
        $partnerSearchParameter = $dom->createElement('novagp:partnerSuchParameter');
122 3
        $method->appendChild($partnerSearchParameter);
123
124 3
        $parameterWriter = new NovaParameterWriter($dom, $partnerSearchParameter);
125
126 3
        $parameterWriter->appendToDocument(
127 3
            new NovaParameterMap(
128
                [
129 3
                    'tkid' => $parameter->tkId,
130 3
                    'grundkartenNummer' => $parameter->cardNumber,
131 3
                    'ckm' => $parameter->ckm,
132 3
                    'name' => $parameter->lastName,
133 3
                    'vorname' => $parameter->firstName,
134 3
                    'mail' => $parameter->mail,
135 3
                    'land' => $parameter->country,
136 3
                    'ort' => $parameter->city,
137 3
                    'plz' => $parameter->postalCode,
138 3
                    'strasseHnr' => $parameter->street,
139 3
                    'geburtsDatum' => $parameter->dateOfBirth ? $parameter->dateOfBirth->format('Y-m-d') : null,
140
                ]
141
            )
142
        );
143
144 3
        $pagingElement = $dom->createElement('novagp:pagingParameter');
145 3
        $partnerSearchParameter->appendChild($pagingElement);
146
147 3
        return (string)$dom->saveXML();
148
    }
149
150
    /**
151
     * Create result object.
152
     *
153
     * @param XmlDocument $xml The xml document
154
     *
155
     * @return NovaSearchPartnerResult The mapped result
156
     */
157 3
    private function createResult(XmlDocument $xml): NovaSearchPartnerResult
158
    {
159 3
        $result = new NovaSearchPartnerResult();
160
161 3
        $xml = $xml->withoutNamespaces();
162
163
        // Find and append all messages
164 3
        foreach ($this->novaMessageParser->findNovaMessages($xml) as $message) {
165
            $result->addMessage($message);
166
        }
167
168
        // Root node
169 3
        $responseNode = $xml->queryFirstNode('/Envelope/Body/suchePartnerResponse');
170 3
        $partnerNodes = $xml->queryNodes('partner', $responseNode);
171
172
        /** @var DOMElement $partnerNode */
173 3
        foreach ($partnerNodes as $partnerNode) {
174 3
            $result->partners[] = $this->createPartner($partnerNode, $xml);
175
        }
176
177 3
        return $result;
178
    }
179
180
    /**
181
     * Map partner node to NovaPartner object.
182
     *
183
     * @param DOMElement $partnerNode The partnerNode
184
     * @param XmlDocument $xml The xml document
185
     *
186
     * @return NovaPartner The new NovaPartner instance
187
     */
188 3
    private function createPartner(DOMElement $partnerNode, XmlDocument $xml): NovaPartner
189
    {
190 3
        $partner = new NovaPartner();
191
192 3
        $partner->tkId = $xml->getAttributeValue('@tkid', $partnerNode);
193 3
        $partner->ckm = $xml->findAttributeValue('@ckm', $partnerNode);
194 3
        $partner->cardNumber = $xml->findAttributeValue('@grundkartenNummer', $partnerNode);
195
196 3
        $changeDate = $xml->findAttributeValue('@mutDatum', $partnerNode);
197 3
        if ($changeDate !== null) {
198 3
            $partner->changedAt = $xml->createChronosFromXsDateTime($changeDate);
199
        }
200
201 3
        $partner->lastName = $xml->findAttributeValue('name/@name', $partnerNode);
202 3
        $partner->firstName = $xml->findAttributeValue('name/@vorname', $partnerNode);
203 3
        $partner->title = $xml->findAttributeValue('@titel', $partnerNode);
204
205 3
        $deceased = $xml->findAttributeValue('@verstorben', $partnerNode);
206 3
        if ($deceased !== null) {
207 3
            $partner->deceased = $deceased === 'false' ? 0 : 1;
208
        }
209
210
        // Date of birth can be empty sometimes
211 3
        $dateOfBirth = $xml->findAttributeValue('@geburtsDatum', $partnerNode);
212 3
        if ($dateOfBirth) {
213 3
            $dateOfBirth = Chronos::createFromFormat('Y-m-d', $dateOfBirth)->setTime(0, 0);
214 3
            $partner->dateOfBirth = $dateOfBirth;
215
        }
216
217 3
        $gender = $xml->findAttributeValue('@geschlecht', $partnerNode);
218 3
        $genderTypeId = $gender === 'MAENNLICH' ? GenderType::MEN : GenderType::WOMEN;
219 3
        $partner->genderTypeId = $genderTypeId;
220
221
        // Address
222 3
        $addressNodes = $xml->queryNodes('sitz/adresse', $partnerNode);
223
224
        // Could be empty, one, or more then one address: postal addresse, communication address etc.
225 3
        if ($addressNodes->length >= 1) {
226 3
            $addressNode = $xml->getFirstNode($addressNodes);
227
228 3
            $country = $xml->findAttributeValue('@land', $addressNode);
229 3
            $partner->country = $country;
230
231 3
            $city = $xml->findAttributeValue('@ort', $addressNode);
232 3
            $partner->city = $city;
233
234 3
            $postalCode = $xml->findAttributeValue('@plz', $addressNode);
235 3
            $partner->postalCode = $postalCode;
236
237 3
            $additional = $xml->findAttributeValue('@adressZusatz', $addressNode);
238 3
            if ($additional !== null) {
239
                $partner->additional = $additional;
240
            }
241
242 3
            $street = $xml->findAttributeValue('@strasseHnr', $addressNode);
243 3
            $partner->street = $street;
244
245 3
            $poBox = $xml->findAttributeValue('@postfach', $addressNode);
246 3
            if ($poBox !== null) {
247 3
                $partner->poBox = $poBox;
248
            }
249
        }
250
251
        // MOBIL, FESTNETZ or MAIL
252 3
        $phoneNumber = $xml->findAttributeValue('festnetz/@formatiertE123', $partnerNode);
253 3
        if ($phoneNumber !== null) {
254 3
            $partner->phoneNumber = str_replace(' ', '', $phoneNumber);
255
        }
256
257 3
        $mobileNumber = $xml->findAttributeValue('mobil/@formatiertE123', $partnerNode);
258 3
        if ($mobileNumber !== null) {
259 3
            $partner->mobileNumber = str_replace(' ', '', $mobileNumber);
260
        }
261
262 3
        $email = $xml->findAttributeValue('@email', $partnerNode);
263 3
        if ($email && filter_var($email, FILTER_VALIDATE_EMAIL) !== false) {
264 3
            $partner->email = $email;
265
        }
266
267 3
        return $partner;
268
    }
269
}
270