Issues (112)

src/Bpack247.php (1 issue)

Severity
1
<?php
2
declare(strict_types=1);
3
4
namespace Bpost\BpostApiClient;
5
6
use Bpost\BpostApiClient\Bpack247\Customer;
7
use Bpost\BpostApiClient\Exception\BpostApiResponseException\BpostApiBusinessException;
8
use Bpost\BpostApiClient\Exception\BpostApiResponseException\BpostApiSystemException;
9
use Bpost\BpostApiClient\Exception\BpostApiResponseException\BpostCurlException;
10
use Bpost\BpostApiClient\Exception\BpostApiResponseException\BpostInvalidResponseException;
11
use DOMDocument;
12
use SimpleXMLElement;
13
use CurlHandle;
14
15
/**
16
 * bPost Bpack24/7 class
17
 *
18
 * @author    Tijs Verkoyen <[email protected]>
19
 *
20
 * @version   3.0.0
21
 *
22
 * @copyright Copyright (c), Tijs Verkoyen. All rights reserved.
23
 * @license   BSD License
24
 */
25
class Bpack247
26
{
27
    /** URL for the API */
28
    public const API_URL = 'http://www.bpack247.be/BpostRegistrationWebserviceREST/servicecontroller.svc';
29
30
    /** current version */
31
    public const VERSION = '3.0.0';
32
33
    private string $accountId;
34
    private string $passPhrase;
35
36
    /** * The port to use. */
37
    private ?int $port = null;
38
39
    /** Timeout in seconds */
40
    private int $timeOut = 30;
41
42
    private string $userAgent = '';
43
44
    public function __construct(string $accountId, string $passPhrase)
45
    {
46
        $this->accountId  = $accountId;
47
        $this->passPhrase = $passPhrase;
48
    }
49
50
    /**
51
     * Make the call
52
     *
53
     * @throws BpostApiBusinessException
54
     * @throws BpostApiSystemException
55
     * @throws BpostCurlException
56
     * @throws BpostInvalidResponseException
57
     */
58
    private function doCall(string $url, ?string $body = null, string $method = 'GET'): SimpleXMLElement
59
    {
60
        $headers = [
61
            'Authorization: Basic ' . $this->getAuthorizationHeader(),
62
        ];
63
64
        $options = [
65
            CURLOPT_URL            => self::API_URL . $url,
66
            CURLOPT_USERAGENT      => $this->getUserAgent(),
67
            CURLOPT_RETURNTRANSFER => true,
68
            CURLOPT_TIMEOUT        => $this->getTimeOut(),
69
            CURLOPT_HTTP_VERSION   => CURL_HTTP_VERSION_1_1,
70
            CURLOPT_HTTPHEADER     => $headers,
71
        ];
72
73
        if ($this->port !== null) {
74
            $options[CURLOPT_PORT] = $this->port;
75
        }
76
77
        if ($method === 'POST') {
78
            $options[CURLOPT_POST]       = true;
79
            $options[CURLOPT_POSTFIELDS] = $body ?? '';
80
        }
81
82
        $curl = curl_init();
83
        curl_setopt_array($curl, $options);
84
85
        try {
86
            $response = curl_exec($curl);
87
            $info     = curl_getinfo($curl);
88
89
            $errorNumber  = curl_errno($curl);
90
            $errorMessage = curl_error($curl);
91
92
            if ($errorNumber !== 0) {
93
                throw new BpostCurlException($errorMessage, $errorNumber);
94
            }
95
96
            $httpCode = (int)($info['http_code'] ?? 0);
97
98
            // Non 200 => tenter de parser l'erreur métier pour renvoyer l’exception dédiée
99
            if (!in_array($httpCode, [0, 200], true)) {
100
                $xml = @simplexml_load_string((string)$response);
101
102
                if (
103
                    $xml !== false
104
                    && ($xml->getName() === 'businessException' || $xml->getName() === 'systemException')
105
                ) {
106
                    $message = (string) ($xml->message ?? '');
107
                    $code    = isset($xml->code) ? (int) $xml->code : 0;
108
109
                    if ($xml->getName() === 'businessException') {
110
                        throw new BpostApiBusinessException($message, $code);
111
                    }
112
                    throw new BpostApiSystemException($message, $code);
113
                }
114
115
                throw new BpostInvalidResponseException('', $httpCode);
116
            }
117
118
            // 200: parser XML
119
            $xml = simplexml_load_string((string)$response);
120
            if ($xml === false) {
121
                // pas de XML valide alors que 200 => considérer comme réponse invalide
122
                throw new BpostInvalidResponseException('Empty or invalid XML body', 200);
123
            }
124
125
            if ($xml->getName() === 'businessException') {
126
                $message = (string) ($xml->message ?? '');
127
                $code    = (int) ($xml->code ?? 0);
128
                throw new BpostApiBusinessException($message, $code);
129
            }
130
131
            return $xml;
132
        } finally {
133
            curl_close($curl);
134
            $curl = null;
0 ignored issues
show
The assignment to $curl is dead and can be removed.
Loading history...
135
        }
136
    }
137
138
    /**
139
     * Generate the secret string for the Authorization header
140
     */
141
    private function getAuthorizationHeader(): string
142
    {
143
        return base64_encode($this->accountId . ':' . $this->passPhrase);
144
    }
145
146
    /**
147
     * After this time the request will stop.
148
     */
149
    public function setTimeOut(int $seconds): void
150
    {
151
        $this->timeOut = $seconds;
152
    }
153
154
    public function getTimeOut(): int
155
    {
156
        return $this->timeOut;
157
    }
158
159
    /**
160
     * Get the useragent that will be used.
161
     * Our version will be prepended to yours.
162
     * It will look like: "PHP Bpost/<version> <your-user-agent>"
163
     *
164
     * @return string
165
     */
166
    public function getUserAgent(): string
167
    {
168
        $extra = trim($this->userAgent);
169
        return sprintf('PHP Bpost Bpack247/%s%s', self::VERSION, $extra !== '' ? ' ' . $extra : '');
170
    }
171
172
    /**
173
     * Set your application user-agent, e.g. "MyApp/1.2.3"
174
     */
175
    public function setUserAgent(string $userAgent): void
176
    {
177
        $this->userAgent = $userAgent;
178
    }
179
180
    // Webservice methods
181
    /**
182
     * @throws BpostApiBusinessException
183
     * @throws BpostApiSystemException
184
     * @throws BpostCurlException
185
     * @throws BpostInvalidResponseException
186
     */
187
    public function createMember(Customer $customer): SimpleXMLElement
188
    {
189
        $url = '/customer';
190
191
        $document = new DOMDocument('1.0', 'utf-8');
192
        $document->preserveWhiteSpace = false;
193
        $document->formatOutput = true;
194
195
        $document->appendChild($customer->toXML($document));
196
197
        return $this->doCall($url, $document->saveXML(), 'POST');
198
    }
199
200
    /**
201
     * Retrieve member information
202
     *
203
     * @throws BpostApiBusinessException
204
     * @throws BpostApiSystemException
205
     * @throws BpostCurlException
206
     * @throws BpostInvalidResponseException
207
     * @throws Exception\XmlException\BpostXmlNoUserIdFoundException
208
     */
209
    public function getMember(string $id): Customer
210
    {
211
        $xml = $this->doCall('/customer/' . $id);
212
        return Customer::createFromXML($xml);
213
    }
214
}