PluginProbe
Analytify – Google Analytics Dashboard For WordPress (GA4 analytics tracking) / 1.0.1
Analytify – Google Analytics Dashboard For WordPress (GA4 analytics tracking) v1.0.1
9.1.2 9.1.1 9.1.0 9.0.2 9.0.1 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.1.0 1.1.1 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.3.0 1.3.1 1.3.2 All 153 releases
wp-analytify / lib / Google / Http / MediaFileUpload.php

MediaFileUpload.php in Analytify – Google Analytics Dashboard For WordPress (GA4 analytics tracking) 1.0.1, at lib/Google/Http/MediaFileUpload.php

293 lines 7.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Copyright 2012 Google Inc.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 require_once ANALYTIFY_LIB_PATH . 'Google/Client.php';
19 require_once ANALYTIFY_LIB_PATH . 'Google/Exception.php';
20 require_once ANALYTIFY_LIB_PATH . 'Google/Http/Request.php';
21 require_once ANALYTIFY_LIB_PATH . 'Google/Http/REST.php';
22 require_once ANALYTIFY_LIB_PATH . 'Google/Utils.php';
23
24 /**
25 * @author Chirag Shah <chirags@google.com>
26 *
27 */
28 class Analytify_Google_Http_MediaFileUpload
29 {
30 const UPLOAD_MEDIA_TYPE = 'media';
31 const UPLOAD_MULTIPART_TYPE = 'multipart';
32 const UPLOAD_RESUMABLE_TYPE = 'resumable';
33
34 /** @var string $mimeType */
35 private $mimeType;
36
37 /** @var string $data */
38 private $data;
39
40 /** @var bool $resumable */
41 private $resumable;
42
43 /** @var int $chunkSize */
44 private $chunkSize;
45
46 /** @var int $size */
47 private $size;
48
49 /** @var string $resumeUri */
50 private $resumeUri;
51
52 /** @var int $progress */
53 private $progress;
54
55 /** @var Analytify_Google_Client */
56 private $client;
57
58 /** @var Analytify_Google_Http_Request */
59 private $request;
60
61 /** @var string */
62 private $boundary;
63
64 /**
65 * Result code from last HTTP call
66 * @var int
67 */
68 private $httpResultCode;
69
70 /**
71 * @param $mimeType string
72 * @param $data string The bytes you want to upload.
73 * @param $resumable bool
74 * @param bool $chunkSize File will be uploaded in chunks of this many bytes.
75 * only used if resumable=True
76 */
77 public function __construct(
78 Analytify_Google_Client $client,
79 Analytify_Google_Http_Request $request,
80 $mimeType,
81 $data,
82 $resumable = false,
83 $chunkSize = false,
84 $boundary = false
85 ) {
86 $this->client = $client;
87 $this->request = $request;
88 $this->mimeType = $mimeType;
89 $this->data = $data;
90 $this->size = strlen($this->data);
91 $this->resumable = $resumable;
92 if (!$chunkSize) {
93 $chunkSize = 256 * 1024;
94 }
95 $this->chunkSize = $chunkSize;
96 $this->progress = 0;
97 $this->boundary = $boundary;
98
99 // Process Media Request
100 $this->process();
101 }
102
103 /**
104 * Set the size of the file that is being uploaded.
105 * @param $size - int file size in bytes
106 */
107 public function setFileSize($size)
108 {
109 $this->size = $size;
110 }
111
112 /**
113 * Return the progress on the upload
114 * @return int progress in bytes uploaded.
115 */
116 public function getProgress()
117 {
118 return $this->progress;
119 }
120
121 /**
122 * Return the HTTP result code from the last call made.
123 * @return int code
124 */
125 public function getHttpResultCode()
126 {
127 return $this->httpResultCode;
128 }
129
130 /**
131 * Send the next part of the file to upload.
132 * @param [$chunk] the next set of bytes to send. If false will used $data passed
133 * at construct time.
134 */
135 public function nextChunk($chunk = false)
136 {
137 if (false == $this->resumeUri) {
138 $this->resumeUri = $this->getResumeUri();
139 }
140
141 if (false == $chunk) {
142 $chunk = substr($this->data, $this->progress, $this->chunkSize);
143 }
144
145 $lastBytePos = $this->progress + strlen($chunk) - 1;
146 $headers = array(
147 'content-range' => "bytes $this->progress-$lastBytePos/$this->size",
148 'content-type' => $this->request->getRequestHeader('content-type'),
149 'content-length' => $this->chunkSize,
150 'expect' => '',
151 );
152
153 $httpRequest = new Analytify_Google_Http_Request(
154 $this->resumeUri,
155 'PUT',
156 $headers,
157 $chunk
158 );
159
160 if ($this->client->getClassConfig("Analytify_Google_Http_Request", "enable_gzip_for_uploads")) {
161 $httpRequest->enableGzip();
162 } else {
163 $httpRequest->disableGzip();
164 }
165
166 $response = $this->client->getIo()->makeRequest($httpRequest);
167 $response->setExpectedClass($this->request->getExpectedClass());
168 $code = $response->getResponseHttpCode();
169 $this->httpResultCode = $code;
170
171 if (308 == $code) {
172 // Track the amount uploaded.
173 $range = explode('-', $response->getResponseHeader('range'));
174 $this->progress = $range[1] + 1;
175
176 // Allow for changing upload URLs.
177 $location = $response->getResponseHeader('location');
178 if ($location) {
179 $this->resumeUri = $location;
180 }
181
182 // No problems, but upload not complete.
183 return false;
184 } else {
185 return Analytify_Google_Http_REST::decodeHttpResponse($response);
186 }
187 }
188
189 /**
190 * @param $meta
191 * @param $params
192 * @return array|bool
193 * @visible for testing
194 */
195 private function process()
196 {
197 $postBody = false;
198 $contentType = false;
199
200 $meta = $this->request->getPostBody();
201 $meta = is_string($meta) ? json_decode($meta, true) : $meta;
202
203 $uploadType = $this->getUploadType($meta);
204 $this->request->setQueryParam('uploadType', $uploadType);
205 $this->transformToUploadUrl();
206 $mimeType = $this->mimeType ?
207 $this->mimeType :
208 $this->request->getRequestHeader('content-type');
209
210 if (self::UPLOAD_RESUMABLE_TYPE == $uploadType) {
211 $contentType = $mimeType;
212 $postBody = is_string($meta) ? $meta : json_encode($meta);
213 } else if (self::UPLOAD_MEDIA_TYPE == $uploadType) {
214 $contentType = $mimeType;
215 $postBody = $this->data;
216 } else if (self::UPLOAD_MULTIPART_TYPE == $uploadType) {
217 // This is a multipart/related upload.
218 $boundary = $this->boundary ? $this->boundary : mt_rand();
219 $boundary = str_replace('"', '', $boundary);
220 $contentType = 'multipart/related; boundary=' . $boundary;
221 $related = "--$boundary\r\n";
222 $related .= "Content-Type: application/json; charset=UTF-8\r\n";
223 $related .= "\r\n" . json_encode($meta) . "\r\n";
224 $related .= "--$boundary\r\n";
225 $related .= "Content-Type: $mimeType\r\n";
226 $related .= "Content-Transfer-Encoding: base64\r\n";
227 $related .= "\r\n" . base64_encode($this->data) . "\r\n";
228 $related .= "--$boundary--";
229 $postBody = $related;
230 }
231
232 $this->request->setPostBody($postBody);
233
234 if (isset($contentType) && $contentType) {
235 $contentTypeHeader['content-type'] = $contentType;
236 $this->request->setRequestHeaders($contentTypeHeader);
237 }
238 }
239
240 private function transformToUploadUrl()
241 {
242 $base = $this->request->getBaseComponent();
243 $this->request->setBaseComponent($base . '/upload');
244 }
245
246 /**
247 * Valid upload types:
248 * - resumable (UPLOAD_RESUMABLE_TYPE)
249 * - media (UPLOAD_MEDIA_TYPE)
250 * - multipart (UPLOAD_MULTIPART_TYPE)
251 * @param $meta
252 * @return string
253 * @visible for testing
254 */
255 public function getUploadType($meta)
256 {
257 if ($this->resumable) {
258 return self::UPLOAD_RESUMABLE_TYPE;
259 }
260
261 if (false == $meta && $this->data) {
262 return self::UPLOAD_MEDIA_TYPE;
263 }
264
265 return self::UPLOAD_MULTIPART_TYPE;
266 }
267
268 private function getResumeUri()
269 {
270 $result = null;
271 $body = $this->request->getPostBody();
272 if ($body) {
273 $headers = array(
274 'content-type' => 'application/json; charset=UTF-8',
275 'content-length' => Analytify_Google_Utils::getStrLen($body),
276 'x-upload-content-type' => $this->mimeType,
277 'x-upload-content-length' => $this->size,
278 'expect' => '',
279 );
280 $this->request->setRequestHeaders($headers);
281 }
282
283 $response = $this->client->getIo()->makeRequest($this->request);
284 $location = $response->getResponseHeader('location');
285 $code = $response->getResponseHttpCode();
286
287 if (200 == $code && true == $location) {
288 return $location;
289 }
290 throw new Analytify_Google_Exception("Failed to start the resumable upload");
291 }
292 }
293