Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
apihelper.php
1<?php
2
4
15
16Loc::loadMessages(__FILE__);
17
23{
24 private $vk;
25 private $api;
26 private $executer;
27 private $exportId;
28 private $logger;
29
34 public function __construct($exportId)
35 {
36 if (empty($exportId))
37 {
38 throw new ArgumentNullException('exportId');
39 }
40
41 $this->exportId = $exportId;
42 $this->vk = Vk::getInstance();
43 $this->api = $this->vk->getApi($exportId);
44 $this->executer = $this->vk->getExecuter($exportId);
45 $this->logger = new Logger($this->exportId);
46 }
47
48
56 public static function extractItemsFromArray($data = array(), $keys = array())
57 {
58 if (!isset($keys) || empty($keys))
59 return $data;
60
61 $newArr = array();
62 foreach ($data as $value)
63 {
64 if (!is_array($value))
65 {
66 $newArr[] = $value;
67 }
68 else
69 {
70 $currArr = array();
71 foreach ($keys as $k)
72 {
73 $currArr[$k] = $value[$k];
74 }
75 $newArr[] = $currArr;
76 }
77 }
78
79 return $newArr;
80 }
81
82
91 public static function addResultToData($data = array(), $result = array(), $referenceKey)
92 {
93 if (empty($result) || !isset($referenceKey))
94 {
95 return $data;
96 }
97
98 foreach ($result as $item)
99 {
100 if (isset($data[$item[$referenceKey]]))
101 {
102 $data[$item[$referenceKey]] += $item;
103 }
104 }
105
106 return $data;
107 }
108
109
118 public static function changeArrayMainKey($data = array(), $mainKey, $keyRename = '')
119 {
120 if (!isset($mainKey))
121 return $data;
122
123 $result = array();
124 foreach ($data as $item)
125 {
126 $result[$item[$mainKey]] = $item;
127 if ($keyRename)
128 {
129 $result[$item[$mainKey]][$keyRename] = $result[$item[$mainKey]][$mainKey];
130 unset($result[$item[$mainKey]][$mainKey]);
131 }
132 }
133
134 return $result;
135 }
136
137
149 public function uploadPhotos($data, $vkGroupId, $uploadType, Timer $timer = NULL)
150 {
151// todo: this is a little kostyl. In cool variant we must separately do http-upload,
152// todo: and photo save run through execute method
153// todo: but now VK can't run savePhotoMethod through execute. Sadness ((
154
155// PARAMS set
156 $photoSaveResults = array();
157 switch ($uploadType)
158 {
159 case 'PRODUCT_MAIN_PHOTO':
160 $uploadServerMethod = 'photos.getMarketUploadServer';
161 $saveMethod = 'photos.saveMarketPhoto';
162 $keyReference = 'BX_ID';
163 $keyPhotoVk = 'PHOTO_MAIN_VK_ID';
164 $keyPhotoBx = 'PHOTO_MAIN_BX_ID';
165 break;
166
167 case 'PRODUCT_PHOTOS':
168 $uploadServerMethod = 'photos.getMarketUploadServer';
169 $saveMethod = 'photos.saveMarketPhoto';
170 $keyReference = 'PHOTO_BX_ID';
171 $keyPhotoVk = 'PHOTO_VK_ID';
172 $keyPhotoBx = 'PHOTO_BX_ID';
173 break;
174
175 case 'ALBUM_PHOTO':
176 $uploadServerMethod = 'photos.getMarketAlbumUploadServer';
177 $saveMethod = 'photos.saveMarketAlbumPhoto';
178 $keyReference = 'SECTION_ID';
179 $keyPhotoVk = 'PHOTO_VK_ID';
180 $keyPhotoBx = 'PHOTO_BX_ID';
181 break;
182
183 default:
184 throw new SystemException("Wrong photo upload type");
185 break;
186 }
187
188// PROCESSED
189 foreach ($data as $item)
190 {
191// check EXISTING photo
192 if (!array_key_exists($keyPhotoBx, $item) || empty($item[$keyPhotoBx]))
193 continue;
194
195// GET upload server by type
196 $getServerParams = array("group_id" => str_replace("-", "", $vkGroupId));
197 if ($uploadType == 'PRODUCT_MAIN_PHOTO')
198 $getServerParams += self::setUploadServerMainPhotoParams($item[$keyPhotoBx]);
199
200 $uploadServer = $this->api->run($uploadServerMethod, $getServerParams);
201// todo: may be this error in upload server response
202 $this->logger->addLog("Get photo upload server", [
203 'PARAMS' => $getServerParams,
204 'RESULT' => $uploadServer,
205 ]);
206 $uploadServer = $uploadServer["upload_url"];
207
208
209// UPLOAD photo by http
210 $this->logger->addLog("Upload photo HTTP before", array(
211 "UPLOAD_TYPE" => $uploadType,
212 "ITEM" => array_key_exists("BX_ID", $item) ?
213 $item["BX_ID"].': '.$item["NAME"] :
214 $item["SECTION_ID"].': '.$item["TITLE"],
215 "PHOTO_BX_ID" => array_key_exists("PHOTO_MAIN_BX_ID", $item) ? $item["PHOTO_MAIN_BX_ID"] : $item["PHOTO_BX_ID"],
216 "PHOTO_URL" => array_key_exists("PHOTO_MAIN_URL", $item) ? $item["PHOTO_MAIN_URL"] : $item["PHOTO_URL"],
217 "PHOTOS" => $item["PHOTOS"] //only for products
218 ));
219 $responseHttp = $this->uploadPhotoHttp($item, $uploadServer, $uploadType, $timer);
220
221// SAVE upload result
222 $photoSaveParams = array(
223 "group_id" => str_replace('-', '', $vkGroupId),
224 "photo" => $responseHttp["photo"],
225 "server" => $responseHttp["server"],
226 "hash" => $responseHttp["hash"],
227 );
228
229 // for product photo we need more params
230 if ($saveMethod == "photos.saveMarketPhoto")
231 {
232 if (isset($responseHttp["crop_hash"]) && $responseHttp["crop_hash"])
233 $photoSaveParams["crop_hash"] = $responseHttp["crop_hash"];
234 if (isset($responseHttp["crop_data"]) && $responseHttp["crop_data"])
235 $photoSaveParams["crop_data"] = $responseHttp["crop_data"];
236 }
237
238 $responsePhotoSave = $this->api->run($saveMethod, $photoSaveParams);
239
240// RESULT
241 $photoSaveResults[] = array(
242 $keyReference => $item[$keyReference],
243 $keyPhotoVk => $responsePhotoSave[0]["id"],
244 );
245
246// todo: photo mapping. po odnomu, navernoe, ved timer
247 }
248
249 return $photoSaveResults;
250 }
251
252
265 private function uploadPhotoHttp($data, $uploadServer, $uploadType, Timer $timer = NULL)
266 {
267 switch ($uploadType)
268 {
269 case 'ALBUM_PHOTO':
270 $postParams = array(
271 "url" => $data["PHOTO_URL"],
272 "filename" => IO\Path::getName($data["PHOTO_URL"]),
273 "param_name" => 'file',
274 "timer" => $timer,
275 );
276 break;
277
278 case 'PRODUCT_MAIN_PHOTO':
279 $postParams = array(
280 "url" => $data["PHOTO_MAIN_URL"],
281 "filename" => IO\Path::getName($data["PHOTO_MAIN_URL"]),
282 "param_name" => 'file',
283 "timer" => $timer,
284 );
285 break;
286
287 case 'PRODUCT_PHOTOS':
288 $postParams = array(
289 "url" => $data["PHOTO_URL"],
290 "filename" => IO\Path::getName($data["PHOTO_URL"]),
291 "param_name" => 'file',
292 "timer" => $timer,
293 );
294 break;
295
296 default:
297 throw new SystemException("Wrong upload type");
298 break;
299
300 }
301
302 return $this->uploadHttp($uploadServer, $postParams);
303 }
304
305
313 private static function setUploadServerMainPhotoParams($photoId)
314 {
315 $result = array();
316 $result["main_photo"] = 1;
317
318 $photoParams = \CFile::GetFileArray($photoId);
319 $w = $photoParams["WIDTH"];
320 $h = $photoParams["HEIGHT"];
321
322 if ($w >= $h)
323 {
324 $result["crop_x"] = ceil(($w + $h) / 2);
325 $result["crop_y"] = 0;
326 $result["crop_width"] = $h;
327 }
328 else
329 {
330 $result["crop_x"] = 0;
331 $result["crop_y"] = ceil(($w + $h) / 2);
332 $result["crop_width"] = $w;
333 }
334
335 return $result;
336 }
337
346 private function uploadHttp($uploadServer, $params)
347 {
348 $http = new HttpClient();
349 $boundary = md5(rand() . time());
350
351 $file = $this->getFile($params["url"]);
352
353 $data = '--' . $boundary . "\r\n";
354 $data .= 'Content-Disposition: form-data; name="' . $params["param_name"] . '"; filename="' . $params["filename"] . '"' . "\r\n";
355 $data .= 'Content-Type: application/octet-stream' . "\r\n\r\n";
356 $data .= $file . "\r\n";
357 $data .= '--' . $boundary . "--\r\n";
358
359 $http->setHeader('Content-type', 'multipart/form-data; boundary=' . $boundary);
360 $http->setHeader('Content-length', \Bitrix\Main\Text\BinaryString::getLength($data));
361
362 $this->logger->addLog("Upload photo HTTP params", [
363 'SERVER' => $uploadServer,
364 'PARAMS' => $params,
365 'FILE_OK' => $file ? 'Y' : 'N',
366 ]);
367 $result = $http->post($uploadServer, $data);
368
369 $result = Json::decode($result);
370 $this->logger->addLog("Upload photo HTTP response", $result);
371
372// check TIMER if set
373 if (array_key_exists("timer", $params))
374 {
375 $timer = $params["timer"];
376 if ($timer !== NULL && !$timer->check())
377 throw new TimeIsOverException();
378 }
379
380 return $result;
381 }
382
383 private function getFile(string $url)
384 {
385 $http = new HttpClient();
386
387 return $http->get($url);
388 }
389
390 public function getUserGroupsSelector($selectedValue = null, $name = null, $id = null)
391 {
392// todo: maybe cached this values
393 $groupsSelector = false;
394
395 $gpoups = $this->getUserGroups();
396 if(is_array($gpoups) && !empty($gpoups))
397 {
398 $groupsSelector = '<option value="-1">['.Loc::getMessage('SALE_VK_CHANGE_GROUP').']</option>';
399 $selectedValue = str_replace('-', '', $selectedValue);
400 $name = $name ? ' name="' . $name . '"' : '';
401 $id = $id ? ' id="' . $id . '"' : '';
402
403 foreach ($gpoups as $group)
404 {
405 $selected = $selectedValue == $group["id"] ? ' selected' : '';
406 $groupsSelector .=
407 '<option' . $selected . ' value="' . $group['id'] . '">' . $group['name'] . '</option>';
408 }
409
410 $groupsSelector =
411 '<select id="vk_export_groupselector" onchange="BX.Sale.VkAdmin.changeVkGroupLink();"' . $id . $name . '>' .
412 $groupsSelector .
413 '</select>';
414 $groupsSelector.=
415 '<span style="padding-left:10px">
416 <a href="https://vk.com/club'. $selectedValue .'" id="vk_export_groupselector__link">
417 <img src="/bitrix/images/sale/vk/vk_icon.png">
418 </a>
419 </span>';
420 }
421
422 return $groupsSelector;
423 }
424
425
426 private function getUserGroups($offset = null)
427 {
428 $userGroups = array();
429 $stepCount = 0;
430
431// max 1000 in one step.Check this value and run api again if needed
432 while(true)
433 {
434 $params = array(
435 'extended' => 1,
436 'filter' => 'editor',
437 'offset' => $stepCount,
438 'count' => Vk::GROUP_GET_STEP,
439 );
440 $apiResult = $this->api->run('groups.get', $params);
441 foreach($apiResult['items'] as $group)
442 {
443 $userGroups[$group['id']] = array(
444 'id' => $group['id'],
445 'name' => $group['name']
446 );
447 }
448
449// increment step items counter
450 if($apiResult['count'] > Vk::GROUP_GET_STEP + $stepCount)
451 $stepCount += Vk::GROUP_GET_STEP;
452 else
453 break;
454 }
455
456 return $userGroups;
457 }
458
466 public function getALbumsFromVk($vkGroupId, $flip = true)
467 {
468// todo: so slow api request. Try cached this data or other acceleration techniques
469 $albumsFromVk = $this->executer->executeMarketAlbumsGet(array(
470 "owner_id" => $vkGroupId,
471 "offset" => 0,
472 "count" => Vk::MAX_ALBUMS,
473 ));
474 $albumsFromVk = $albumsFromVk["items"]; // get only items from response
475 foreach ($albumsFromVk as &$item) // get only IDs from response
476 {
477 $item = $item["id"];
478 }
479 if ($flip)
480 $albumsFromVk = array_flip($albumsFromVk); // we need albumID as keys
481
482 return $albumsFromVk;
483 }
484
485
492 public function getProductsFromVk($vkGroupId)
493 {
494 $productsFromVk = array();
495 $prodGetStep = 0;
496 while ($prodGetStep < Vk::MAX_PRODUCTS_IN_ALBUM)
497 {
498 $productsFromVk += $this->executer->executeMarketProductsGet(array(
499 "owner_id" => $vkGroupId,
500 "offset" => $prodGetStep,
501 "step" => Vk::PRODUCTS_GET_STEP)
502 );
503 $prodGetStep += Vk::PRODUCTS_GET_STEP;
504 // exit from loop, if we reach end of VK-products
505 if ($productsFromVk["end_products"])
506 {
507 unset($productsFromVk["end_products"]);
508 break;
509 }
510 }
511
512 $result = array();
513 foreach($productsFromVk as $productFromVk)
514 $result[$productFromVk] = array("VK_ID" => $productFromVk);
515
516 return $result;
517 }
518
519
527 public static function prepareProductsDataToVk($data)
528 {
529 $result = array();
530 foreach ($data as $item)
531 {
532// check PHOTOS and formatted
533 if (isset($item["PHOTOS"]) && is_array($item["PHOTOS"]))
534 {
535 $photosIds = array();
536 foreach ($item["PHOTOS"] as $photo)
537 {
538 if (is_numeric($photo["PHOTO_VK_ID"]))
539 $photosIds[] = $photo["PHOTO_VK_ID"];
540 }
541
542 if (!empty($photosIds))
543 $item["PHOTOS"] = implode(",", $photosIds);
544 else
545 unset($item["PHOTOS"]);
546 }
547
548// check VK_CATEGORY
549 if (!(isset($item["CATEGORY_VK"]) && intval($item["CATEGORY_VK"]) > 0))
550 {
551 $item["CATEGORY_VK"] = Vk::VERY_DEFAULT_VK_CATEGORY;
552 } // we need some category
553
554 $result[] = $item;
555 }
556
557 return $result;
558 }
559
560
561
562
563
571 public function getVkCategories($count = Vk::MAX_VK_CATEGORIES, $offset = 0)
572 {
573 $vkCats = $this->api->run('market.getCategories', array("count" => $count, "offset" => $offset));
574
575 if (!empty($vkCats))
576 {
577 return $vkCats["items"];
578 }
579
580 else
581 {
582 return false;
583 }
584 }
585}
static loadMessages($file)
Definition loc.php:64
static extractItemsFromArray($data=array(), $keys=array())
Definition apihelper.php:56
uploadPhotos($data, $vkGroupId, $uploadType, Timer $timer=NULL)
getVkCategories($count=Vk::MAX_VK_CATEGORIES, $offset=0)
getUserGroupsSelector($selectedValue=null, $name=null, $id=null)
static changeArrayMainKey($data=array(), $mainKey, $keyRename='')
static addResultToData($data=array(), $result=array(), $referenceKey)
Definition apihelper.php:91