1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace MovingImage\Client\VMPro\Util; |
4
|
|
|
|
5
|
|
|
use MovingImage\Client\VMPro\Entity\ChannelsRequestParameters; |
6
|
|
|
use MovingImage\Client\VMPro\Entity\VideosRequestParameters; |
7
|
|
|
use MovingImage\Client\VMPro\Exception; |
8
|
|
|
|
9
|
|
|
/** |
10
|
|
|
* Helper methods for dealing with search endpoint. |
11
|
|
|
*/ |
12
|
|
|
trait SearchEndpointTrait |
13
|
|
|
{ |
14
|
|
|
/** |
15
|
|
|
* Creates an elastic search query from the provided array od parameters. |
16
|
|
|
* |
17
|
|
|
* @param array $params |
18
|
|
|
* @param string $operator |
19
|
|
|
* |
20
|
|
|
* @return string |
21
|
|
|
*/ |
22
|
|
|
private function createElasticSearchQuery(array $params, $operator = 'AND') |
23
|
|
|
{ |
24
|
|
|
$filteredParams = []; |
25
|
|
|
foreach ($params as $name => $value) { |
26
|
|
|
if (empty($name) || empty($value)) { |
27
|
|
|
continue; |
28
|
|
|
} |
29
|
|
|
|
30
|
|
|
$filteredParams[] = "$name:$value"; |
31
|
|
|
} |
32
|
|
|
|
33
|
|
|
return implode(" $operator ", $filteredParams); |
34
|
|
|
} |
35
|
|
|
|
36
|
|
|
/** |
37
|
|
|
* Adjust the response from the `search` endpoint for video data type, |
38
|
|
|
* so that it is compatible with the response of `videos` endpoint. |
39
|
|
|
* Namely, it converts the date to a timestamp, adjusts the format of channels array |
40
|
|
|
* and re-maps some renamed properties (such as duration). |
41
|
|
|
* It also renames root-level properties so that they can be correctly unserialized. |
42
|
|
|
* |
43
|
|
|
* @param string $response |
44
|
|
|
* |
45
|
|
|
* @return string |
46
|
|
|
* |
47
|
|
|
* @throws Exception |
48
|
|
|
*/ |
49
|
|
|
private function normalizeSearchVideosResponse($response) |
50
|
|
|
{ |
51
|
|
|
$response = json_decode($response, true); |
52
|
|
View Code Duplication |
if (!is_array($response) || !array_key_exists('result', $response) || !array_key_exists('total', $response)) { |
|
|
|
|
53
|
|
|
throw new Exception('Invalid response from search endpoint'); |
54
|
|
|
} |
55
|
|
|
|
56
|
|
|
$response['totalCount'] = $response['total']; |
57
|
|
|
$response['videos'] = $response['result']; |
58
|
|
|
unset($response['result'], $response['total']); |
59
|
|
|
|
60
|
|
|
foreach ($response['videos'] as &$video) { |
61
|
|
|
$video['uploadDate'] = $video['createdDate']; |
62
|
|
|
$video['length'] = $video['duration']; |
63
|
|
|
foreach ($video as $prop => $value) { |
64
|
|
|
if (in_array($prop, ['createdDate', 'modifiedDate', 'uploadDate'])) { |
65
|
|
|
$video[$prop] = (new \DateTime($value))->getTimestamp(); |
66
|
|
|
} |
67
|
|
|
|
68
|
|
|
if ($prop === 'channels') { |
69
|
|
|
foreach ($value as $channelIndex => $channelId) { |
70
|
|
|
$video[$prop][$channelIndex] = [ |
71
|
|
|
'id' => $channelId, |
72
|
|
|
'name' => '', |
73
|
|
|
]; |
74
|
|
|
} |
75
|
|
|
} |
76
|
|
|
} |
77
|
|
|
} |
78
|
|
|
|
79
|
|
|
return json_encode($response); |
80
|
|
|
} |
81
|
|
|
|
82
|
|
|
/** |
83
|
|
|
* Adjust the response from the `search` endpoint for channel data type. |
84
|
|
|
* Namely, it renames the root-level properties, so they can be correctly unserialized. |
85
|
|
|
* |
86
|
|
|
* @param string $response |
87
|
|
|
* |
88
|
|
|
* @return string |
89
|
|
|
* |
90
|
|
|
* @throws Exception |
91
|
|
|
*/ |
92
|
|
|
private function normalizeSearchChannelsResponse($response) |
93
|
|
|
{ |
94
|
|
|
$response = json_decode($response, true); |
95
|
|
View Code Duplication |
if (!is_array($response) || !array_key_exists('result', $response) || !array_key_exists('total', $response)) { |
|
|
|
|
96
|
|
|
throw new Exception('Invalid response from search endpoint'); |
97
|
|
|
} |
98
|
|
|
|
99
|
|
|
$response['totalCount'] = $response['total']; |
100
|
|
|
$response['channels'] = $response['result']; |
101
|
|
|
unset($response['result'], $response['total']); |
102
|
|
|
|
103
|
|
|
return json_encode($response); |
104
|
|
|
} |
105
|
|
|
|
106
|
|
|
/** |
107
|
|
|
* @param string $response |
108
|
|
|
* |
109
|
|
|
* @return int |
110
|
|
|
* |
111
|
|
|
* @throws Exception |
112
|
|
|
*/ |
113
|
|
|
private function getTotalCountFromSearchVideosResponse($response) |
|
|
|
|
114
|
|
|
{ |
115
|
|
|
$response = json_decode($response, true); |
116
|
|
|
if (!is_array($response) || !array_key_exists('total', $response)) { |
117
|
|
|
throw new Exception('Response from search endpoint is missing the "total" key'); |
118
|
|
|
} |
119
|
|
|
|
120
|
|
|
return (int) $response['total']; |
121
|
|
|
} |
122
|
|
|
|
123
|
|
|
/** |
124
|
|
|
* @param int $videoManagerId |
125
|
|
|
* @param VideosRequestParameters|null $parameters |
126
|
|
|
* |
127
|
|
|
* @return array |
128
|
|
|
*/ |
129
|
|
|
private function getRequestOptionsForSearchVideosEndpoint( |
130
|
|
|
$videoManagerId, |
131
|
|
|
VideosRequestParameters $parameters = null |
132
|
|
|
) { |
133
|
|
|
$options = [ |
134
|
|
|
'documentType' => 'video', |
135
|
|
|
'videoManagerIds' => [$videoManagerId], |
136
|
|
|
'fetchSources' => [ |
137
|
|
|
'id', |
138
|
|
|
'title', |
139
|
|
|
'description', |
140
|
|
|
'createdDate', |
141
|
|
|
'duration', |
142
|
|
|
'published', |
143
|
|
|
'customMetadata', |
144
|
|
|
'keywords', |
145
|
|
|
'channels', |
146
|
|
|
'downloadable', |
147
|
|
|
], |
148
|
|
|
]; |
149
|
|
|
|
150
|
|
|
if ($parameters) { |
151
|
|
|
$queryParams = [ |
152
|
|
|
'channels' => $parameters->getChannelId(), |
153
|
|
|
'published' => $parameters->getPublicationState(), |
154
|
|
|
'id' => $parameters->getVideoId(), |
155
|
|
|
$parameters->getSearchInField() => $parameters->getSearchTerm(), |
156
|
|
|
]; |
157
|
|
|
|
158
|
|
|
$options += [ |
159
|
|
|
'size' => $parameters->getLimit(), |
160
|
|
|
'from' => $parameters->getOffset(), |
161
|
|
|
'orderBy' => $parameters->getOrderProperty(), |
162
|
|
|
'order' => $parameters->getOrder(), |
163
|
|
|
'query' => $this->createElasticSearchQuery($queryParams), |
164
|
|
|
]; |
165
|
|
|
} |
166
|
|
|
|
167
|
|
|
return $options; |
168
|
|
|
} |
169
|
|
|
|
170
|
|
|
/** |
171
|
|
|
* @param int $videoManagerId |
172
|
|
|
* @param ChannelsRequestParameters|null $parameters |
173
|
|
|
* |
174
|
|
|
* @return array |
175
|
|
|
*/ |
176
|
|
|
private function getRequestOptionsForSearchChannelsEndpoint( |
177
|
|
|
$videoManagerId, |
178
|
|
|
ChannelsRequestParameters $parameters = null |
179
|
|
|
) { |
180
|
|
|
$options = [ |
181
|
|
|
'documentType' => 'channel', |
182
|
|
|
'videoManagerIds' => [$videoManagerId], |
183
|
|
|
'fetchSources' => [ |
184
|
|
|
'id', |
185
|
|
|
'videoManagerId', |
186
|
|
|
'parentId', |
187
|
|
|
'name', |
188
|
|
|
'description', |
189
|
|
|
'customMetadata', |
190
|
|
|
], |
191
|
|
|
]; |
192
|
|
|
|
193
|
|
|
$queryParams = [ |
194
|
|
|
'videoManagerId' => $videoManagerId, |
195
|
|
|
]; |
196
|
|
|
|
197
|
|
|
if ($parameters) { |
198
|
|
|
$queryParams += [ |
199
|
|
|
$parameters->getSearchInField() => $parameters->getSearchTerm(), |
200
|
|
|
]; |
201
|
|
|
|
202
|
|
|
$options += [ |
203
|
|
|
'size' => $parameters->getLimit(), |
204
|
|
|
'from' => $parameters->getOffset(), |
205
|
|
|
'orderBy' => $parameters->getOrderProperty(), |
206
|
|
|
'order' => $parameters->getOrder(), |
207
|
|
|
]; |
208
|
|
|
} |
209
|
|
|
|
210
|
|
|
$options['query'] = $this->createElasticSearchQuery($queryParams); |
211
|
|
|
|
212
|
|
|
return $options; |
213
|
|
|
} |
214
|
|
|
} |
215
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.