BpmOnline::getResponse()   A
last analyzed

Complexity

Conditions 3
Paths 4

Size

Total Lines 39
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 25
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 27
nc 4
nop 2
dl 0
loc 39
ccs 25
cts 25
cp 1
crap 3
rs 9.488
c 0
b 0
f 0
1
<?php
2
/**
3
 * @category    Brownie/BpmOnline
4
 * @author      Brownie <[email protected]>
5
 * @license     https://opensource.org/licenses/MIT
6
 */
7
8
namespace Brownie\BpmOnline;
9
10
use Brownie\BpmOnline\Exception\AuthenticationException;
11
use Brownie\BpmOnline\Exception\HttpCodeException;
12
use Brownie\HttpClient\Header\Header;
13
use Brownie\HttpClient\HTTPClient;
14
use Brownie\BpmOnline\DataService\Contract;
15
use Brownie\HttpClient\Request;
16
use Brownie\Util\StorageArray;
17
use Brownie\HttpClient\Exception\ClientException;
18
use Brownie\HttpClient\Exception\ValidateException;
19
use Brownie\BpmOnline\DataService\Response;
20
21
/**
22
 * API access to a single marketing management platform 'CRM-system bpm’online'
23
 *
24
 * @method HTTPClient   getHttpClient()             HTTP client.
25
 * @method Config       getConfig()                 Bpm'online config.
26
 * @method array        getAuthentication()         Returns authentication data.
27
 * @method BpmOnline    setAuthentication($data)    Sets authentication data.
28
 * @method int          getConfigurationNumber()    Returns configuration number.
29
 * @method string       getDataFormat()             Returns data format.
30
 */
31
class BpmOnline extends StorageArray
32
{
33
34
    /**
35
     * List of supported fields.
36
     *
37
     * @var array
38
     */
39
    protected $fields = [
40
        'httpClient' => null,
41
        'config' => null,
42
        'configurationNumber' => 0,
43
        'dataFormat' => 'json',
44
        'authentication' => null,
45
    ];
46
47
    /**
48
     * Sets the input values.
49
     *
50
     * @param HTTPClient    $httpClient     HTTP client.
51
     * @param Config        $config         Bpm'online config.
52
     */
53 5
    public function __construct(HTTPClient $httpClient, Config $config)
54
    {
55 5
        parent::__construct([
56 5
            'httpClient' => $httpClient,
57 5
            'config' => $config,
58
        ]);
59 5
    }
60
61
    /**
62
     * Creates a request to DataService.
63
     *
64
     * @param string    $url        Request URL.
65
     * @param string    $rawBody    Raw body.
66
     *
67
     * @return Request
68
     */
69 5
    private function createRequest($url, $rawBody)
70
    {
71
        return $this
72 5
            ->getHttpClient()
73 5
            ->createRequest()
74 5
            ->setMethod(Request::HTTP_METHOD_POST)
75 5
            ->setUrl($url)
76 5
            ->setBodyFormat(Request::FORMAT_APPLICATION_JSON)
77 5
            ->addHeader(new Header([
78 5
                'name' => 'Content-Type',
79 5
                'value' => Request::FORMAT_APPLICATION_JSON,
80
            ]))
81 5
            ->setBody($rawBody)
82 5
            ->setTimeOut($this->getConfig()->getApiConnectTimeOut());
83
    }
84
85
    /**
86
     * Authenticates in the DataService bpm'online.
87
     *
88
     * @throws AuthenticationException
89
     * @throws HttpCodeException
90
     * @throws ClientException
91
     * @throws ValidateException
92
     */
93 4
    private function authentication()
94
    {
95
        $request = $this
96 4
            ->createRequest(
97 4
                $this->getConfig()->getApiUrlScheme() . '://' .
98 4
                $this->getConfig()->getUserDomain() . '.' .
99 4
                $this->getConfig()->getApiDomain() .
100 4
                '/ServiceModel/AuthService.svc/Login',
101 4
                json_encode([
102 4
                    'UserName' => $this->getConfig()->getUserName(),
103 4
                    'UserPassword' => $this->getConfig()->getUserPassword(),
104
                ])
105
            );
106
107 4
        $response = $this->getHttpClient()->request($request);
108
109 4
        if (200 != $response->getHttpCode()) {
110 1
            throw new HttpCodeException('Invalid response code: ' . $response->getHttpCode());
111
        }
112
113 3
        $jsonResponse = json_decode($response->getBody(), true);
114
115 3
        if ((JSON_ERROR_NONE != json_last_error()) || (0 != $jsonResponse['Code']))
116
        {
117 2
            throw new AuthenticationException('Authentication failed.');
118
        }
119
120 1
        $this->setAuthentication([
121 1
            '.aspxauth' => $response->getHttpCookieList()->get('.aspxauth'),
122 1
            'bpmcsrf' => $response->getHttpCookieList()->get('bpmcsrf'),
123
        ]);
124 1
    }
125
126
    /**
127
     * Returns the response from the execution of the contract.
128
     *
129
     * @param Contract  $contract    DataService contract.
130
     * @param int       $attempts    Number of request retries.
131
     *
132
     * @return Response
133
     *
134
     * @throws AuthenticationException
135
     * @throws ClientException
136
     * @throws Exception\ValidateException
137
     * @throws HttpCodeException
138
     * @throws ValidateException
139
     */
140 5
    public function getResponse(Contract $contract, $attempts = 3)
141
    {
142 5
        $contract->validate();
143 5
        if (empty($this->getAuthentication())) {
144 4
            $this->authentication();
145
        }
146
147
        $request = $this
148 2
            ->createRequest(
149 2
                $this->getConfig()->getApiUrlScheme() . '://' .
150 2
                $this->getConfig()->getUserDomain() . '.' . $this->getConfig()->getApiDomain() .
151 2
                '/' . $this->getConfigurationNumber() . '/dataservice/' . $this->getDataFormat() .
152 2
                '/reply/' . $contract->getContractType(),
153 2
                json_encode($contract->toArray())
154
            )
155 2
            ->addCookie($this->getAuthentication()['.aspxauth'])
156 2
            ->addCookie($this->getAuthentication()['bpmcsrf'])
157 2
            ->addHeader(
158
                $this
159 2
                    ->getHttpClient()
160 2
                    ->createHeader('Authorization', 'Cookie')
161
            )
162 2
            ->addHeader(
163
                $this
164 2
                    ->getHttpClient()
165 2
                    ->createHeader('BPMCSRF', $this->getAuthentication()['bpmcsrf']->getValue())
166
            );
167
168 2
        $response = $this->getHttpClient()->request($request, $attempts, [200, 500]);
169 2
        $contractResponse = $contract->getResponse($response->getBody());
170
171 2
        if (200 != $response->getHttpCode()) {
172 1
            throw new HttpCodeException(
173 1
                'Invalid response code: ' . $response->getHttpCode() . ', ' .
174 1
                $contractResponse->getErrorMessage()
175
            );
176
        }
177
178 1
        return $contractResponse;
179
    }
180
}
181