Issues (35)

src/Recognizers/Rekognition.php (2 issues)

1
<?php
2
3
namespace Meema\MediaRecognition\Recognizers;
4
5
use Aws\Rekognition\RekognitionClient;
6
use Illuminate\Support\Facades\Storage;
7
use Illuminate\Support\Str;
8
use Meema\MediaRecognition\Contracts\MediaRecognition as MediaRecognitionInterface;
9
use Meema\MediaRecognition\Events\FacialAnalysisCompleted;
10
use Meema\MediaRecognition\Events\LabelAnalysisCompleted;
11
use Meema\MediaRecognition\Events\ModerationAnalysisCompleted;
12
use Meema\MediaRecognition\Events\TextAnalysisCompleted;
13
use Meema\MediaRecognition\Models\MediaRecognition;
14
use Meema\MediaRecognition\Traits\CanRecognizeImages;
15
use Meema\MediaRecognition\Traits\CanRecognizeVideos;
16
use Meema\MediaRecognition\Traits\InteractsWithStorage;
17
18
class Rekognition implements MediaRecognitionInterface
19
{
20
    use InteractsWithStorage, CanRecognizeImages, CanRecognizeVideos;
21
22
    /**
23
     * Client instance of MediaRecognition.
24
     *
25
     * @var \Aws\Rekognition\RekognitionClient
26
     */
27
    protected RekognitionClient $client;
28
29
    /**
30
     * The settings provided to the Rekognition job.
31
     *
32
     * @var array
33
     */
34
    protected array $settings;
35
36
    /**
37
     * Construct converter.
38
     *
39
     * @param \Aws\Rekognition\RekognitionClient $client
40
     * @throws \Exception
41
     */
42
    public function __construct(RekognitionClient $client)
43
    {
44
        $this->client = $client;
45
    }
46
47
    /**
48
     * Get the MediaRecognition Client.
49
     *
50
     * @return \Aws\Rekognition\RekognitionClient
51
     */
52
    public function getClient(): RekognitionClient
53
    {
54
        return $this->client;
55
    }
56
57
    /**
58
     * Detects labels/objects in an image.
59
     *
60
     * @param int|null $minConfidence
61
     * @param int|null $maxLabels
62
     * @return \Aws\Result
63
     * @throws \Exception
64
     */
65
    public function detectLabels($minConfidence = null, $maxLabels = null)
66
    {
67
        $this->ensureMimeTypeIsSet();
68
69
        if (Str::contains($this->mimeType, 'image')) {
70
            $result = $this->detectImageLabels($minConfidence, $maxLabels);
0 ignored issues
show
It seems like $maxLabels can also be of type integer; however, parameter $maxLabels of Meema\MediaRecognition\R...on::detectImageLabels() does only seem to accept null, maybe add an additional type check? ( Ignorable by Annotation )

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

70
            $result = $this->detectImageLabels($minConfidence, /** @scrutinizer ignore-type */ $maxLabels);
Loading history...
71
72
            // we need to manually fire the event for image analyses because unlike the video analysis,
73
            // AWS is not sending a webhook upon completion of the image analysis
74
            event(new LabelAnalysisCompleted($result->toArray(), $this->mediaId));
75
76
            return $result;
77
        }
78
79
        if (Str::contains($this->mimeType, 'video')) {
80
            return $this->detectVideoLabels($minConfidence, $maxLabels);
81
        }
82
83
        throw new \Exception('$mimeType does neither indicate being a video nor an image');
84
    }
85
86
    /**
87
     * Detects faces in an image & analyzes them.
88
     *
89
     * @param array $attributes
90
     * @return \Aws\Result
91
     * @throws \Exception
92
     */
93
    public function detectFaces($attributes = ['DEFAULT'])
94
    {
95
        $this->ensureMimeTypeIsSet();
96
97
        if (Str::contains($this->mimeType, 'image')) {
98
            $result = $this->detectImageFaces($attributes);
99
100
            // we need to manually fire the event for image analyses because unlike the video analysis,
101
            // AWS is not sending a webhook upon completion of the image analysis
102
            event(new FacialAnalysisCompleted($result->toArray(), $this->mediaId));
103
104
            return $result;
105
        }
106
107
        if (Str::contains($this->mimeType, 'video')) {
108
            return $this->detectVideoFaces($attributes);
109
        }
110
111
        throw new \Exception('$mimeType does neither indicate being a video nor an image');
112
    }
113
114
    /**
115
     * Detects moderation labels in an image.
116
     * This can be useful for children-friendly images or NSFW images.
117
     *
118
     * @param int|null $minConfidence
119
     * @return \Aws\Result
120
     * @throws \Exception
121
     */
122
    public function detectModeration($minConfidence = null)
123
    {
124
        $this->ensureMimeTypeIsSet();
125
126
        if (Str::contains($this->mimeType, 'image')) {
127
            $result = $this->detectImageModeration($minConfidence);
128
129
            // we need to manually fire the event for image analyses because unlike the video analysis,
130
            // AWS is not sending a webhook upon completion of the image analysis
131
            event(new ModerationAnalysisCompleted($result->toArray(), $this->mediaId));
132
133
            return $result;
134
        }
135
136
        if (Str::contains($this->mimeType, 'video')) {
137
            return $this->detectVideoModeration($minConfidence);
138
        }
139
140
        throw new \Exception('$mimeType does neither indicate being a video nor an image');
141
    }
142
143
    /**
144
     * Detects text in an image (OCR).
145
     *
146
     * @param array|null $filters
147
     * @return \Aws\Result
148
     * @throws \Exception
149
     */
150
    public function detectText(array $filters = null)
151
    {
152
        $this->ensureMimeTypeIsSet();
153
154
        if (Str::contains($this->mimeType, 'image')) {
155
            $result = $this->detectImageText($filters);
156
157
            // we need to manually fire the event for image analyses because unlike the video analysis,
158
            // AWS is not sending a webhook upon completion of the image analysis
159
            event(new TextAnalysisCompleted($result->toArray(), $this->mediaId));
160
161
            return $result;
162
        }
163
164
        if (Str::contains($this->mimeType, 'video')) {
165
            return $this->detectVideoText($filters);
166
        }
167
168
        throw new \Exception('$mimeType does neither indicate being a video nor an image');
169
    }
170
171
    /**
172
     * @param $type
173
     * @param $results
174
     * @return mixed
175
     * @throws \Exception
176
     */
177
    protected function updateOrCreate($type, $results)
178
    {
179
        MediaRecognition::updateOrCreate([
180
            'model_id' => $this->mediaId,
181
            'model_type' => config('media-converter.media_model'),
182
        ], [$type => $results->toArray()]);
183
184
        return $results;
185
    }
186
187
    /**
188
     * @param string $jobId
189
     * @param string $type
190
     * @return void
191
     * @throws \Exception
192
     */
193
    protected function updateJobId(string $jobId, string $type)
194
    {
195
        if (is_null($this->mediaId)) {
196
            return;
197
        }
198
199
        MediaRecognition::updateOrCreate([
200
            'model_id' => $this->mediaId,
201
            'model_type' => config('media-converter.media_model'),
202
        ], [$type.'_job_id' => $jobId]);
203
    }
204
205
    /**
206
     * @param array $results
207
     * @param string $type
208
     * @param int $mediaId
209
     * @return void
210
     */
211
    protected function updateVideoResults(array $results, string $type, int $mediaId)
212
    {
213
        $mediaRecognition = MediaRecognition::where('model_id', $mediaId)->firstOrFail();
214
        $mediaRecognition->$type = $results;
215
        $mediaRecognition->save();
216
    }
217
218
    protected function ensureMimeTypeIsSet()
219
    {
220
        if (is_null($this->mimeType)) {
221
            $this->mimeType = Storage::disk(config('media-recognition.disk'))->mimeType($this->source);
0 ignored issues
show
Documentation Bug introduced by
It seems like Illuminate\Support\Facad...mimeType($this->source) can also be of type false. However, the property $mimeType is declared as type null|string. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
222
        }
223
    }
224
}
225