Query   A
last analyzed

Complexity

Total Complexity 19

Size/Duplication

Total Lines 166
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 19
lcom 1
cbo 5
dl 0
loc 166
ccs 0
cts 71
cp 0
rs 10
c 0
b 0
f 0

12 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A makeModel() 0 11 2
model() 0 1 ?
A execute() 0 17 3
A prepareRequestData() 0 13 4
getAttributeMap() 0 1 ?
A getUri() 0 4 1
A getRequestMethod() 0 4 1
A getUrl() 0 4 2
isSecure() 0 1 ?
A prepareResponse() 0 16 2
A setAttributes() 0 12 3
1
<?php
2
3
namespace DJStarCOM\BookingComSDK\Query;
4
5
use function count;
6
use DJStarCOM\BookingComSDK\Exceptions\BookingResponseException;
7
use DJStarCOM\BookingComSDK\Exceptions\ModelException;
8
use DJStarCOM\BookingComSDK\HttpClient\HttpClientInterface;
9
use DJStarCOM\BookingComSDK\Models\Model;
10
use DJStarCOM\BookingComSDK\Models\Result;
11
use function is_array;
12
13
/**
14
 * Class QueryAbstract
15
 * @package DJStarCOM\BookingComSDK\Query
16
 */
17
abstract class Query
18
{
19
    public const REQUEST_METHOD_POST = 'POST';
20
    public const REQUEST_METHOD_GET = 'GET';
21
22
    /**
23
     * @var string
24
     */
25
    protected static $uri;
26
27
    /**
28
     * @var string
29
     */
30
    protected $model;
31
32
    /**
33
     * @var string
34
     */
35
    protected $endpoint = 'https://{secure}distribution-xml.booking.com/2.4/json';
36
37
    /**
38
     * QueryAbstract constructor.
39
     * @throws ModelException
40
     */
41
    public function __construct()
42
    {
43
        $this->makeModel();
44
    }
45
46
    /**
47
     * @return Model
48
     * @throws ModelException
49
     */
50
    public function makeModel(): Model
51
    {
52
        $class = $this->model();
53
        $model = new $class;
54
55
        if (!$model instanceof Model) {
56
            throw new ModelException(sprintf('Class %s must be an instance of %s', $this->model(), Model::class));
57
        }
58
59
        return $this->model = $model;
0 ignored issues
show
Documentation Bug introduced by
It seems like $model of type object<DJStarCOM\BookingComSDK\Models\Model> is incompatible with the declared type string of property $model.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
60
    }
61
62
    /**
63
     * @return string
64
     */
65
    abstract protected function model(): string;
66
67
    /**
68
     * Returns a list of the bookings that have been made through your account or with one of your affiliate IDs.
69
     *
70
     * @param HttpClientInterface $client
71
     * @return Result
72
     * @throws BookingResponseException
73
     */
74
    public function execute(HttpClientInterface $client): Result
75
    {
76
        $data = $this->prepareRequestData();
77
78
        $uri = $this->getUri() ?? null;
79
        if ($uri === null) {
80
            throw new BookingResponseException('URI is not set');
81
        }
82
83
        $response = $client->call($this->getRequestMethod(), $this->getUrl($uri), $data);
84
85
        if (isset($response->message)) {
86
            throw new BookingResponseException($response->message);
87
        }
88
89
        return $this->prepareResponse($response->result);
90
    }
91
92
    /**
93
     * Prepare data for request.
94
     *
95
     * @return array
96
     */
97
    protected function prepareRequestData(): array
98
    {
99
        $data = array_filter(array_intersect_key(get_object_vars($this), $this->getAttributeMap()));
100
        if (count($data)) {
101
            foreach ($data as $key => $value) {
102
                if (is_array($value)) {
103
                    $data[$key] = implode(',', $value);
104
                }
105
            }
106
        }
107
108
        return $data;
109
    }
110
111
    /**
112
     * @return array
113
     */
114
    abstract protected function getAttributeMap(): array;
115
116
    /**
117
     * @return string
118
     */
119
    public function getUri(): ?string
120
    {
121
        return static::$uri;
122
    }
123
124
    /**
125
     * @return string
126
     */
127
    protected function getRequestMethod(): string
128
    {
129
        return self::REQUEST_METHOD_GET;
130
    }
131
132
    /**
133
     * @param $url
134
     * @return string
135
     */
136
    protected function getUrl($url): string
137
    {
138
        return str_replace('{secure}', $this->isSecure() ? 'secure-' : '', $this->endpoint) . $url;
139
    }
140
141
    /**
142
     * @return bool
143
     */
144
    abstract protected function isSecure(): bool;
145
146
    /**
147
     * @param $data
148
     * @return Result
149
     */
150
    protected function prepareResponse($data): Result
151
    {
152
        $collections = new Result();
153
154
        foreach ($data as $item) {
155
            $class = $this->model();
156
157
            /** @var Model $model */
158
            $model = new $class;
159
            $model->setAttributes((array)$item);
160
161
            $collections->addItem($model, $model->getPrimaryKey());
162
        }
163
164
        return $collections;
165
    }
166
167
    /**
168
     * @param array $data
169
     */
170
    public function setAttributes(array $data): void
171
    {
172
        $prepareData = array_intersect_key($data, $this->getAttributeMap());
173
174
        foreach ($prepareData as $key => $value) {
175
            if (!property_exists($this, $key)) {
176
                continue;
177
            }
178
179
            $this->$key = $value;
180
        }
181
    }
182
}
183