|
1
|
|
|
<?php |
|
2
|
|
|
/** |
|
3
|
|
|
* Created by PhpStorm. |
|
4
|
|
|
* User: hborras |
|
5
|
|
|
* Date: 1/07/16 |
|
6
|
|
|
* Time: 21:35 |
|
7
|
|
|
*/ |
|
8
|
|
|
|
|
9
|
|
|
namespace Hborras\TwitterAdsSDK; |
|
10
|
|
|
|
|
11
|
|
|
|
|
12
|
|
|
class TONUpload |
|
13
|
|
|
{ |
|
14
|
|
|
const DEFAULT_DOMAIN = 'https://ton.twitter.com'; |
|
15
|
|
|
const DEFAULT_RESOURCE = '/1.1/ton/bucket/'; |
|
16
|
|
|
const DEFAULT_BUCKET = 'ta_partner'; |
|
17
|
|
|
const MIN_FILE_SIZE = 1048576; |
|
18
|
|
|
|
|
19
|
|
|
private $filePath; |
|
20
|
|
|
private $fileSize; |
|
21
|
|
|
/** @var TwitterAds */ |
|
22
|
|
|
private $twitterAds; |
|
23
|
|
|
private $params; |
|
24
|
|
|
|
|
25
|
|
|
public function __construct(TwitterAds $twitterAds, $filePath, $params = []) |
|
26
|
|
|
{ |
|
27
|
|
|
if (!file_exists($filePath)) { |
|
|
|
|
|
|
28
|
|
|
// TODO: Throw Exception |
|
29
|
|
|
} |
|
30
|
|
|
$this->filePath = $filePath; |
|
31
|
|
|
$this->fileSize = filesize($filePath); |
|
32
|
|
|
$this->twitterAds = $twitterAds; |
|
33
|
|
|
$this->params = $params; |
|
34
|
|
|
} |
|
35
|
|
|
|
|
36
|
|
|
public function getContentType() |
|
37
|
|
|
{ |
|
38
|
|
|
if (isset($this->contentType)) { |
|
39
|
|
|
return $this->contentType; |
|
|
|
|
|
|
40
|
|
|
} |
|
41
|
|
|
|
|
42
|
|
|
$extension = pathinfo($this->filePath, PATHINFO_EXTENSION); |
|
43
|
|
|
|
|
44
|
|
|
if ($extension == 'csv') { |
|
45
|
|
|
$this->contentType = 'text/csv'; |
|
46
|
|
|
} else if ($extension == 'tsv') { |
|
47
|
|
|
$this->contentType = 'text/tab-separated-values'; |
|
48
|
|
|
} else { |
|
49
|
|
|
$this->contentType = 'text/plain'; |
|
50
|
|
|
} |
|
51
|
|
|
|
|
52
|
|
|
return $this->contentType; |
|
53
|
|
|
} |
|
54
|
|
|
|
|
55
|
|
|
public function perform() |
|
56
|
|
|
{ |
|
57
|
|
|
if ($this->fileSize < self::MIN_FILE_SIZE) { |
|
58
|
|
|
$response = $this->upload(); |
|
59
|
|
|
return $response->getsHeaders()['location']; |
|
60
|
|
|
} else { |
|
61
|
|
|
$response = $this->initChunkedUpload(); |
|
62
|
|
|
$responseHeaders = $response->getsHeaders(); |
|
63
|
|
|
$chunkSize = intval($responseHeaders['x_ton_min_chunk_size']); |
|
64
|
|
|
$location = $responseHeaders['location']; |
|
65
|
|
|
|
|
66
|
|
|
$file = fopen($this->filePath, 'rb'); |
|
67
|
|
|
$bytesRead = 0; |
|
68
|
|
|
while (!feof($file)) { |
|
69
|
|
|
$bytes = fread($file, $chunkSize); |
|
70
|
|
|
$bytesStart = $bytesRead; |
|
71
|
|
|
$bytesRead += strlen($bytes); |
|
72
|
|
|
$this->uploadChunk($location, $chunkSize, $bytes, $bytesStart, $bytesRead); |
|
73
|
|
|
} |
|
74
|
|
|
fclose($file); |
|
75
|
|
|
|
|
76
|
|
|
return $location; |
|
77
|
|
|
} |
|
78
|
|
|
} |
|
79
|
|
|
|
|
80
|
|
|
public function upload() |
|
81
|
|
|
{ |
|
82
|
|
|
/** Here you can add any header you want to the request*/ |
|
83
|
|
|
$headers = [ |
|
84
|
|
|
'x-ton-expires: ' . gmdate('D, d M Y H:i:s T', strtotime("+10 day")), |
|
85
|
|
|
'content-type: ' . $this->getContentType(), |
|
86
|
|
|
'Content-Length: ' . $this->fileSize |
|
87
|
|
|
]; |
|
88
|
|
|
|
|
89
|
|
|
$response = $this->getTwitterAds()->post(self::DEFAULT_DOMAIN.self::DEFAULT_RESOURCE.self::DEFAULT_BUCKET, ['raw' => file_get_contents($this->filePath)], $headers); |
|
90
|
|
|
return $response; |
|
91
|
|
|
} |
|
92
|
|
|
|
|
93
|
|
|
public function uploadChunk($resource, $chunkSize, $bytes, $bytesStart, $bytesRead) |
|
|
|
|
|
|
94
|
|
|
{ |
|
95
|
|
|
$headers = [ |
|
96
|
|
|
'Content-Type: ' . $this->getContentType(), |
|
97
|
|
|
'Content-Range: bytes ' . $bytesStart . '-' . ($bytesRead - 1) . '/' . $this->fileSize |
|
98
|
|
|
]; |
|
99
|
|
|
$response = $this->getTwitterAds()->put(self::DEFAULT_DOMAIN.$resource, ['raw' => $bytes], $headers); |
|
100
|
|
|
|
|
101
|
|
|
return $response; |
|
102
|
|
|
} |
|
103
|
|
|
|
|
104
|
|
|
public function initChunkedUpload() |
|
105
|
|
|
{ |
|
106
|
|
|
$headers = [ |
|
107
|
|
|
'X-Ton-Content-Type: ' . $this->getContentType(), |
|
108
|
|
|
'X-Ton-Content-Length: ' . $this->fileSize, |
|
109
|
|
|
'X-Ton-Expires: ' . gmdate('D, d M Y H:i:s T', strtotime("+6 day")), |
|
110
|
|
|
'Content-Type: ' . $this->getContentType(), |
|
111
|
|
|
'Content-Length: ' . strval(0) |
|
112
|
|
|
]; |
|
113
|
|
|
|
|
114
|
|
|
$resource = self::DEFAULT_DOMAIN.self::DEFAULT_RESOURCE.self::DEFAULT_BUCKET. '?resumable=true'; |
|
115
|
|
|
$response = $this->getTwitterAds()->post($resource, [], $headers); |
|
116
|
|
|
return $response; |
|
117
|
|
|
} |
|
118
|
|
|
|
|
119
|
|
|
/** |
|
120
|
|
|
* @return mixed |
|
121
|
|
|
*/ |
|
122
|
|
|
public function getFilePath() |
|
123
|
|
|
{ |
|
124
|
|
|
return $this->filePath; |
|
125
|
|
|
} |
|
126
|
|
|
|
|
127
|
|
|
/** |
|
128
|
|
|
* @param mixed $filePath |
|
129
|
|
|
*/ |
|
130
|
|
|
public function setFilePath($filePath) |
|
131
|
|
|
{ |
|
132
|
|
|
$this->filePath = $filePath; |
|
133
|
|
|
} |
|
134
|
|
|
|
|
135
|
|
|
/** |
|
136
|
|
|
* @return mixed |
|
137
|
|
|
*/ |
|
138
|
|
|
public function getFileSize() |
|
139
|
|
|
{ |
|
140
|
|
|
return $this->fileSize; |
|
141
|
|
|
} |
|
142
|
|
|
|
|
143
|
|
|
/** |
|
144
|
|
|
* @param mixed $fileSize |
|
145
|
|
|
*/ |
|
146
|
|
|
public function setFileSize($fileSize) |
|
147
|
|
|
{ |
|
148
|
|
|
$this->fileSize = $fileSize; |
|
149
|
|
|
} |
|
150
|
|
|
|
|
151
|
|
|
/** |
|
152
|
|
|
* @return TwitterAds |
|
153
|
|
|
*/ |
|
154
|
|
|
public function getTwitterAds() |
|
155
|
|
|
{ |
|
156
|
|
|
return $this->twitterAds; |
|
157
|
|
|
} |
|
158
|
|
|
|
|
159
|
|
|
/** |
|
160
|
|
|
* @param mixed $twitterAds |
|
161
|
|
|
*/ |
|
162
|
|
|
public function setTwitterAds($twitterAds) |
|
163
|
|
|
{ |
|
164
|
|
|
$this->twitterAds = $twitterAds; |
|
165
|
|
|
} |
|
166
|
|
|
|
|
167
|
|
|
/** |
|
168
|
|
|
* @return mixed |
|
169
|
|
|
*/ |
|
170
|
|
|
public function getParams() |
|
171
|
|
|
{ |
|
172
|
|
|
return $this->params; |
|
173
|
|
|
} |
|
174
|
|
|
|
|
175
|
|
|
/** |
|
176
|
|
|
* @param mixed $params |
|
177
|
|
|
*/ |
|
178
|
|
|
public function setParams($params) |
|
179
|
|
|
{ |
|
180
|
|
|
$this->params = $params; |
|
181
|
|
|
} |
|
182
|
|
|
} |
This check looks for the bodies of
ifstatements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.These
ifbodies can be removed. If you have an empty if but statements in theelsebranch, consider inverting the condition.could be turned into
This is much more concise to read.