Completed
Push — master ( 36f767...4e930b )
by Milan
03:53
created

Queue::setSleep()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
3
namespace h4kuna\Fio\Request;
4
5
use GuzzleHttp,
6
	h4kuna\Fio,
7
	h4kuna\Fio\Response\Pay,
8
	Nette\Utils;
9
10
class Queue implements IQueue
11
{
12
13
	/** @var string[] */
14
	private static $tokens = [];
15
16
	/** @var int */
17
	private $limitLoop = 5;
18
19
	/** @var bool */
20
	private $sleep = TRUE;
21
22
	/** @var array */
23
	private $downloadOptions = [];
24
25
	public function setLimitLoop($limitLoop)
26
	{
27
		$this->limitLoop = $limitLoop;
28
	}
29
30
	public function setDownloadOptions($downloadOptions)
31
	{
32
		foreach ($downloadOptions as $define => $value) {
33
			if (is_string($define)) {
34
				if (!defined($define)) {
35
					throw new Fio\InvalidArgumentException('Value must be name of global constant like CURLOPT_*.');
36
				}
37
				$define = constant($define);
38
			}
39
			$this->downloadOptions[$define] = $value;
40
		}
41
	}
42
43
	public function setSleep($sleep)
44
	{
45
		$this->sleep = (bool) $sleep;
46
	}
47
48
	public function download($token, $url)
49
	{
50
		return $this->request($token, function(GuzzleHttp\Client $client) use ($url) {
51
				return $client->request('GET', $url, $this->downloadOptions);
52
			});
53
	}
54
55
	/** @return Pay\IResponse  */
56
	public function upload($url, $token, array $post, $filename)
57
	{
58
		$newPost = [];
59
		foreach ($post as $name => $value) {
60
			$newPost[] = ['name' => $name, 'contents' => $value];
61
		}
62
		$newPost[] = ['name' => 'file', 'contents' => fopen($filename, 'r')];
63
64
		/* @var $response GuzzleHttp\Psr7\Stream */
65
		$response = $this->request($token, function(GuzzleHttp\Client $client) use ($url, $newPost) {
66
			return $client->request('POST', $url, [GuzzleHttp\RequestOptions::MULTIPART => $newPost]);
67
		});
68
		return new Pay\XMLResponse($response->getContents());
69
	}
70
71
	private function request($token, $fallback)
72
	{
73
		$request = new GuzzleHttp\Client;
74
		$tempFile = self::loadFileName($token);
75
		$file = fopen(self::safeProtocol($tempFile), 'w');
76
		$i = 0;
77
		do {
78
			$next = FALSE;
79
			++$i;
80
			try {
81
				$response = $fallback($request);
82
			} catch (GuzzleHttp\Exception\ClientException $e) {
83
				if ($e->getCode() !== self::HEADER_CONFLICT || !$this->sleep) {
84
					fclose($file);
85
					throw $e;
86
				} elseif ($i >= $this->limitLoop) {
87
					fclose($file);
88
					throw new Fio\QueueLimitException('You have limit up requests to server ' . $this->limitLoop);
89
				}
90
				self::sleep($tempFile);
91
				$next = TRUE;
92
			}
93
		} while ($next);
94
		fclose($file);
95
		touch($tempFile);
96
		return $response->getBody();
97
	}
98
99
	private static function sleep($filename)
100
	{
101
		$criticalTime = time() - filemtime($filename);
102
		if ($criticalTime < self::WAIT_TIME) {
103
			sleep(self::WAIT_TIME - $criticalTime);
104
		}
105
	}
106
107
	/**
108
	 * @param string $token
109
	 * @return string
110
	 */
111
	private static function loadFileName($token)
112
	{
113
		$key = substr($token, 10, -10);
114
		if (!isset(self::$tokens[$key])) {
115
			self::$tokens[$key] = sys_get_temp_dir() . DIRECTORY_SEPARATOR . md5($key);
116
		}
117
118
		return self::$tokens[$key];
119
	}
120
121
	private static function safeProtocol($filename)
122
	{
123
		return Utils\SafeStream::PROTOCOL . '://' . $filename;
124
	}
125
126
}
127