Completed
Push — master ( 30e5c9...119263 )
by
unknown
12s
created

SearchEndpointTrait   A

Complexity

Total Complexity 24

Size/Duplication

Total Lines 203
Duplicated Lines 2.96 %

Coupling/Cohesion

Components 0
Dependencies 3

Importance

Changes 0
Metric Value
wmc 24
lcom 0
cbo 3
dl 6
loc 203
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A createElasticSearchQuery() 0 13 4
D normalizeSearchVideosResponse() 3 32 9
A normalizeSearchChannelsResponse() 3 13 4
A getTotalCountFromSearchVideosResponse() 0 9 3
B getRequestOptionsForSearchVideosEndpoint() 0 40 2
B getRequestOptionsForSearchChannelsEndpoint() 0 38 2

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
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)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
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)
0 ignored issues
show
Unused Code introduced by
This method is not used, and could be removed.
Loading history...
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