Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
photouploader.php
1<?php
2
4
14
15Loc::loadMessages(__FILE__);
16
23{
24 private $exportId;
25 private $vk;
26 private $api;
27 private $logger;
28 private $type;
29 private $timer;
30 private $vkGroupId;
31 private $params = [];
32
33 const TYPE_PRODUCT_MAIN_PHOTO = 'PRODUCT_MAIN_PHOTO';
34 const TYPE_PRODUCT_PHOTOS = 'PRODUCT_PHOTOS';
35 const TYPE_ALBUM_PHOTO = 'ALBUM_PHOTO';
36
37 public function __construct($exportId, $photoType, Timer $timer = null)
38 {
39 if (empty($exportId))
40 {
41 throw new ArgumentNullException('exportId');
42 }
43
44 if (empty($photoType))
45 {
46 throw new ArgumentNullException('photoType');
47 }
48
49 $this->exportId = $exportId;
50 $this->type = $photoType;
51 $this->timer = $timer;
52 $this->vk = Vk::getInstance();
53 $this->vkGroupId = $this->vk->getGroupId($this->exportId);
54 $this->api = $this->vk->getApi($exportId);
55 $this->logger = new Logger($this->exportId);
56
57 $this->initByType();
58 }
59
60
65 protected function initByType()
66 {
67 $this->type;
68
69 switch ($this->type)
70 {
72 $this->params['uploadServerMethod']= 'photos.getMarketUploadServer';
73 $this->params['saveMethod'] = 'photos.saveMarketPhoto';
74 $this->params['keyReference'] = 'BX_ID';
75 $this->params['keyPhotoVk'] = 'PHOTO_MAIN_VK_ID';
76 $this->params['keyPhotoBx'] = 'PHOTO_MAIN_BX_ID';
77 $this->params['keyPhotoUrl']= 'PHOTO_MAIN_URL';
78 break;
79
81 $this->params['uploadServerMethod']= 'photos.getMarketUploadServer';
82 $this->params['saveMethod'] = 'photos.saveMarketPhoto';
83 $this->params['keyReference'] = 'PHOTO_BX_ID';
84 $this->params['keyPhotoVk'] = 'PHOTO_VK_ID';
85 $this->params['keyPhotoBx'] = 'PHOTO_BX_ID';
86 $this->params['keyPhotoUrl']= 'PHOTO_URL';
87 break;
88
90 $this->params['uploadServerMethod']= 'photos.getMarketAlbumUploadServer';
91 $this->params['saveMethod'] = 'photos.saveMarketAlbumPhoto';
92 $this->params['keyReference'] = 'SECTION_ID';
93 $this->params['keyPhotoVk'] = 'PHOTO_VK_ID';
94 $this->params['keyPhotoBx'] = 'PHOTO_BX_ID';
95 $this->params['keyPhotoUrl']= 'PHOTO_URL';
96 break;
97
98 default:
99 throw new SystemException("Wrong photo upload type");
100 break;
101 }
102 }
103
111 public function upload($data)
112 {
113// todo: this is a little kostyl. In cool variant we must separately do http-upload,
114// todo: and photo save run through execute method
115// todo: but now VK can't run savePhotoMethod through execute. Sadness ((
116
117// PARAMS set
118 $photoSaveResults = array();
119
120
121// PROCESSED
122 foreach ($data as $item)
123 {
124// check EXISTING photo
125 if (!array_key_exists($this->params['keyPhotoBx'], $item) || empty($item[$this->params['keyPhotoBx']]))
126 {
127 continue;
128 }
129
130// GET upload server by type
131 $getServerParams = array("group_id" => str_replace("-", "", $this->vkGroupId));
132 if ($this->type == 'PRODUCT_MAIN_PHOTO')
133 {
134 $getServerParams += self::setUploadServerMainPhotoParams($item[$this->params['keyPhotoBx']]);
135 }
136
137 $uploadServer = $this->api->run($this->params['uploadServerMethod'], $getServerParams);
138// todo: may be this error in upload server response
139 $this->logger->addLog("Get photo upload server", [
140 'PARAMS' => $getServerParams,
141 'RESULT' => $uploadServer,
142 ]);
143 $uploadServer = $uploadServer["upload_url"];
144
145
146// UPLOAD photo by http
147 $this->logger->addLog("Upload photo HTTP before", array(
148 "UPLOAD_TYPE" => $this->type,
149 "ITEM" => array_key_exists("BX_ID", $item) ?
150 $item["BX_ID"] . ': ' . $item["NAME"] :
151 $item["SECTION_ID"] . ': ' . $item["TITLE"],
152 "PHOTO_BX_ID" => array_key_exists("PHOTO_MAIN_BX_ID",
153 $item) ? $item["PHOTO_MAIN_BX_ID"] : $item["PHOTO_BX_ID"],
154 "PHOTO_URL" => array_key_exists("PHOTO_MAIN_URL", $item) ? $item["PHOTO_MAIN_URL"] : $item["PHOTO_URL"],
155 "PHOTOS" => $item["PHOTOS"] //only for products
156 ));
157 $uploadHttpResult = $this->uploadHttp($item, $uploadServer);
158// if not response - was be ERROR in http upload. SKIP saving
159 if($uploadHttpResult === false)
160 {
161 if(!$photoSaveResults['errors'])
162 {
163 $photoSaveResults['errors'] = [];
164 }
165 $photoSaveResults['errors'][] = $item[$this->params['keyReference']];
166 continue;
167 }
168
169 $savePhotoResult = $this->savePhoto($uploadHttpResult);
170// RESULT
171 $photoSaveResults[$item[$this->params['keyReference']]] = array(
172 $this->params['keyReference'] => $item[$this->params['keyReference']],
173 $this->params['keyPhotoVk'] => $savePhotoResult[0]["id"],
174 );
175// todo: photo mapping. po odnomu, navernoe, ved timer
176 }
177
178 return $photoSaveResults;
179 }
180
181
190 private function uploadHttp($data, $uploadServer)
191 {
192 $postParams = array(
193 "url" => $data[$this->params['keyPhotoUrl']],
194 "filename" => IO\Path::getName($data[$this->params['keyPhotoUrl']]),
195 "param_name" => 'file',
196 );
197
198 $http = new HttpClient();
199
200 $boundary = md5(rand() . time());
201 $file = $this->getFile($postParams["url"]);
202
203 $request = '--' . $boundary . "\r\n";
204 $request .= 'Content-Disposition: form-data; name="' . $postParams["param_name"] . '"; filename="' . $postParams["filename"] . '"' . "\r\n";
205 $request .= 'Content-Type: application/octet-stream' . "\r\n\r\n";
206 $request .= $file . "\r\n";
207 $request .= '--' . $boundary . "--\r\n";
208
209 $http->setHeader('Content-type', 'multipart/form-data; boundary=' . $boundary);
210 $http->setHeader('Content-length', \Bitrix\Main\Text\BinaryString::getLength($request));
211
212 $this->logger->addLog("Upload photo HTTP params", [
213 'SERVER' => $uploadServer,
214 'PARAMS' => $postParams,
215 'FILE_OK' => $file ? 'Y' : 'N',
216 ]);
217 $result = $http->post($uploadServer, $request);
218
219 $result = Json::decode($result);
220 $this->logger->addLog("Upload photo HTTP response", $result);
221
222// check http upload status. If error - need skip this image
223 if($result['error'])
224 {
225// get error code from error string
226 $this->logger->addError(
227 explode(':', $result['error'])[0] . '_' . $this->type,
228 $data[$this->params['keyReference']]
229 );
230
231 return false;
232 }
233
234// check TIMER if set
235 if($this->timer !== null && !$this->timer->check())
236 {
237 throw new TimeIsOverException();
238 }
239
240 return $result;
241 }
242
243 private function getFile(string $url)
244 {
245 $http = new HttpClient();
246
247 return $http->get($url);
248 }
249
250
256 private function savePhoto($uploadResult)
257 {
258 $photoSaveParams = array(
259 "group_id" => str_replace('-', '', $this->vkGroupId),
260 "photo" => $uploadResult["photo"],
261 "server" => $uploadResult["server"],
262 "hash" => $uploadResult["hash"],
263 );
264
265 // for product photo we need more params
266 if ($this->params['saveMethod'] == "photos.saveMarketPhoto")
267 {
268 if (isset($uploadResult["crop_hash"]) && $uploadResult["crop_hash"])
269 $photoSaveParams["crop_hash"] = $uploadResult["crop_hash"];
270 if (isset($uploadResult["crop_data"]) && $uploadResult["crop_data"])
271 $photoSaveParams["crop_data"] = $uploadResult["crop_data"];
272 }
273
274 return $this->api->run($this->params['saveMethod'], $photoSaveParams);
275 }
276
277
284 private static function setUploadServerMainPhotoParams($photoId)
285 {
286 $result = array();
287 $result["main_photo"] = 1;
288
289 $photoParams = \CFile::GetFileArray($photoId);
290 $w = $photoParams["WIDTH"];
291 $h = $photoParams["HEIGHT"];
292
293 if ($w >= $h)
294 {
295 $result["crop_x"] = ceil(($w + $h) / 2);
296 $result["crop_y"] = 0;
297 $result["crop_width"] = $h;
298 }
299 else
300 {
301 $result["crop_x"] = 0;
302 $result["crop_y"] = ceil(($w + $h) / 2);
303 $result["crop_width"] = $w;
304 }
305
306 return $result;
307 }
308}
static loadMessages($file)
Definition loc.php:64
__construct($exportId, $photoType, Timer $timer=null)