Completed
Pull Request — master (#82)
by
unknown
20:55
created

SearchEndpointTrait   A

Complexity

Total Complexity 28

Size/Duplication

Total Lines 175
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 2

Importance

Changes 0
Metric Value
wmc 28
lcom 0
cbo 2
dl 0
loc 175
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A createElasticSearchQuery() 0 13 4
B normalizeSearchVideosResponse() 0 32 9
A normalizeSearchChannelsResponse() 0 13 4
A getTotalCountFromSearchVideosResponse() 0 9 3
B getRequestOptionsForSearchVideosEndpoint() 0 44 5
A getRequestOptionsForSearchChannelsEndpoint() 0 34 3
1
<?php
2
3
declare(strict_types=1);
4
5
namespace MovingImage\Client\VMPro\Util;
6
7
use DateTime;
8
use MovingImage\Client\VMPro\Entity\ChannelsRequestParameters;
9
use MovingImage\Client\VMPro\Entity\VideosRequestParameters;
10
use MovingImage\Client\VMPro\Exception;
11
use MovingImage\Meta\Enums\PublicationState;
12
13
/**
14
 * Helper methods for dealing with search endpoint.
15
 */
16
trait SearchEndpointTrait
17
{
18
    /**
19
     * Creates an elastic search query from the provided array od parameters.
20
     */
21
    private function createElasticSearchQuery(array $params, ?string $operator = 'AND'): string
22
    {
23
        $filteredParams = [];
24
        foreach ($params as $name => $value) {
25
            if (empty($name) || empty($value)) {
26
                continue;
27
            }
28
29
            $filteredParams[] = "$name:$value";
30
        }
31
32
        return implode(" $operator ", $filteredParams);
33
    }
34
35
    /**
36
     * Adjust the response from the `search` endpoint for video data type,
37
     * so that it is compatible with the response of `videos` endpoint.
38
     * Namely, it converts the date to a timestamp, adjusts the format of channels array
39
     * and re-maps some renamed properties (such as duration).
40
     * It also renames root-level properties so that they can be correctly unserialized.
41
     *
42
     * @throws Exception
43
     * @throws \Exception
44
     */
45
    private function normalizeSearchVideosResponse(string $response): string
46
    {
47
        $response = json_decode($response, true);
48
        if (!is_array($response) || !array_key_exists('result', $response) || !array_key_exists('total', $response)) {
49
            throw new Exception('Invalid response from search endpoint');
50
        }
51
52
        $response['totalCount'] = $response['total'];
53
        $response['videos'] = $response['result'];
54
        unset($response['result'], $response['total']);
55
56
        foreach ($response['videos'] as &$video) {
57
            $video['uploadDate'] = $video['createdDate'];
58
            $video['length'] = $video['duration'];
59
            foreach ($video as $prop => $value) {
60
                if (in_array($prop, ['createdDate', 'modifiedDate', 'uploadDate'])) {
61
                    $video[$prop] = (new DateTime($value))->getTimestamp();
62
                }
63
64
                if ('channels' === $prop) {
65
                    foreach ($value as $channelIndex => $channelId) {
66
                        $video[$prop][$channelIndex] = [
67
                            'id' => $channelId,
68
                            'name' => '',
69
                        ];
70
                    }
71
                }
72
            }
73
        }
74
75
        return json_encode($response);
76
    }
77
78
    /**
79
     * Adjust the response from the `search` endpoint for channel data type.
80
     * Namely, it renames the root-level properties, so they can be correctly unserialized.
81
     *
82
     * @throws Exception
83
     */
84
    private function normalizeSearchChannelsResponse(string $response): string
85
    {
86
        $response = json_decode($response, true);
87
        if (!is_array($response) || !array_key_exists('result', $response) || !array_key_exists('total', $response)) {
88
            throw new Exception('Invalid response from search endpoint');
89
        }
90
91
        $response['totalCount'] = $response['total'];
92
        $response['channels'] = $response['result'];
93
        unset($response['result'], $response['total']);
94
95
        return json_encode($response);
96
    }
97
98
    /**
99
     * @throws Exception
100
     */
101
    private function getTotalCountFromSearchVideosResponse(string $response): int
0 ignored issues
show
Unused Code introduced by
This method is not used, and could be removed.
Loading history...
102
    {
103
        $response = json_decode($response, true);
104
        if (!is_array($response) || !array_key_exists('total', $response)) {
105
            throw new Exception('Response from search endpoint is missing the "total" key');
106
        }
107
108
        return (int) $response['total'];
109
    }
110
111
    private function getRequestOptionsForSearchVideosEndpoint(
112
        int $videoManagerId,
113
        ?VideosRequestParameters $parameters = null
114
    ): array {
115
        $options = [
116
            'documentType' => 'video',
117
            'videoManagerIds' => [$videoManagerId],
118
        ];
119
120
        $queryParams = [];
121
122
        if ($parameters) {
123
            $queryParams += [
124
                'channels' => implode(',', $parameters->getChannelIds()),
125
                'id' => $parameters->getVideoId(),
126
                $parameters->getSearchInField() => $parameters->getSearchTerm(),
127
            ];
128
129
            switch ($parameters->getPublicationState()) {
130
                case PublicationState::PUBLISHED:
131
                    $queryParams['published'] = 'true';
132
                    break;
133
                case PublicationState::NOT_PUBLISHED:
134
                    $queryParams['published'] = 'false';
135
                    break;
136
                //case 'all': do nothing
137
            }
138
139
            $options += [
140
                'size' => $parameters->getLimit(),
141
                'from' => $parameters->getOffset(),
142
                'orderBy' => $parameters->getOrderProperty(),
143
                'order' => $parameters->getOrder(),
144
            ];
145
146
            if ($parameters->getMetadataSetKey()) {
147
                $options['metaDataSetKey'] = $parameters->getMetadataSetKey();
148
            }
149
        }
150
151
        $options['query'] = $this->createElasticSearchQuery($queryParams);
152
153
        return $options;
154
    }
155
156
    private function getRequestOptionsForSearchChannelsEndpoint(
157
        int $videoManagerId,
158
        ChannelsRequestParameters $parameters = null
159
    ): array {
160
        $options = [
161
            'documentType' => 'channel',
162
            'videoManagerIds' => [$videoManagerId],
163
        ];
164
165
        $queryParams = [
166
            'videoManagerId' => $videoManagerId,
167
        ];
168
169
        if ($parameters) {
170
            $queryParams += [
171
                $parameters->getSearchInField() => $parameters->getSearchTerm(),
172
            ];
173
174
            $options += [
175
                'size' => $parameters->getLimit(),
176
                'from' => $parameters->getOffset(),
177
                'orderBy' => $parameters->getOrderProperty(),
178
                'order' => $parameters->getOrder(),
179
            ];
180
181
            if ($parameters->getMetadataSetKey()) {
182
                $options['metaDataSetKey'] = $parameters->getMetadataSetKey();
183
            }
184
        }
185
186
        $options['query'] = $this->createElasticSearchQuery($queryParams);
187
188
        return $options;
189
    }
190
}
191