-
-
Save codezixo/b2dce9537d214cefb9b323cee042239f to your computer and use it in GitHub Desktop.
1C-Bitrix :: Загрузка изображений из папки на основе артикулов в инфоблок товаров
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<? | |
/** | |
* Загрузка изображение к товаров из папки | |
* | |
* PROPS: | |
* Фотографии [PHOTO] | |
* Alt-тег для фото [ALT_TAG_PHOTO] | |
* Не нужен водяной знак [NO_WATER_MARK] | |
* Индекс SORT [SORT_PHOTO] | |
*/ | |
class PUPictures | |
{ | |
const DIR = '/load_photo/'; | |
const DIR_UPLOAD = '/upload/'; | |
const DIR_LOG = '/log/attach_images/'; | |
/** Дефолтная сортировка */ | |
const DEF_SORT = 500; | |
/** Группы сортировки изображений (забиты в порядке сортировки) */ | |
static public $arGroups = Array( | |
'g' => 50, /** Главная */ | |
'o' => 100, /** Одиночная [multiple] */ | |
'k' => 150, /** Крупный план [multiple] */ | |
'i' => 200, /** Интерьерная [multiple] */ | |
's' => 250 /** Схема [multiple] */ | |
); | |
/** Параметры */ | |
static public $arOptions = Array( | |
'w' /** наносить ватермарку */ | |
); | |
/** | |
* Сканирует директорию на наличие новых папок с артикулами товаров | |
* и затем ищет в них изображений и ini файлы настроек | |
*/ | |
static public function scan($arParams) | |
{ | |
$dir = TL::getPath( | |
!empty($arParams['dir']) | |
? $arParams['dir'] | |
: self::DIR | |
); | |
$arFiles = TL::glob( | |
$dir."*.{jpeg,jpg,gif,png,JPEG,JPG,GIF,PNG}", | |
GLOB_BRACE | |
); | |
foreach($arFiles as $path){ | |
$arInfo = pathinfo($path); | |
preg_match( | |
"#\/([\w\d-]+)\/([\w\d.-]+)$#", | |
$arInfo['dirname'], | |
$arMatch | |
); | |
$arInfo['PATH'] = $path; | |
$arInfo['ARTICUL'] = trim($arMatch[1]); | |
$arInfo['FOLDER'] = trim($arMatch[2]); | |
if( !empty($arInfo['ARTICUL']) && !empty($arInfo['FOLDER']) ){ | |
$arInfo['OPTIONS'] = Array(); | |
self::parse($arInfo['FOLDER'], 'options.folder', $arInfo['OPTIONS']); | |
self::parse($arInfo['basename'], 'options.file', $arInfo['OPTIONS']); | |
$arInfo['HASH'] = md5_file($path); | |
$arResult['IMG'][ $arInfo['ARTICUL'] ]['INFO'][ $arInfo['basename'] ][] = $arInfo; | |
$arResult['IMG'][ $arInfo['ARTICUL'] ]['PATHS'][$path] = $path; | |
$arResult['IMG'][ $arInfo['ARTICUL'] ]['DIRS'][ $arInfo['dirname'] ] = $arInfo['dirname']; | |
$arResult['ARTICULS'][] = $arInfo['ARTICUL']; | |
} | |
} | |
foreach($arResult['IMG'] as &$arData){ | |
ksort($arData['INFO']); | |
} | |
return $arResult; | |
} | |
/** Парсинг опций (папки/файла) */ | |
static public function parse($str, $type, &$result) | |
{ | |
$str = is_array($str) ? $str : strtolower( | |
trim($str) | |
); | |
$result = is_array($result) ? $result : Array(); | |
if( !empty($str) && !empty($type) ){ | |
if($type == 'options.folder'){ | |
/** | |
* Парсинг опций папки "4311-1.2.3.4" | |
* 4311-1 - артикул (связка с цветом); | |
* 2.3.4 - прификcы "-1" 4311-2/4311-3/4311-4; | |
*/ | |
$ar1 = explode(".", $str); | |
$ar2 = explode("-", array_shift($ar1) ); | |
$articul = trim(array_shift($ar2)); | |
$prefiks = array_unique( array_merge($ar1, $ar2) ); | |
sort($prefiks); | |
if( is_numeric($articul) ){ | |
if( TL::isArr($prefiks) ){ | |
foreach($prefiks as $pref){ | |
if( strlen($pref) > 3 ){ | |
self::parse($pref, 'options.folder', $result); | |
}else{ | |
$pref = preg_replace('/[^\d]+/', "", $pref); | |
if( isset($pref) ){ | |
$result['sort'][] = (int) $pref; | |
$result['articuls'][] = ( | |
$pref == 0 | |
? $articul | |
: $articul."-".$pref | |
); | |
} | |
} | |
} | |
}else{ | |
$result['articuls'][] = $articul; | |
} | |
sort($result['articuls']); | |
$result['sort'] = (int) min($result['sort']); | |
} | |
}else if($type == 'options.file'){ | |
/** | |
* Парсинг имени файла | |
* g_w.jpeg | |
*/ | |
/** Type Sort */ | |
preg_match('/^('.implode("|", array_keys( self::$arGroups) ).')(\d)?/', $str, $arGroup); | |
$result['group'] = Array( | |
'type' => $arGroup[1], | |
'index' => $arGroup[2] | |
); | |
/** Options */ | |
preg_match_all('/_('.implode("|", self::$arOptions).')([a-z\d]+)?/', $str, $arOptions); | |
$result['options'] = array_combine($arOptions[1], $arOptions[2]); | |
}else if($type == 'options.combine'){ | |
/** | |
* Комбинированый парсинг строки | |
* @format: | |
* - "options.folder->options.file|description" | |
* - "description|options.folder->options.file" | |
* - "options.folder->options.file" | |
* - "description" | |
* @example: | |
* - '2323-1.2.3.4->g_w|Описание мебели' | |
*/ | |
/* | |
[description] => описание мебели | |
[articuls] => Array | |
( | |
[0] => 2323-1 | |
[1] => 2323-2 | |
[2] => 2323-3 | |
[3] => 2323-4 | |
) | |
[group] => g | |
[options] => Array | |
( | |
[w] => | |
) | |
) | |
*/ | |
$str = explode( "|", htmlspecialcharsBack($str) ); | |
foreach($str as $s){ | |
if( preg_match("/->/", $s) ){ | |
$options = $s; | |
}else{ | |
$result['description'] = $s; | |
} | |
} | |
if( !empty($options) ){ | |
list($optionsFolder, $optionsFile) = explode("->", $options); | |
self::parse($optionsFolder, 'options.folder', $result); | |
self::parse($optionsFile, 'options.file', $result); | |
}else if( !empty($result['description']) ){ | |
$res = $result; | |
$result = self::parse($res['description'], 'options.folder'); | |
$result = !TL::isArr($result['articuls']) ? $res : $result; | |
} | |
}else if($type == 'options.str'){ | |
/** | |
* Формирует строку из параметров массива | |
* 4311-1.4311-2.4311-3.4311-4->s1_w| | |
*/ | |
foreach($str['options'] as $k => $v){ | |
$options .= '_'.$k.$v; | |
} | |
$description = trim($str['description']); | |
$newDescription = trim($str['newDescription']); | |
if( !empty($newDescription) && empty($description) ){ | |
$res = self::parse($newDescription, 'options.combine'); | |
$description = $res['description']; | |
} | |
$result = implode(".", $str['articuls']).'->'.implode("", $str['group']).$options.'|'.$description; | |
} | |
return $result; | |
} | |
} | |
/** Получить значение для PROPERTY_ */ | |
static public function value($prop, $arImage, $oldValue) | |
{ | |
$value = trim($oldValue); | |
$options = $arImage['OPTIONS']; | |
if($prop == 'SORT_PHOTO'){ /** Сортировка */ | |
$value = (int) self::$arGroups[ $options['group']['type'] ] + (int) $options['group']['index'] + (int) $options['sort']; | |
$value = empty($value) ? self::DEF_SORT : $value; | |
}else if($prop == 'NO_WATER_MARK'){ /** Ватермартка */ | |
$value = array_key_exists('w', $options['options']) ? 'Y' : 'N'; | |
} | |
return $value; | |
} | |
/** | |
* Производит обновление/привязку найденных изображений к товарам | |
*/ | |
static public function attach($arParams) | |
{ | |
global $DB; | |
$arScan = self::scan($arParams); | |
if( TL::isArr($arScan['ARTICULS']) ){ | |
$arLog = Array( | |
'DATE_START' => date('d.m.Y H:i:s'), | |
'ARTICULS' => implode(", ",$arScan['ARTICULS']) | |
); | |
TL::log( | |
Array( | |
'LOG' => "----[START]--> \n\n".var_export($arLog, true)."\n\n----", | |
'DIR' => self::DIR_LOG, | |
'NAME' => 'attach' | |
) | |
); | |
$arProducts = Product::getList( | |
array( | |
'ID' => array( | |
'ARTICUL' => $arScan['ARTICULS'] | |
), | |
'select' => array( | |
'ID', | |
'PROPERTY_PHOTO', | |
'PROPERTY_ALT_TAG_PHOTO', | |
'PROPERTY_NO_WATER_MARK', | |
'PROPERTY_SORT_PHOTO' | |
) | |
) | |
); | |
foreach($arProducts as $articul => $arProduct){ | |
$arLog = Array( | |
'DATE_START' => date('d.m.Y H:is'), | |
'ARTICUL' => $articul, | |
'PID' => $arProduct['ID'], | |
'ATTACH' => $arScan['IMG'][$articul]['PATHS'] | |
); | |
unset($arUpdateMultipleProps, $arUpdateImages); | |
$arImages = $arScan['IMG'][$articul]['INFO']; | |
if( TL::isArr($arImages) ){ | |
/* | |
$arUpdateMultipleProps = array( | |
'NO_WATER_MARK' => $arProduct['PROPERTY_NO_WATER_MARK_VALUE'], | |
'ALT_TAG_PHOTO' => $arProduct['PROPERTY_ALT_TAG_PHOTO_VALUE'], | |
'SORT_PHOTO' => $arProduct['PROPERTY_SORT_PHOTO_VALUE'] | |
); | |
*/ | |
/** Проинициализация пустых св-в */ | |
foreach($arUpdateMultipleProps as $code => &$arValue){ | |
$arValue = is_array($arValue) ? $arValue : array(); | |
foreach($arProduct['PROPERTY_PHOTO_VALUE'] as $index => $ID){ | |
$arValue[$index] = array( | |
'VALUE' => !empty($arValue[$index]) ? $arValue[$index] : ' ', | |
'DESCRIPTION' => $arProduct['PROPERTY_'.$code.'_DESCRIPTION'][$index] | |
); | |
} | |
} | |
$arHash = $arHashID = Array(); | |
/** Получаем hash фоток которы в базе */ | |
if( TL::isArr($arProduct['PROPERTY_PHOTO_VALUE']) ){ | |
$dbFiles = CFile::GetList( | |
Array(), | |
Array( | |
"@ID" => implode(", ", $arProduct['PROPERTY_PHOTO_VALUE']) | |
) | |
); | |
while( $arFiles = $dbFiles-> GetNext(true, false) ){ | |
$hash = md5_file( | |
TL::getPath( | |
self::DIR_UPLOAD.$arFiles['SUBDIR'].'/'.$arFiles['FILE_NAME'] | |
) | |
); | |
$arHash[] = $hash; | |
$arHashID[$hash] = $arFiles['ID']; | |
} | |
} | |
foreach($arImages as $basename => $arImages){ | |
foreach($arImages as $arImage){ | |
$hash = $arImage['HASH']; | |
$indexHash = array_search( | |
$hash, | |
$arHash | |
); | |
if( !empty($arImage['PATH']) ){ | |
if($indexHash === false ){ /** Обработка изображений */ | |
$arUpdateImages[] = array( | |
'VALUE' => CFile::MakeFileArray( | |
$arImage['PATH'] | |
), | |
'DESCRIPTION' => self::parse($arImage['OPTIONS'], 'options.str') | |
); | |
}else{ /** Обновление описания */ | |
$arImage['OPTIONS']['newDescription'] = $arProduct['PROPERTY_PHOTO_DESCRIPTION'][$indexHash]; | |
$descript = self::parse($arImage['OPTIONS'], 'options.str'); | |
CFile::UpdateDesc( | |
$arHashID[$hash], | |
$descript | |
); | |
$DB-> Query( | |
"UPDATE | |
`b_iblock_element_property` | |
SET | |
DESCRIPTION='".$DB-> ForSQL($descript)."' | |
WHERE | |
VALUE='".$DB-> ForSQL($arHashID[$hash])."' | |
AND | |
IBLOCK_ELEMENT_ID=".intVal($arProduct['ID'])." | |
AND | |
IBLOCK_PROPERTY_ID=".intVal(35)." | |
LIMIT 1" | |
); | |
} | |
} | |
foreach($arUpdateMultipleProps as $code => &$arValue){ /** Обработка множественных св-в */ | |
if($indexHash === false){ | |
$value = self::value($code, $arImage); | |
$arValue[] = array( | |
'VALUE' => !empty($value) ? $value : ' ', | |
'DESCRIPTION' => ' ' | |
); | |
}else{ | |
$value = self::value($code, $arImage, $arValue[$indexHash]['VALUE']); | |
$arValue[$indexHash] = array( | |
'VALUE' => !empty($value) ? $value : ' ', | |
'DESCRIPTION' => $arValue[$indexHash]['DESCRIPTION'] | |
); | |
} | |
} | |
} | |
} | |
if( TL::isArr($arUpdateImages) ){ | |
CIBlockElement::SetPropertyValueCode( | |
$arProduct['ID'], | |
"PHOTO", | |
$arUpdateImages | |
); | |
} | |
if( TL::isArr($arUpdateMultipleProps) ){ | |
CIBlockElement::SetPropertyValuesEx( | |
$arProduct['ID'], | |
$arProduct['IBLOCK_ID'], | |
$arUpdateMultipleProps | |
); | |
} | |
$arLog['DATE_END'] = date('d.m.Y H:i:s'); | |
TL::log( | |
Array( | |
'LOG' => "----[INTERATE]--> \n\n".var_export($arLog, true)."\n\n----", | |
'DIR' => self::DIR_LOG, | |
'NAME' => 'attach' | |
) | |
); | |
if( !$arParams['isNoUnLink'] ){ | |
foreach($arScan['IMG'][$articul]['PATHS'] as $path){ | |
@unlink($path); | |
} | |
foreach($arScan['IMG'][$articul]['DIRS'] as $dir){ | |
@rmdir($dir); | |
} | |
} | |
} | |
} | |
$arLog = Array( | |
'DATE_END' => date('d.m.Y H:i:s'), | |
); | |
TL::log( | |
Array( | |
'LOG' => "----[END]--> \n\n".var_export($arLog, true)."\n\n----", | |
'DIR' => self::DIR_LOG, | |
'NAME' => 'attach' | |
) | |
); | |
} | |
} | |
} | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment