Completed
Push — ticket/25 ( 26e02b...aba345 )
by Marc
02:00
created

StreamReader::resetData()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
3
/**
4
 * fast-image-size stream reader
5
 * @package fast-image-size
6
 * @copyright (c) Marc Alexander <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace FastImageSize;
13
14
class StreamReader
15
{
16
	/** @var bool Flag whether allow_url_fopen is enabled */
17
	protected $isFopenEnabled = false;
18
19
	/** @var string Data retrieved from remote */
20
	public $data = '';
21
22
	/**
23
	 * Constructor for fastImageSize class
24
	 */
25 72
	public function __construct()
26
	{
27 72
		$iniGet = new \bantu\IniGetWrapper\IniGetWrapper();
28 72
		$this->isFopenEnabled = $iniGet->getBool('allow_url_fopen');
29 72
	}
30
31
	/**
32
	 * Reset stream reader data
33
	 */
34 72
	public function resetData()
35
	{
36 72
		$this->data = '';
37 72
	}
38
39
	/**
40
	 * Get image from specified path/source
41
	 *
42
	 * @param string $filename Path to image
43
	 * @param int $offset Offset at which reading of the image should start
44
	 * @param int $length Maximum length that should be read
45
	 * @param bool $forceLength True if the length needs to be the specified
46
	 *			length, false if not. Default: true
47
	 *
48
	 * @return false|string Image data or false if result was empty
49
	 */
50 69
	public function getImage($filename, $offset, $length, $forceLength = true)
51
	{
52 69
		if (empty($this->data))
53 69
		{
54 69
			$this->getImageData($filename, $offset, $length);
55 69
		}
56
57
		// Force length to expected one. Return false if data length
58
		// is smaller than expected length
59 69
		if ($forceLength === true)
60 69
		{
61 47
			return (strlen($this->data) < $length) ? false : substr($this->data, $offset, $length) ;
62
		}
63
64 39
		return empty($this->data) ? false : $this->data;
65
	}
66
67
	/**
68
	 * Get image data for specified filename with offset and length
69
	 *
70
	 * @param string $filename Path to image
71
	 * @param int $offset Offset at which reading of the image should start
72
	 * @param int $length Maximum length that should be read
73
	 */
74 69
	protected function getImageData($filename, $offset, $length)
75
	{
76
		// Check if we don't have a valid scheme according to RFC 3986 and
77
		// try to use file_get_contents in that case
78 69
		if (preg_match('#^([a-z][a-z0-9+\-.]+://)#i', $filename))
79 69
		{
80
			try
81
			{
82 1
				$body = $this->getSeekableImageData($filename, $offset);
83
84 1
				while (!$body->eof())
85
				{
86 1
					$readLength = min($length - strlen($this->data), 8192);
87 1
					$this->data .= $body->read($readLength);
88 1
					if ($readLength < 8192 || strlen($this->data == $readLength))
89 1
					{
90 1
						break;
91
					}
92 1
				}
93
			}
94 1
			catch (\GuzzleHttp\Exception\RequestException $exception)
95
			{
96
				// Silently fail in case of issues during guzzle request
97
			}
98 1
		}
99
100 69
		if (empty($this->data) && $this->isFopenEnabled)
101 69
		{
102 68
			$this->data = @file_get_contents($filename, null, null, $offset, $length);
103 68
		}
104 69
	}
105
106
	/**
107
	 * Get seekable image data in form of Guzzle stream interface
108
	 *
109
	 * @param string $filename Filename / URL to get
110
	 * @param int $offset Offset for response body
111
	 * @return \GuzzleHttp\Stream\StreamInterface|null Stream interface of
112
	 *		requested image or null if it could not be retrieved
113
	 */
114 27
	public function getSeekableImageData($filename, $offset)
115
	{
116 27
		$guzzleClient = new \GuzzleHttp\Client();
117
		// Set stream to true to not read full file data during request
118 27
		$response = $guzzleClient->get($filename, ['stream' => true]);
119
120 3
		$body = $response->getBody();
121
122 3
		if ($offset > 0 && !$body->eof())
123 3
		{
124
			$body->seek($offset);
125
		}
126
127 3
		return $body;
128
	}
129
}
130