Completed
Push — master ( d78672...cd588e )
by Sam
02:00
created

GoogleCloudVision   B

Complexity

Total Complexity 37

Size/Duplication

Total Lines 332
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 37
c 1
b 0
f 0
lcom 1
cbo 3
dl 0
loc 332
rs 8.6

23 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A setEndpoint() 0 4 1
A setImageMaxSize() 0 7 2
B setImage() 0 15 5
A convertImgtoBased64() 0 13 2
A setRequestBody() 0 13 4
A addFeature() 0 10 2
A setImageContext() 0 8 2
A addFeatureUnspecified() 0 4 1
A addFeatureFaceDetection() 0 4 1
A addFeatureLandmarkDetection() 0 4 1
A addFeatureLogoDetection() 0 4 1
A addFeatureLabelDetection() 0 4 1
A addFeatureTextDetection() 0 4 1
A addFeatureOCR() 0 4 1
A addFeatureDocumentTextDetection() 0 4 1
A addFeatureSafeSeachDetection() 0 4 1
A addFeatureImageProperty() 0 4 1
A addFeatureCropHints() 0 4 1
A addFeatureWebDetection() 0 4 1
A request() 0 18 4
A setKey() 0 4 1
A requestServer() 0 6 1
1
<?php
2
/**
3
 * This file contains only the GoogleCloudVision class.
4
 */
5
6
namespace Wikisource\GoogleCloudVisionPHP;
7
8
use Exception;
9
use GuzzleHttp\Client;
10
11
class GoogleCloudVision
12
{
13
14
    protected $features = array();
15
    protected $imageContext = array();
16
    protected $image = array();
17
    protected $requestBody = array();
18
    protected $version = "v1";
19
    protected $endpoint = "https://vision.googleapis.com/";
20
    protected $key;
21
22
    /** @var int The maximum size allowed for the image, in bytes. */
23
    protected $imageMaxSize;
24
25
    /** @var string Image type: Google Cloud Storage URI. Note the typo. */
26
    const IMAGE_TYPE_GCS = 'GSC';
27
28
    /** @var string Image type: file path or URL. */
29
    const IMAGE_TYPE_FILE = 'FILE';
30
31
    /** @var string Image type: raw data. */
32
    const IMAGE_TYPE_RAW = 'RAW';
33
34
    /**
35
     * Create a new GCV API object.
36
     */
37
    public function __construct()
38
    {
39
        $this->imageMaxSize = 1024 * 1024 * 4;
40
    }
41
42
    /**
43
     * Change the URL for the API endpoint. Defaults to https://vision.googleapis.com/ but may need to be changed for
44
     * various reasons (e.g. if routing through a proxy server).
45
     *
46
     * @param string $newEndpoint The new URL of the API endpoint.
47
     */
48
    public function setEndpoint($newEndpoint)
49
    {
50
        $this->endpoint = $newEndpoint;
51
    }
52
53
    /**
54
     * Set the permitted maximum size of images.
55
     * This defaults to 4 MB as per the Google Cloud Vision API limits documentation.
56
     *
57
     * @param int $newSize
58
     * @throws Exception
59
     */
60
    public function setImageMaxSize($newSize)
61
    {
62
        if (!is_int($newSize)) {
63
            throw new Exception("Image size must be specified in integer bytes, '$newSize' given");
64
        }
65
        $this->imageMaxSize = $newSize;
66
    }
67
68
    /**
69
     * Set the image that will be sent to the API.
70
     *
71
     * An image can be set from a filename or URL, raw data, or a Google Cloud Storage item.
72
     *
73
     * A Google Cloud Storage image URI must be in the following form: gs://bucket_name/object_name.
74
     * Object versioning is not supported.
75
     * Read more: https://cloud.google.com/vision/reference/rest/v1/images/annotate#imagesource
76
     *
77
     * @param mixed $input The filename, URL, data, etc.
78
     * @param string $type The type that $input should be treated as.
79
     * @return string[] The request body.
80
     * @throws LimitExceededException When the image size is over the maximum permitted.
81
     */
82
    public function setImage($input, $type = self::IMAGE_TYPE_FILE)
83
    {
84
        if ($type === self::IMAGE_TYPE_GCS) {
85
            $this->image['source']['gcsImageUri'] = $input;
86
        } elseif ($type === self::IMAGE_TYPE_FILE) {
87
            $this->image['content'] = $this->convertImgtoBased64($input);
88
        } elseif ($type === self::IMAGE_TYPE_RAW) {
89
            $size = strlen($input);
90
            if ($size > $this->imageMaxSize) {
91
                throw new LimitExceededException("Image size ($size) exceeds permitted size ($this->imageMaxSize)", 1);
92
            }
93
            $this->image['content'] = base64_encode($input);
94
        }
95
        return $this->setRequestBody();
96
    }
97
98
    /**
99
     * Fetch base64-encoded data of the specified image.
100
     *
101
     * @param string $path Path to the image file. Anything supported by file_get_contents is suitable.
102
     * @return string The encoded data as a string or FALSE on failure.
103
     * @throws LimitExceededException When the image size is over the maximum permitted.
104
     */
105
    public function convertImgtoBased64($path)
106
    {
107
        // Get the data.
108
        $data = file_get_contents($path);
109
        // Check the size.
110
        $size = strlen($data);
111
        if ($size > $this->imageMaxSize) {
112
            $msg = "Image size of %s (%s) exceeds permitted size (%s)";
113
            throw new LimitExceededException(sprintf($msg, $path, $size, $this->imageMaxSize), 2);
114
        }
115
        // Return encoded data.
116
        return base64_encode($data);
117
    }
118
119
    /**
120
     * Set the request body, based on the image, features, and imageContext.
121
     *
122
     * @return string[]
123
     */
124
    protected function setRequestBody()
125
    {
126
        if (!empty($this->image)) {
127
            $this->requestBody['requests'][0]['image'] = $this->image;
128
        }
129
        if (!empty($this->features)) {
130
            $this->requestBody['requests'][0]['features'] = $this->features;
131
        }
132
        if (!empty($this->imageContext)) {
133
            $this->requestBody['requests'][0]['imageContext'] = $this->imageContext;
134
        }
135
        return $this->requestBody;
136
    }
137
138
    /**
139
     * Add a feature request.
140
     * @link https://cloud.google.com/vision/docs/reference/rest/v1/images/annotate#Type
141
     * @deprecated Use one of the explicit addFeature* methods instead.
142
     * @todo Make this protected visibility.
143
     * @param string $type One of the type values.
144
     * @param int $maxResults
145
     * @return string[]
146
     * @throws Exception
147
     */
148
    public function addFeature($type, $maxResults = 1)
149
    {
150
151
        if (!is_numeric($maxResults)) {
152
            throw new Exception("maxResults variable is not valid it should be Integer.", 1);
153
        }
154
155
        $this->features[] = array("type" => $type, "maxResults" => $maxResults);
156
        return $this->setRequestBody();
157
    }
158
159
    public function setImageContext($imageContext)
160
    {
161
        if (!is_array($imageContext)) {
162
            throw new Exception("imageContext variable is not valid it should be Array.", 1);
163
        }
164
        $this->imageContext = $imageContext;
165
        return $this->setRequestBody();
166
    }
167
168
    /**
169
     * Unspecified feature type.
170
     * @param int $maxResults
171
     * @return string[]
172
     */
173
    public function addFeatureUnspecified($maxResults = 1)
174
    {
175
        return $this->addFeature("TYPE_UNSPECIFIED", $maxResults);
0 ignored issues
show
Deprecated Code introduced by
The method Wikisource\GoogleCloudVi...oudVision::addFeature() has been deprecated with message: Use one of the explicit addFeature* methods instead.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
176
    }
177
178
    /**
179
     * Run face detection.
180
     * @param int $maxResults
181
     * @return string[]
182
     */
183
    public function addFeatureFaceDetection($maxResults = 1)
184
    {
185
        return $this->addFeature("FACE_DETECTION", $maxResults);
0 ignored issues
show
Deprecated Code introduced by
The method Wikisource\GoogleCloudVi...oudVision::addFeature() has been deprecated with message: Use one of the explicit addFeature* methods instead.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
186
    }
187
188
    /**
189
     * Run landmark detection.
190
     * @param int $maxResults
191
     * @return string[]
192
     */
193
    public function addFeatureLandmarkDetection($maxResults = 1)
194
    {
195
        return $this->addFeature("LANDMARK_DETECTION", $maxResults);
0 ignored issues
show
Deprecated Code introduced by
The method Wikisource\GoogleCloudVi...oudVision::addFeature() has been deprecated with message: Use one of the explicit addFeature* methods instead.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
196
    }
197
198
    /**
199
     * Run logo detection.
200
     * @param int $maxResults
201
     * @return string[]
202
     */
203
    public function addFeatureLogoDetection($maxResults = 1)
204
    {
205
        return $this->addFeature("LOGO_DETECTION", $maxResults);
0 ignored issues
show
Deprecated Code introduced by
The method Wikisource\GoogleCloudVi...oudVision::addFeature() has been deprecated with message: Use one of the explicit addFeature* methods instead.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
206
    }
207
208
    /**
209
     * Run label detection.
210
     * @param int $maxResults
211
     * @return string[]
212
     */
213
    public function addFeatureLabelDetection($maxResults = 1)
214
    {
215
        return $this->addFeature("LABEL_DETECTION", $maxResults);
0 ignored issues
show
Deprecated Code introduced by
The method Wikisource\GoogleCloudVi...oudVision::addFeature() has been deprecated with message: Use one of the explicit addFeature* methods instead.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
216
    }
217
218
    /**
219
     * Run OCR.
220
     * @param int $maxResults
221
     * @return string[]
222
     */
223
    public function addFeatureTextDetection($maxResults = 1)
224
    {
225
        return $this->addFeature("TEXT_DETECTION", $maxResults);
0 ignored issues
show
Deprecated Code introduced by
The method Wikisource\GoogleCloudVi...oudVision::addFeature() has been deprecated with message: Use one of the explicit addFeature* methods instead.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
226
    }
227
228
    /**
229
     * Run OCR.
230
     * @deprecated Use self::addFeatureTextDetection() instead.
231
     * @param int $maxResults
232
     * @return string[]
233
     */
234
    public function addFeatureOCR($maxResults = 1)
235
    {
236
        return $this->addFeatureTextDetection($maxResults);
237
    }
238
239
    /**
240
     * Run dense text document OCR. Takes precedence when both DOCUMENT_TEXT_DETECTION and TEXT_DETECTION are present.
241
     * @param int $maxResults
242
     * @return string[]
243
     */
244
    public function addFeatureDocumentTextDetection($maxResults = 1)
245
    {
246
        return $this->addFeature("DOCUMENT_TEXT_DETECTION", $maxResults);
0 ignored issues
show
Deprecated Code introduced by
The method Wikisource\GoogleCloudVi...oudVision::addFeature() has been deprecated with message: Use one of the explicit addFeature* methods instead.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
247
    }
248
249
    /**
250
     * Run computer vision models to compute image safe-search properties.
251
     * @param int $maxResults
252
     * @return string[]
253
     */
254
    public function addFeatureSafeSeachDetection($maxResults = 1)
255
    {
256
        return $this->addFeature("SAFE_SEARCH_DETECTION", $maxResults);
0 ignored issues
show
Deprecated Code introduced by
The method Wikisource\GoogleCloudVi...oudVision::addFeature() has been deprecated with message: Use one of the explicit addFeature* methods instead.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
257
    }
258
259
    /**
260
     * Compute a set of image properties, such as the image's dominant colors.
261
     * @param int $maxResults
262
     * @return string[]
263
     */
264
    public function addFeatureImageProperty($maxResults = 1)
265
    {
266
        return $this->addFeature("IMAGE_PROPERTIES", $maxResults);
0 ignored issues
show
Deprecated Code introduced by
The method Wikisource\GoogleCloudVi...oudVision::addFeature() has been deprecated with message: Use one of the explicit addFeature* methods instead.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
267
    }
268
269
    /**
270
     * Run crop hints.
271
     * @param int $maxResults
272
     * @return string[]
273
     */
274
    public function addFeatureCropHints($maxResults = 1)
275
    {
276
        return $this->addFeature("CROP_HINTS", $maxResults);
0 ignored issues
show
Deprecated Code introduced by
The method Wikisource\GoogleCloudVi...oudVision::addFeature() has been deprecated with message: Use one of the explicit addFeature* methods instead.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
277
    }
278
279
    /**
280
     * Run web detection.
281
     * @param int $maxResults
282
     * @return string[]
283
     */
284
    public function addFeatureWebDetection($maxResults = 1)
285
    {
286
        return $this->addFeature("WEB_DETECTION", $maxResults);
0 ignored issues
show
Deprecated Code introduced by
The method Wikisource\GoogleCloudVi...oudVision::addFeature() has been deprecated with message: Use one of the explicit addFeature* methods instead.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
287
    }
288
289
    /**
290
     * Send the request to Google and get the results.
291
     *
292
     * @param string $apiMethod Which API method to use. Currently can only be 'annotate'.
293
     *
294
     * @return string[] The results of the request.
295
     * @throws Exception If any of the key, features, or image have not been set yet.
296
     */
297
    public function request($apiMethod = "annotate")
298
    {
299
        if (empty($this->key) === true) {
300
            $msg = "API Key is empty, please grant from https://console.cloud.google.com/apis/credentials";
301
            throw new Exception($msg);
302
        }
303
304
        if (empty($this->features) === true) {
305
            throw new Exception("Features is can't empty.", 1);
306
        }
307
308
        if (empty($this->image) === true) {
309
            throw new Exception("Images is can't empty.", 1);
310
        }
311
312
        $url = $this->endpoint.$this->version."/images:$apiMethod?key=".$this->key;
313
        return $this->requestServer($url, $this->requestBody);
314
    }
315
316
    /**
317
     * Set the API key.
318
     *
319
     * @param string $key The API key.
320
     *
321
     * @return void
322
     */
323
    public function setKey($key)
324
    {
325
        $this->key = $key;
326
    }
327
328
    /**
329
     * Execute the request and return the result.
330
     *
331
     * @param string $url The full URL to query.
332
     * @param string[] $data The data to send.
333
     *
334
     * @return string[] The resulting information about the image.
335
     */
336
    protected function requestServer($url, $data)
337
    {
338
        $client = new Client();
339
        $result = $client->post($url, ['json' => $data]);
340
        return \GuzzleHttp\json_decode($result->getBody(), true);
341
    }
342
}
343