1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
product.php
См. документацию.
1<?php
2
3namespace Bitrix\Sale\TradingPlatform\Vk\Feed\Data\Converters;
4
5use Bitrix\Main\ArgumentNullException;
6use Bitrix\Main\Localization\Loc;
7use Bitrix\Sale\TradingPlatform\Vk;
8use Bitrix\Highloadblock\HighloadBlockTable;
9
10Loc::loadMessages(__FILE__);
11
13{
15 protected $sectionsList;
16 private $result;
17
19 const DESCRIPTION_LENGHT_MAX = 3300; // it is not entirely accurate value, but in doc i can't find true info
20 const NAME_LENGHT_MIN = 4;
21 const NAME_LENGHT_MAX = 100;
22
27 public function __construct($exportId)
28 {
29 if (!isset($exportId) || $exportId == '')
30 throw new ArgumentNullException("EXPORT_ID");
31
32 $this->exportId = $exportId;
33 $this->sectionsList = new Vk\SectionsList($this->exportId);
34 }
35
36
43 public function convert($data)
44 {
45 $logger = new Vk\Logger($this->exportId);
46 $this->result = array();
47
48// get common SKU and notSKU data
49 $this->result = $this->getNotSkuItemData($data);
50
51// product WITH SKU
52 $offersDescription = '';
53 if (isset($data["OFFERS"]) && is_array($data["OFFERS"]) && !empty($data["OFFERS"]))
54 {
55 //adding desc and additional photos from SKU
56 $this->selectOfferProps = $data["SELECT_OFFER_PROPS"];
57 $this->result["PHOTOS_OFFERS"] = array();
58 $this->result["PHOTOS_OFFERS_FOR_VK"] = array();
59
60 $offersConverted = array();
61 foreach ($data["OFFERS"] as $offer)
62 {
63 $resultOffer = $this->getItemDataOffersOffer($offer);
64
65 if (!empty($resultOffer["PHOTOS"]))
66 $this->result["PHOTOS_OFFERS"] += $resultOffer["PHOTOS"];
67
68 if (!empty($resultOffer["PHOTOS_FOR_VK"]))
69 $this->result["PHOTOS_OFFERS_FOR_VK"] += $resultOffer["PHOTOS_FOR_VK"];
70
71 $offersConverted[] = $resultOffer;
72 }
73
74 $offersDescription = $this->createOffersDescriptionByPrices($offersConverted);
75 }
76
77// check price. After offers convertions price may be changed
78 if (!$this->result["PRICE"])
79 {
80 $logger->addError('PRODUCT_EMPTY_PRICE', $data["ID"]);
81
82 return NULL;
83 }
84
85// if exist offers descriptions - add title for them
86 if ($offersDescription <> '')
87 $this->result["description"] .= "\n\n" . Loc::getMessage("SALE_VK_PRODUCT_VARIANTS") . "\n" . $offersDescription;
88
89// sorted photos array in right order
90// todo: move this operation in Photoresizer
91 $photosSorted = $this->sortPhotosArray();
92
93// CHECK photo sizes and count
94 $photosChecked = Vk\PhotoResizer::checkPhotos($photosSorted, 'PRODUCT');
95 if (empty($photosChecked))
96 {
97 $logger->addError("PRODUCT_WRONG_PHOTOS", $data["ID"]);
98
99 return NULL;
100 }
101
102 $this->result["PHOTO_MAIN_BX_ID"] = $photosChecked["PHOTO_MAIN_BX_ID"];
103 $this->result["PHOTO_MAIN_URL"] = $photosChecked["PHOTO_MAIN_URL"];
104 $this->result["PHOTOS"] = $photosChecked["PHOTOS"];
105
106// add item to log, if image was be resized
107 if ($photosChecked['RESIZE_UP'])
108 $logger->addError('PRODUCT_PHOTOS_RESIZE_UP', $data["ID"]);
109 if ($photosChecked['RESIZE_DOWN'])
110 $logger->addError('PRODUCT_PHOTOS_RESIZE_DOWN', $data["ID"]);
111
112
113// cleaing DESCRIPTION
114 $this->result["description"] = html_entity_decode($this->result["description"]);
115 $this->result["description"] = preg_replace('/\t*/', '', $this->result["description"]);
116 $this->result["description"] = strip_tags($this->result["description"]);
117
118 $this->result['description'] = $this->validateDescription($this->result['description'], $logger);
119
120 $this->result['NAME'] = $this->validateName($this->result['NAME'], $logger);
121
122 return array($data["ID"] => $this->result);
123 }
124
125
133 private function validateName($name, Vk\Logger $logger = NULL)
134 {
135 $newName = $name;
136
137 if (($length = self::matchLength($name)) < self::NAME_LENGHT_MIN)
138 {
139 $newName = self::extendString($name, $length, self::NAME_LENGHT_MIN);
140 if ($logger)
141 {
142 $logger->addError('PRODUCT_SHORT_NAME', $this->result["BX_ID"]);
143 }
144 }
145
146 if (($length = self::matchLength($name)) > self::NAME_LENGHT_MAX)
147 {
148 $newName = self::reduceString($name, $length, self::NAME_LENGHT_MAX);
149 if ($logger)
150 {
151 $logger->addError('PRODUCT_LONG_NAME', $this->result["BX_ID"]);
152 }
153 }
154
155 return $newName;
156 }
157
158
166 private function validateDescription($desc, Vk\Logger $logger = NULL)
167 {
168 $newDesc = $desc;
169
170 if (mb_strlen($desc) < self::DESCRIPTION_LENGHT_MIN)
171 {
172 $newDesc = $this->result['NAME'] . ': ' . $desc;
173 if (mb_strlen($newDesc) < self::DESCRIPTION_LENGHT_MIN)
174 {
175 $newDesc = self::mb_str_pad($newDesc, self::DESCRIPTION_LENGHT_MIN, self::PAD_STRING);
176// ending space trim fix
177 if ($newDesc[mb_strlen($newDesc) - 1] == ' ')
178 {
179 $newDesc .= self::PAD_STRING;
180 }
181 if ($logger)
182 {
183 $logger->addError('PRODUCT_SHORT_DESCRIPTION', $this->result["BX_ID"]);
184 }
185 }
186 }
187
188 if (mb_strlen($newDesc) > self::DESCRIPTION_LENGHT_MAX)
189 {
190 $newDesc = mb_substr($newDesc, 0, self::DESCRIPTION_LENGHT_MAX).'...';
191 }
192
193 return $newDesc;
194 }
195
196
205 private function createOffersDescriptionByPrices($offers)
206 {
207 $mainPrice = isset($this->result['PRICE']) && $this->result['PRICE'] ? $this->result['PRICE'] : 0;
208 $needSkuPriceDescription = false;
209
210// compare main price and SKU prices. Find minimum, check difference
211 foreach ($offers as $offer)
212 {
213 if ($offer['PRICE'])
214 {
215// if not set main price - get them from SKU prices
216 if ($mainPrice == 0)
217 $mainPrice = $offer['PRICE'];
218
219// add price to SKU descriptions only of prices is different
220 if ($offer['PRICE'] != $mainPrice)
221 $needSkuPriceDescription = true;
222
223 $mainPrice = ($mainPrice != 0) ? min($offer['PRICE'], $mainPrice) : $offer['PRICE'];
224 }
225 }
226
227// update SKU DESRIPTIONS if needed
228 $offersDescription = '';
229 if ($needSkuPriceDescription)
230 {
231 foreach ($offers as $offer)
232 {
233 $offersDescription .= $offer["DESCRIPTION_PROPERTIES"] . " - " . Loc::getMessage("SALE_VK_PRODUCT_PRICE") . " " . $offer['PRICE'] . " " . Loc::getMessage("SALE_VK_PRODUCT_CURRENCY") . "\n";
234 }
235 }
236
237 else
238 {
239 foreach ($offers as $offer)
240 {
241 $offersDescription .= $offer["DESCRIPTION_PROPERTIES"] . "\n";
242 }
243 }
244
245 $this->result['PRICE'] = $mainPrice;
246
247 return $offersDescription;
248 }
249
250
256 private function sortPhotosArray()
257 {
258 $newPhotos = array();
259 if (isset($this->result['PHOTOS_FOR_VK']) && !empty($this->result['PHOTOS_FOR_VK']))
260 $newPhotos += $this->result['PHOTOS_FOR_VK'];
261
262 if (isset($this->result['PHOTOS_OFFERS_FOR_VK']) && !empty($this->result['PHOTOS_OFFERS_FOR_VK']))
263 $newPhotos += $this->result['PHOTOS_OFFERS_FOR_VK'];
264
265 if (isset($this->result['PHOTO_MAIN']) && !empty($this->result['PHOTO_MAIN']))
266 $newPhotos += $this->result['PHOTO_MAIN'];
267
268 if (isset($this->result['PHOTOS']) && !empty($this->result['PHOTOS']))
269 $newPhotos += $this->result['PHOTOS'];
270
271 if (isset($this->result['PHOTOS_OFFERS']) && !empty($this->result['PHOTOS_OFFERS']))
272 $newPhotos += $this->result['PHOTOS_OFFERS'];
273
274// delete wasted photos
275 unset(
276 $this->result['PHOTOS_FOR_VK'],
277 $this->result['PHOTOS_OFFERS_FOR_VK'],
278 $this->result['PHOTOS'],
279 $this->result['PHOTO_MAIN'],
280 $this->result['PHOTOS_OFFERS']
281 );
282
283 return $newPhotos;
284 }
285
286
295 private function getItemDataOffersOffer($data)
296 {
297 $result = array("DESCRIPTION" => "");
298
299// create description for SKU PROPERTIES
300 $propertyDescriptions = array();
301 foreach ($this->selectOfferProps as $prop)
302 {
303 if ($propValue = $data["PROPERTIES"][$prop]["VALUE"])
304 {
305// check if HIGLOADBLOCKS
306 if ($data["PROPERTIES"][$prop]["USER_TYPE"] == 'directory')
307 {
308 if (\CModule::IncludeModule('highloadblock'))
309 {
310// get ID for hl-block
311 $resHlBlocks = HighloadBlockTable::getList(array(
312 'filter' => array('=TABLE_NAME' => $data["PROPERTIES"][$prop]["USER_TYPE_SETTINGS"]["TABLE_NAME"]),
313 ));
314 $hlBlockItemId = $resHlBlocks->fetch();
315 $hlBlockItemId = $hlBlockItemId['ID'];
316// HL directory may not exist in some strange situations
317 if(!$hlBlockItemId)
318 continue;
319
320// get entity class for current hl
321 $hlBlock = HighloadBlockTable::getById($hlBlockItemId)->fetch();
322 $hlEntity = HighloadBlockTable::compileEntity($hlBlock);
323 $strEntityDataClass = $hlEntity->getDataClass();
324
325// get value for current hl
326 $resData = $strEntityDataClass::getList(array(
327 'select' => array('ID', 'UF_NAME'),
328 'filter' => array('=UF_XML_ID' => $propValue),
329 ));
330 $propValue = $resData->fetch();
331 $propValue = $propValue['UF_NAME'];
332 }
333 }
334
335 if(is_array($propValue))
336 $propValue = implode(', ', $propValue);
337
338 $propertyDescriptions[] = $data["PROPERTIES"][$prop]["NAME"] . ": " . $propValue;
339 }
340 }
341 if (!empty($propertyDescriptions))
342 $result["DESCRIPTION_PROPERTIES"] = implode("; ", $propertyDescriptions);
343
344// adding MAIN DESCRIPTION
345 $description = strip_tags($data["~DETAIL_TEXT"] <> '' ? $data["~DETAIL_TEXT"] : $data["~PREVIEW_TEXT"]);
346 if ($description)
347 $result["DESCRIPTION"] .= $description;
348
349// adding PRICE. Ib desc we adding prices later
350 $result['PRICE'] = $data["PRICES"]["MIN_RUB"];
351
352// adding PHOTOS
353 $photoId = ($data["DETAIL_PICTURE"] <> '') ? $data["DETAIL_PICTURE"] : $data["PREVIEW_PICTURE"];
354 if ($photoId)
355 $result["PHOTOS"] = array($photoId => array("PHOTO_BX_ID" => $photoId));
356
357// adding special VK photos
358 $vkPhotosKey = 'PHOTOS_FOR_VK_' . $data["IBLOCK_ID"];
359 $resOfferProps = new \_CIBElement();
360 $resOfferProps->fields = array("IBLOCK_ID" => $data["IBLOCK_ID"], "ID" => $data["ID"]);
361 $resOfferProps = $resOfferProps->GetProperties(array(), array("CODE" => $vkPhotosKey));
362 if (!empty($resOfferProps[$vkPhotosKey]["VALUE"]))
363 {
364 foreach ($resOfferProps[$vkPhotosKey]["VALUE"] as $ph)
365 {
366 $result["PHOTOS_FOR_VK"][$ph] = array(
367 "PHOTO_BX_ID" => $ph,
368 );
369 }
370 }
371
372 return $result;
373 }
374
375
382 private function getNotSkuItemData($data)
383 {
384 $result = array();
385 $result["BX_ID"] = $data["ID"];
386 $result["IBLOCK_ID"] = $data["IBLOCK_ID"];
387 $result["NAME"] = $data["~NAME"];
388 $result["SECTION_ID"] = $data["IBLOCK_SECTION_ID"];
389 $result["CATEGORY_VK"] = $this->sectionsList->getVkCategory($data["IBLOCK_SECTION_ID"]);
390
391// todo: DELETED should depended by AVAILABLE
392 $result["deleted"] = 0;
393 $result["PRICE"] = $data["PRICES"]["MIN_RUB"]; // price converted in roubles
394 $result["description"] = $data["~DETAIL_TEXT"] <> '' ? $data["~DETAIL_TEXT"] : $data["~PREVIEW_TEXT"];
395 $result["description"] = trim(preg_replace('/\s{2,}/', "\n", $result["description"]));
396// get main photo from preview or detail
397 $photoMainBxId = $data["DETAIL_PICTURE"] <> '' ? $data["DETAIL_PICTURE"] : $data["PREVIEW_PICTURE"];
398 $photoMainUrl = $data["DETAIL_PICTURE_URL"] <> '' ? $data["DETAIL_PICTURE_URL"] : $data["PREVIEW_PICTURE_URL"];
399 if ($photoMainBxId && $photoMainUrl)
400 $result["PHOTO_MAIN"] = array(
401 $photoMainBxId => array(
402 "PHOTO_BX_ID" => $photoMainBxId,
403 "PHOTO_URL" => $photoMainUrl,
404 ),
405 );
406
407// adding MORE PHOTOS to the all_photos array/ Later we will checked sizes
408 if (isset($data["PROPERTIES"]["MORE_PHOTO"]["VALUE"]) &&
409 is_array($data["PROPERTIES"]["MORE_PHOTO"]["VALUE"]) &&
410 !empty($data["PROPERTIES"]["MORE_PHOTO"]["VALUE"])
411 )
412 {
413 foreach ($data["PROPERTIES"]["MORE_PHOTO"]["VALUE"] as $ph)
414 {
415 $result["PHOTOS"][$ph] = array("PHOTO_BX_ID" => $ph);
416 }
417 }
418
419// take special VK photos
420 $vkPhotosKey = 'PHOTOS_FOR_VK_' . $data["IBLOCK_ID"];
421 if (isset($data["PROPERTIES"][$vkPhotosKey]["VALUE"]) &&
422 is_array($data["PROPERTIES"][$vkPhotosKey]["VALUE"]) &&
423 !empty($data["PROPERTIES"][$vkPhotosKey]["VALUE"])
424 )
425 {
426 foreach ($data["PROPERTIES"][$vkPhotosKey]["VALUE"] as $ph)
427 {
428 $result["PHOTOS_FOR_VK"][$ph] = array(
429 "PHOTO_BX_ID" => $ph,
430 );
431 }
432 }
433
434 return $result;
435 }
436}
static checkPhotos($photos, $type)
Определения photoresizer.php:125
$data['IS_AVAILABLE']
Определения .description.php:13
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
Определения file_new.php:804
if(Loader::includeModule( 'bitrix24')) elseif(Loader::includeModule('intranet') &&CIntranetUtils::getPortalZone() !=='ru') $description
Определения .description.php:24
$name
Определения menu_edit.php:35
Определения basket.php:2
if(mb_strlen($order)< 6) $desc
Определения payment.php:44