processAdditionalParameters()   D
last analyzed

Complexity

Conditions 10
Paths 10

Size

Total Lines 35
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 10
eloc 23
nc 10
nop 2
dl 0
loc 35
rs 4.8196
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace GinoPane\PHPolyglot\API\Implementation\TTS\IbmWatson\AudioFormat;
4
5
use GinoPane\NanoRest\Supplemental\Headers;
6
use GinoPane\PHPolyglot\API\Supplemental\TTS\TtsAudioFormat;
7
use GinoPane\PHPolyglot\Exception\InvalidContentTypeException;
8
use GinoPane\PHPolyglot\Exception\InvalidAudioFormatCodeException;
9
use GinoPane\PHPolyglot\Exception\InvalidAudioFormatParameterException;
10
11
/**
12
 * Trait IbmWatsonAudioFormatsTrait
13
 *
14
 * @link https://console.bluemix.net/docs/services/text-to-speech/http.html#format
15
 *
16
 * @author Sergey <Gino Pane> Karavay
17
 */
18
trait IbmWatsonAudioFormatsTrait
19
{
20
    /**
21
     * TTS audio format codes to IBM-Watson-specific codes mapping
22
     *
23
     * @var array
24
     */
25
    private static $formatMapping = [
26
        TtsAudioFormat::AUDIO_BASIC => IbmWatsonAudioFormatsInterface::AUDIO_BASIC,
27
        TtsAudioFormat::AUDIO_FLAC  => IbmWatsonAudioFormatsInterface::AUDIO_FLAC,
28
        TtsAudioFormat::AUDIO_L16   => IbmWatsonAudioFormatsInterface::AUDIO_L16,
29
        TtsAudioFormat::AUDIO_MP3   => IbmWatsonAudioFormatsInterface::AUDIO_MP3,
30
        TtsAudioFormat::AUDIO_MPEG  => IbmWatsonAudioFormatsInterface::AUDIO_MPEG,
31
        TtsAudioFormat::AUDIO_MULAW => IbmWatsonAudioFormatsInterface::AUDIO_MULAW,
32
        TtsAudioFormat::AUDIO_OGG   => IbmWatsonAudioFormatsInterface::AUDIO_OGG,
33
        TtsAudioFormat::AUDIO_WAV   => IbmWatsonAudioFormatsInterface::AUDIO_WAV,
34
        TtsAudioFormat::AUDIO_WEBM  => IbmWatsonAudioFormatsInterface::AUDIO_WEBM
35
    ];
36
37
    /**
38
     * Returns the string containing the accept parameter required for TTS.
39
     * It specifies audio format, sample rate and additional params if any
40
     *
41
     * @param TtsAudioFormat $format
42
     * @param array          $additionalData
43
     *
44
     * @throws InvalidAudioFormatCodeException
45
     * @throws InvalidAudioFormatParameterException
46
     *
47
     * @return string
48
     */
49
    public function getAcceptParameter(TtsAudioFormat $format, array $additionalData = []): string
50
    {
51
        $audioFormat = self::$formatMapping[$format->getFormat()] ?? '';
52
53
        if (empty($audioFormat)) {
54
            throw new InvalidAudioFormatCodeException($format->getFormat());
55
        }
56
57
        $accept = array_merge([$audioFormat], $this->processAdditionalParameters($format, $additionalData));
58
59
        return implode(";", $accept);
60
    }
61
62
    /**
63
     * @param Headers $headers
64
     *
65
     * @return TtsAudioFormat
66
     *
67
     * @throws InvalidContentTypeException
68
     */
69
    public function getAudioFormatByContentTypeHeader(Headers $headers): TtsAudioFormat
70
    {
71
        if (is_null($header = $headers->getHeader('content-type'))) {
72
            throw new InvalidContentTypeException("Response content-type is invalid or empty");
73
        }
74
75
        preg_match('/([^;]+)[;]?/', $header, $matches);
76
77
        if (empty($matches[1]) || !in_array($matches[1], self::$formatMapping)) {
78
            throw new InvalidContentTypeException(
79
                sprintf("Cannot extract audio format from content type: \"%s\"", $header)
80
            );
81
        }
82
83
        return new TtsAudioFormat((string)array_search($matches[1], self::$formatMapping));
84
    }
85
86
    /**
87
     * @param TtsAudioFormat $format
88
     * @param array          $additionalData
89
     *
90
     * @throws InvalidAudioFormatParameterException
91
     *
92
     * @return array
93
     */
94
    private function processAdditionalParameters(TtsAudioFormat $format, array $additionalData = []): array
95
    {
96
        $additional = [];
97
98
        switch ($format->getFormat()) {
99
            case TtsAudioFormat::AUDIO_FLAC:
100
            case TtsAudioFormat::AUDIO_MP3:
101
            case TtsAudioFormat::AUDIO_MPEG:
102
            case TtsAudioFormat::AUDIO_WAV:
103
                $additional[] = $this->extractRate($additionalData);
104
105
                break;
106
            case TtsAudioFormat::AUDIO_OGG:
107
                $additional[] = $this->extractRate($additionalData);
108
                $additional[] = $this->extractCodec($additionalData);
109
110
                break;
111
            case TtsAudioFormat::AUDIO_L16:
112
            case TtsAudioFormat::AUDIO_MULAW:
113
                $additional[] = $this->extractRate($additionalData, true);
114
115
                break;
116
            case TtsAudioFormat::AUDIO_WEBM:
117
                $codec = $this->extractCodec($additionalData);
118
119
                if ($codec == ("codecs=" . IbmWatsonAudioFormatsInterface::CODEC_VORBIS)) {
120
                    $additional[] = $this->extractRate($additionalData);
121
                }
122
123
                $additional[] = $codec;
124
125
                break;
126
        }
127
128
        return array_filter($additional);
129
    }
130
131
    /**
132
     * @param string $codec
133
     *
134
     * @return bool
135
     */
136
    private function codecIsValid(string $codec): bool
137
    {
138
        return in_array(
139
            $codec, //@codeCoverageIgnore
140
            [
141
                IbmWatsonAudioFormatsInterface::CODEC_OPUS,
142
                IbmWatsonAudioFormatsInterface::CODEC_VORBIS
143
            ]
144
        );
145
    }
146
147
    /**
148
     * @param array $additionalData
149
     *
150
     * @return mixed
151
     * @throws InvalidAudioFormatParameterException
152
     */
153
    private function extractCodec(array $additionalData)
154
    {
155
        $codec = $this->extractOptionalParameter('codec', $additionalData);
156
157
        if ($codec && !$this->codecIsValid($codec)) {
158
            throw new InvalidAudioFormatParameterException(
159
                sprintf("Specified codec \"%s\" is invalid", $codec)
160
            );
161
        }
162
163
        return "codecs=$codec";
164
    }
165
166
    /**
167
     * @param array $additionalData
168
     * @param bool  $required
169
     *
170
     * @throws InvalidAudioFormatParameterException
171
     *
172
     * @return mixed
173
     */
174
    private function extractRate(array $additionalData, bool $required = false)
175
    {
176
        $rateString = '';
177
178
        if ($required) {
179
            $rate = (int)$this->extractRequiredParameter('rate', $additionalData);
180
        } else {
181
            $rate = (int)$this->extractOptionalParameter('rate', $additionalData);
182
        }
183
184
        if ($rate) {
185
            $rateString = "rate=$rate";
186
        }
187
188
        return $rateString;
189
    }
190
191
    /**
192
     * @param string $parameter
193
     * @param array  $data
194
     *
195
     * @throws InvalidAudioFormatParameterException
196
     *
197
     * @return mixed
198
     */
199
    private function extractRequiredParameter(string $parameter, array $data)
200
    {
201
        if (!isset($data[$parameter])) {
202
            throw new InvalidAudioFormatParameterException(
203
                sprintf("Parameter \"%s\" is required", $parameter)
204
            );
205
        }
206
207
        return $data[$parameter];
208
    }
209
210
    /**
211
     * @param string $parameter
212
     * @param array  $data
213
     *
214
     * @return mixed|null
215
     */
216
    private function extractOptionalParameter(string $parameter, array $data)
217
    {
218
        if (isset($data[$parameter])) {
219
            return $data[$parameter];
220
        }
221
222
        return null;
223
    }
224
}
225