Skip to content

Instantly share code, notes, and snippets.

@di7spider
Created September 22, 2015 07:28
Show Gist options
  • Save di7spider/6df64f94626edd587543 to your computer and use it in GitHub Desktop.
Save di7spider/6df64f94626edd587543 to your computer and use it in GitHub Desktop.
1C-Bitrix :: Загрузка изображений из папки на основе артикулов в инфоблок товаров
<?
/**
* Загрузка изображение к товаров из папки
*
* 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