Passed
Push — master ( 11fb09...dec909 )
by Chris
13:46
created

Rekognition::startDetectingLabels()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 15
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 8
c 1
b 0
f 0
dl 0
loc 15
rs 10
cc 2
nc 2
nop 3
1
<?php
2
3
namespace Meema\MediaRecognition\Recognizers;
4
5
use Aws\Rekognition\RekognitionClient;
6
use Exception;
7
use Meema\MediaRecognition\Contracts\MediaRecognition as MediaRecognitionInterface;
8
use Meema\MediaRecognition\Models\MediaRecognition;
9
use Meema\MediaRecognition\Traits\InteractsWithStorage;
10
11
class Rekognition implements MediaRecognitionInterface
12
{
13
    use InteractsWithStorage;
14
15
    /**
16
     * Client instance of MediaRecognition.
17
     *
18
     * @var \Aws\Rekognition\RekognitionClient
19
     */
20
    protected RekognitionClient $client;
21
22
    /**
23
     * The settings provided to the Rekognition job.
24
     *
25
     * @var array
26
     */
27
    protected array $settings;
28
29
    /**
30
     * The input image as base64-encoded bytes.
31
     *
32
     * @var string|null
33
     */
34
    protected ?string $blob = null;
35
36
    /**
37
     * The relating media model's id.
38
     *
39
     * @var int|null
40
     */
41
    protected ?int $mediaId = null;
42
43
    /**
44
     * Construct converter.
45
     *
46
     * @param \Aws\Rekognition\RekognitionClient $client
47
     */
48
    public function __construct(RekognitionClient $client)
49
    {
50
        $this->client = $client;
51
    }
52
53
    /**
54
     * Get the MediaRecognition Client.
55
     *
56
     * @return \Aws\Rekognition\RekognitionClient
57
     */
58
    public function getClient(): RekognitionClient
59
    {
60
        return $this->client;
61
    }
62
63
    /**
64
     * Set the base64 encoded image.
65
     *
66
     * @param string $blob
67
     *
68
     * @return $this
69
     */
70
    public function blob(string $blob)
71
    {
72
        $this->blob = $blob;
73
74
        return $this;
75
    }
76
77
    /**
78
     * Sets the image to be analyzed.
79
     *
80
     * @return void
81
     * @throws \Exception
82
     */
83
    protected function setImageSettings(): void
84
    {
85
        if (is_string($this->blob)) {
86
            $this->settings['Image'] = [
87
                'Bytes' => $this->blob,
88
            ];
89
90
            return;
91
        }
92
93
        $disk = $this->disk ?? config('media-recognition.disk');
94
        $bucketName = config("filesystems.disks.$disk.bucket");
95
96
        if (! $bucketName) {
97
            throw new Exception('Please make sure to set a S3 bucket name.');
98
        }
99
100
        $this->settings['Image'] = [
101
            'S3Object' => [
102
                'Bucket' => $bucketName,
103
                'Name' => $this->path,
104
            ],
105
        ];
106
    }
107
108
    /**
109
     * Sets the video to be analyzed.
110
     *
111
     * @param $type - used to create a readable identifier.
0 ignored issues
show
Documentation Bug introduced by
The doc comment - at position 0 could not be parsed: Unknown type name '-' at position 0 in -.
Loading history...
112
     * @return void
113
     * @throws \Exception
114
     */
115
    protected function setVideoSettings($type): void
116
    {
117
        $disk = $this->disk ?? config('media-recognition.disk');
118
        $bucketName = config("filesystems.disks.$disk.bucket");
119
120
        if (! $bucketName) {
121
            throw new Exception('Please make sure to set a S3 bucket name.');
122
        }
123
124
        $this->settings['Video'] = [
125
            'S3Object' => [
126
                'Bucket' => $bucketName,
127
                'Name' => $this->path,
128
            ],
129
        ];
130
131
        $this->settings['NotificationChannel'] = [
132
            'RoleArn' => config('media-recognition.iam_arn'),
133
            'SNSTopicArn' => config('media-recognition.sns_topic_arn'),
134
        ];
135
136
        $uniqueId = $type.'_'.$this->mediaId;
137
        // Idempotent token used to identify the start request.
138
        // If you use the same token with multiple StartCelebrityRecognition requests, the same JobId is returned.
139
        // Use ClientRequestToken to prevent the same job from being accidentally started more than once.
140
        $this->settings['ClientRequestToken'] = $uniqueId;
141
142
        // the JobTag is set to be the media id, so we can adjust the media record with the results once the webhook comes in
143
        $this->settings['JobTag'] = $uniqueId;
144
    }
145
146
    /**
147
     * Detects labels/objects in an image.
148
     *
149
     * @param int|null $mediaId
150
     * @param int|null $minConfidence
151
     * @param int|null $maxLabels
152
     * @return \Aws\Result
153
     * @throws \Exception
154
     */
155
    public function detectLabels($mediaId = null, $minConfidence = null, $maxLabels = null)
156
    {
157
        $settings = $this->setImageSettings();
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $settings is correct as $this->setImageSettings() targeting Meema\MediaRecognition\R...ion::setImageSettings() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
158
159
        $settings['MinConfidence'] = $minConfidence ?? config('media-recognition.min_confidence');
160
161
        if (is_int($maxLabels)) {
162
            $settings['MaxLabels'] = $maxLabels;
163
        }
164
165
        $results = $this->client->detectLabels($settings);
0 ignored issues
show
Bug introduced by
$settings of type void is incompatible with the type array expected by parameter $args of Aws\Rekognition\RekognitionClient::detectLabels(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

165
        $results = $this->client->detectLabels(/** @scrutinizer ignore-type */ $settings);
Loading history...
166
167
        if (! config('media-recognition.track_media_recognitions')) {
168
            return $results;
169
        }
170
171
        if (is_null($mediaId)) {
172
            throw new Exception('Please make sure to set a $mediaId.');
173
        }
174
175
        MediaRecognition::updateOrCreate([
176
            'model_id' => $mediaId,
177
            'model_type' => config('media-converter.media_model'),
178
        ], ['labels' => $results->toArray()]);
179
180
        return $results;
181
    }
182
183
    /**
184
     * Starts the detection of labels/objects in a video.
185
     *
186
     * @param int $mediaId
187
     * @param int|null $minConfidence
188
     * @param int $maxResults
189
     * @return \Aws\Result
190
     * @throws \Exception
191
     */
192
    public function startDetectingLabels(int $mediaId, $minConfidence = null, $maxResults = 1000)
193
    {
194
        $this->mediaId = $mediaId;
195
196
        $this->setVideoSettings('StartLabelDetection');
197
        $this->settings['MinConfidence'] = $minConfidence ?? config('media-recognition.min_confidence');
198
        $this->settings['MaxResults'] = $maxResults;
199
200
        $results = $this->client->startLabelDetection($this->settings);
201
202
        if ($results['JobId']) {
203
            $this->updateJobId($results['JobId']);
204
        }
205
206
        return $results;
207
    }
208
209
    /**
210
     * Detects faces in an image & analyzes them.
211
     *
212
     * @param int|null $mediaId
213
     * @param array $attributes
214
     * @return \Aws\Result
215
     * @throws \Exception
216
     */
217
    public function detectFaces($mediaId = null, $attributes = ['DEFAULT'])
218
    {
219
        $settings = $this->setImageSettings();
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $settings is correct as $this->setImageSettings() targeting Meema\MediaRecognition\R...ion::setImageSettings() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
220
221
        $settings['Attributes'] = $attributes;
222
223
        $results = $this->client->detectFaces($settings);
0 ignored issues
show
Bug introduced by
$settings of type void is incompatible with the type array expected by parameter $args of Aws\Rekognition\RekognitionClient::detectFaces(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

223
        $results = $this->client->detectFaces(/** @scrutinizer ignore-type */ $settings);
Loading history...
224
225
        $this->updateOrCreate('faces', $mediaId, $results);
226
227
        return $results;
228
    }
229
230
    /**
231
     * Detects moderation labels in an image.
232
     * This can be useful for children-friendly images or NSFW images.
233
     *
234
     * @param int|null $mediaId
235
     * @param int|null $minConfidence
236
     * @return \Aws\Result
237
     * @throws \Exception
238
     */
239
    public function detectModeration($mediaId = null, $minConfidence = null)
240
    {
241
        $settings = $this->setImageSettings();
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $settings is correct as $this->setImageSettings() targeting Meema\MediaRecognition\R...ion::setImageSettings() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
242
243
        $settings['MinConfidence'] = $minConfidence ?? config('media-recognition.min_confidence');
244
245
        $results = $this->client->detectModerationLabels($settings);
0 ignored issues
show
Bug introduced by
$settings of type void is incompatible with the type array expected by parameter $args of Aws\Rekognition\Rekognit...etectModerationLabels(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

245
        $results = $this->client->detectModerationLabels(/** @scrutinizer ignore-type */ $settings);
Loading history...
246
247
        $this->updateOrCreate('moderation', $mediaId, $results);
248
249
        return $results;
250
    }
251
252
    /**
253
     * Detects text in an image (OCR).
254
     *
255
     * @param int|null $mediaId
256
     * @param int|null $minConfidence
257
     * @return \Aws\Result
258
     * @throws \Exception
259
     */
260
    public function detectText($mediaId = null, $minConfidence = null)
261
    {
262
        $settings = $this->setImageSettings();
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $settings is correct as $this->setImageSettings() targeting Meema\MediaRecognition\R...ion::setImageSettings() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
263
264
        $results = $this->client->detectText($settings);
0 ignored issues
show
Bug introduced by
$settings of type void is incompatible with the type array expected by parameter $args of Aws\Rekognition\RekognitionClient::detectText(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

264
        $results = $this->client->detectText(/** @scrutinizer ignore-type */ $settings);
Loading history...
265
266
        $this->updateOrCreate('ocr', $mediaId, $results);
267
268
        return $results;
269
    }
270
271
    /**
272
     * @param $type
273
     * @param $mediaId
274
     * @param $results
275
     * @return mixed
276
     * @throws \Exception
277
     */
278
    protected function updateOrCreate($type, $mediaId, $results)
279
    {
280
        if (! config('media-recognition.track_media_recognitions')) {
281
            return $results;
282
        }
283
284
        if (is_null($mediaId)) {
285
            throw new Exception('Please make sure to set a $mediaId.');
286
        }
287
288
        MediaRecognition::updateOrCreate([
289
            'model_id' => $mediaId,
290
            'model_type' => config('media-converter.media_model'),
291
        ], [$type => $results->toArray()]);
292
293
        return $results;
294
    }
295
296
    /**
297
     * @param $jobId
298
     * @return void
299
     * @throws \Exception
300
     */
301
    protected function updateJobId($jobId)
302
    {
303
        if (! config('media-recognition.track_media_recognitions')) {
304
            return;
305
        }
306
307
        if (is_null($this->mediaId)) {
308
            throw new Exception('Please make sure to set a $mediaId.');
309
        }
310
311
        MediaRecognition::updateOrCreate([
312
            'model_id' => $this->mediaId,
313
            'model_type' => config('media-converter.media_model'),
314
        ], ['job_id' => $jobId]);
315
    }
316
}
317