Completed
Push — master ( 7cb46a...8a709c )
by Andrew
12:32
created

ImageUtils::handleEntity()   B

Complexity

Conditions 6
Paths 2

Size

Total Lines 47
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 8
Bugs 2 Features 2
Metric Value
c 8
b 2
f 2
dl 0
loc 47
rs 8.5125
cc 6
eloc 27
nc 2
nop 3
1
<?php
2
3
namespace Goose\Images;
4
5
use Goose\Configuration;
6
7
/**
8
 * Image Utils
9
 *
10
 * @package Goose\Images
11
 * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
12
 */
13
class ImageUtils {
14
    /**
15
     * @param string $filePath
16
     *
17
     * @return object
18
     */
19
    public static function getImageDimensions($filePath) {
20
        list($width, $height, $type) = getimagesize($filePath);
21
22
        return (object)[
23
            'width' => $width,
24
            'height' => $height,
25
            'mime' => image_type_to_mime_type($type),
26
        ];
27
    }
28
29
    /**
30
     * Writes an image src http string to disk as a temporary file and returns the LocallyStoredImage object that has the info you should need
31
     * on the image
32
     *
33
     * @param string[] $imageSrcs
34
     * @param bool $returnAll
35
     * @param Configuration $config
36
     *
37
     * @return LocallyStoredImage[]
38
     */
39
    public static function storeImagesToLocalFile($imageSrcs, $returnAll, Configuration $config) {
40
        $localImages = self::handleEntity($imageSrcs, $returnAll, $config);
41
42
        if (empty($localImages)) {
43
            return [];
44
        }
45
46
        $locallyStoredImages = [];
47
48
        foreach ($localImages as $localImage) {
49
            $imageDetails = self::getImageDimensions($localImage->file);
50
51
            $locallyStoredImages[] = new LocallyStoredImage([
52
                'imgSrc' => $localImage->url,
53
                'localFileName' => $localImage->file,
54
                'bytes' => filesize($localImage->file),
55
                'height' => $imageDetails->height,
56
                'width' => $imageDetails->width,
57
                'fileExtension' => self::getFileExtensionName($imageDetails),
58
            ]);
59
        }
60
61
        return $locallyStoredImages;
62
    }
63
64
    /**
65
     * @param object $imageDetails
66
     *
67
     * @return string
68
     */
69
    private static function getFileExtensionName($imageDetails) {
70
        $extensions = [
71
            'image/gif' => '.gif',
72
            'image/jpeg' => '.jpg',
73
            'image/png' => '.png',
74
        ];
75
76
        return (
77
            isset($extensions[$imageDetails->mime])
78
            ? $extensions[$imageDetails->mime]
79
            : 'NA'
80
        );
81
    }
82
83
    /**
84
     * @param string[] $imageSrcs
85
     * @param bool $returnAll
86
     * @param Configuration $config
87
     *
88
     * @return object[]|null
89
     */
90
    private static function handleEntity($imageSrcs, $returnAll, $config) {
91
        $guzzle = new \GuzzleHttp\Client();
92
93
        $results = [];
94
95
        $requests = function($urls) use ($guzzle, $config, &$results) {
96
            foreach ($urls as $key => $url) {
97
                $file = tempnam(sys_get_temp_dir(), 'goose');
98
99
                $results[] = (object)[
100
                    'url' => $url,
101
                    'file' => $file,
102
                ];
103
104
                yield $key => function($options) use ($guzzle, $url, $file) {
105
                    $options['sink'] = $file;
106
107
                    return $guzzle->sendAsync(new \GuzzleHttp\Psr7\Request('GET', $url), $options);
108
                };
109
            }
110
        };
111
112
        $pool = new \GuzzleHttp\Pool($guzzle, $requests($imageSrcs), [
113
            'concurrency' => 25,
114
            'fulfilled' => function($response, $index) use (&$results, $returnAll) {
115
                if (!$returnAll && $response->getStatusCode() != 200) {
116
                    unset($results[$index]);
117
                }
118
            },
119
            'rejected' => function($reason, $index) use (&$results, $returnAll) {
120
                if ($returnAll) {
121
                    $results[$index]->file = null;
122
                } else {
123
                    unset($results[$index]);
124
                }
125
            },
126
            'options' => $config->get('browser'),
127
        ]);
128
129
        $pool->promise()->wait();
130
131
        if (empty($results)) {
132
            return null;
133
        }
134
135
        return $results;
136
    }
137
}
138