Дополнительные картинки в новостях Битрикс, почти фотогалерея.

Просмотров: 53048

Частенько стоит задача, по мимо стандартных "Картинка для анонса" и "Детальная картинка", добавить возможность загрузки изображений в новости Битрикс. Чтобы вывести дополнительные картинки в bitrix:news изначально такой возможности не заложено. Исправим это, а заодно и превратим шаблон "Новости и статьи" в что-то вроде фотогалереи с эффектом fancybox

ВАЖНО!!!
Эта заметка написана в далеком 2013-ом году. Она вполне работоспособна, но есть более свежая и актуальная версия. Лучше, воспользуйтесь ею.
Фотогалерея на базе компонента новостей, с fancybox.

По интернету ходит вполне подробная инструкция по добавлению и выводу дополнительных изображений в новостях- ею и воспользуемся :

Для вывода дополнительных изображений в элементах информационного блока (т.е. изображений кроме PREVIEW_PICTURE и DETAIL_PICTURE) необходимо создать дополнительное свойство типа ФАЙЛ с кодом MORE_PHOTO.

Дополнительные картинки в новостях Битрикс

Детальное редактирование.

Дополнительные картинки в новостях Битрикс

Нужно в шаблоне news.detail добавить в файл result_modifier.php следующий код:


<? 
 $arResult["MORE_PHOTO"] = array(); 
 if(isset($arResult["PROPERTIES"]["MORE_PHOTO"]["VALUE"]) && is_array($arResult["PROPERTIES"]["MORE_PHOTO"]["VALUE"])) 
 { 
 foreach($arResult["PROPERTIES"]["MORE_PHOTO"]["VALUE"] as $FILE) 
 { 
 $FILE = CFile::GetFileArray($FILE); 
 if(is_array($FILE)) 
 $arResult["MORE_PHOTO"][]=$FILE; 
 } 
 } 
 ?>

Тем самым мы сможем обращаться к массиву фотографий также, как это происходит в шаблоне каталога: $arResult["MORE_PHOTO"].

Далее копируем код из шаблона каталога для вывода изображений в шаблон новостей news.detail:

<? 
 // additional photos 
$LINE_ELEMENT_COUNT = 2; // number of elements in a row 
if(count($arResult["MORE_PHOTO"])>0):?> 
<a name="more_photo"></a> 
<?foreach($arResult["MORE_PHOTO"] as $PHOTO):?> 
<img border="0" src="<?=$PHOTO["SRC"]?>" width="<?=$PHOTO["WIDTH"]?>" height="<?=$PHOTO["HEIGHT"]?>"
 alt="<?=$arResult["NAME"]?>" title="<?=$arResult["NAME"]?>" /><br /> 
<?endforeach?> 
<?endif?>

После этого подгруженные изображения будут отображаться при выводе новостей. Правда таким образом выводить изображения навтрятли кто станет, ведь они выводятся в реальном размере и могут сильно попортить дизайн сайта. Чтобы этого не происходило применяют следующую функцию.

CFile::ResizeImageGet

Вот что говорится в официальной документации: Функция уменьшает картинку и размещает уменьшенную копию в папку /upload/resize_cache/путь. Один раз уменьшив изображение получаем физический файл, который позволяет при последующих обращениях не проводить операции по уменьшению изображения. При следующем вызове функция вернет путь к уменьшенному файлу.

Таким образом нам достаточно немного подправить код:

<? 
// additional photos 
$LINE_ELEMENT_COUNT = 2; // number of elements in a row 
if(count($arResult["MORE_PHOTO"])>0):?> 
<?foreach($arResult["MORE_PHOTO"] as $PHOTO):?> 
<? $file = CFile::ResizeImageGet($PHOTO, array('width'=>150, 'height'=>'112'), BX_RESIZE_IMAGE_EXACT, true); ?> 
<div class="more_photo"> 
<a href="<?=$PHOTO["SRC"]?>" name="more_photo"> 
<img border="0" src="<?=$file["src"]?>" width="<?=$file["width"]?>" height="<?=$file["height"]?>" 
alt="<?=$arResult["NAME"]?>" title="<?=$arResult["NAME"]?>" /> 
</a> 
</div> 
<?endforeach?> 
<?endif?>

И мы получаем список превьюшек с ссылками на оригиналы. В итоге при добавлении новости просто выбираем изображения при добавлении статьи или новости:

Дополнительные картинки в новостях Битрикс

Прикручиваем красотулечку

Итак, мы вывели превьюшки в новость, сделали их ссылками на полное изображение. Давайте теперь прикрутим к этому fancybox

Скачиваем архивчик с плагином и закидываем в корень сайта (можно конечно в любую папку, например в папку с шаблоном)

Добавляем в news.detail:

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script> 
<script> 
!window.jQuery && document.write('<script src="jquery-1.4.3.min.js"><\/script>'); 
</script> 
<script type="text/javascript" src="/fancybox/jquery.mousewheel-3.0.4.pack.js"></script> 
<script type="text/javascript" src="/fancybox/jquery.fancybox-1.3.4.pack.js"></script> 
<link rel="stylesheet" type="text/css" href="/fancybox/jquery.fancybox-1.3.4.css" media="screen" /> 
<link rel="stylesheet" href="style.css" /> 
<script type="text/javascript"> 
$(document).ready(function() { 
/* 
* Examples - images 
*/
$("a#example1").fancybox(); 
$("a#example2").fancybox({ 
  'overlayShow'	: false, 
  'transitionIn'	: 'elastic', 
      'transitionOut'	: 'elastic' 
});
$("a#example3").fancybox({ 
  'transitionIn'	: 'none', 
  'transitionOut'	: 'none'
}); 
$("a#example4").fancybox({ 
    'opacity': true, 
    'overlayShow' false, 
    'transitionIn'	: 'elastic', 
    'transitionOut': 'none' 
}); 
$("a#example5").fancybox(); 
   $("a#example6").fancybox({ 
   'titlePosition': 'outside', 
   'overlayColor'	: '#000', 
   'overlayOpacity': 0.9 
}); 
$("a#example7").fancybox({ 
    'titlePosition'	: 'inside' 
}); 
$("a#example8").fancybox({ 
    'titlePosition': 'over' 
}); 
$("a[rel=example_group]").fancybox({ 
   'transitionIn': 'none', 
   'transitionOut'	: 'none', 
   'titlePosition': 'over', 
   'titleFormat': function(title, currentArray, currentIndex, currentOpts) { 
   return '<span id="fancybox-title-over">Image ' + (currentIndex + 1) + ' / ' + currentArray.length + (title.length ? ' &nbsp; ' + title : '') + '</span>'; 
} 
}); 
/* 
* Examples - various 
*/ 
$("#various1").fancybox({ 
'titlePosition'		: 'inside', 
'transitionIn'		: 'none', 
'transitionOut'		: 'none' 
}); 
$("#various2").fancybox(); 
$("#various3").fancybox({ 
   'width': '75%', 
   'height': '75%', 
   'autoScale': false, 
   'transitionIn': 'none', 
   'transitionOut'	: 'none', 
   'type': 'iframe' 
}); 
$("#various4").fancybox({ 
    'padding': 0, 
    'autoScale': false, 
    'transitionIn': 'none', 
    'transitionOut': 'none' 
}); 
}); 
</script>

И в строчке


<a href="<?=$PHOTO["SRC"]?>" name="more_photo">

Дописываем


<a rel="example_group" href="<?=$PHOTO["SRC"]?>" name="more_photo"   title="<?=(strlen($arResult["DETAIL_PICTURE"]["DESCRIPTION"]) > 0 ? $arResult["DETAIL_PICTURE"]["DESCRIPTION"] : $arResult["NAME"])?>">
Alex_amz 07.09.2017
Добрый день!
Прочитал Вашу заметку https://camouf.ru/club/user/1/blog/48/# но так и не понял как убрать ссылки загрузить. Можете более подробно рассказать куда следует вставить код?
Спасибо!
Валерий Курейчик 01.11.2017
Делаю всё до пункта CFile::ResizeImageGet
Вроде бы слишком просто, чтобы напортачить . Но. Не выводится эта дополнительная картинка. Как будто бы ничего не сделал.
В папке news.detail/.default файл result_modifier.php есть. Полностью с вашим кодом.
В файл template.php просто в конец скопировал ваш код.
В инфоблоке свойство прописано правильно.
В чём может быть проблема?
Михаил Базаров 02.11.2017
Цитата
Валерий Курейчик написал:
Делаю всё до пункта CFile::ResizeImageGet
Вроде бы слишком просто, чтобы напортачить . Но. Не выводится эта дополнительная картинка. Как будто бы ничего не сделал.
В папке news.detail/.default файл result_modifier.php есть. Полностью с вашим кодом.
В файл template.php просто в конец скопировал ваш код.
В инфоблоке свойство прописано правильно.
В чём может быть проблема?
Может быть не указали в настройках компонента, что нужно это свойство MORE_PHOTO выводить
Сергей Стефанович 12.01.2018
Тоже хороший способ. без result_modifier.php
только как прикрутить сюда ресайз


Код
<?if(count($arResult['PROPERTIES']['MORE_PHOTO']['VALUE']) > 0 && intval($arResult['PROPERTIES']['MORE_PHOTO']['VALUE']) > 0):?>
   <?if(count($arResult['PROPERTIES']['MORE_PHOTO']['VALUE']) > 4):?>
      <div class="owl-carousel owl-theme">


               <?foreach($arResult['PROPERTIES']['MORE_PHOTO']['VALUE'] as $num=>$arItems):?>
                  <?$img_href = CFile::GetPath($arItems);?>
                  <a href="<?=$img_href?>" class="item" data-lightbox="example-set"><img src="<?=$img_href?>" class="img-responsive" alt="фото <?=$arResult['PROPERTIES']['MORE_PHOTO']['DESCRIPTION'][$num]?>"/></a>
               <?endforeach;?>


      </div>
   <?else:?>
      <div class="owl-carousel owl-theme">

            <?foreach($arResult['PROPERTIES']['MORE_PHOTO']['VALUE'] as $num=>$arItems):?>
               <?$img_href = CFile::GetPath($arItems);?>
               <a href="<?=$img_href?>" class="item"  data-lightbox="example-set"><img src="<?=$img_href?>" class="img-responsive" alt="фото <?=$arResult['PROPERTIES']['MORE_PHOTO']['DESCRIPTION'][$num]?>" /></a>
            <?endforeach;?>

      </div>
   <?endif;?>
<?endif;?>
 
Сергей Стефанович 06.02.2018
и как отресайзить все загружаемые фото сразу при загрузке в инфоблок ?
нашел вот такой способ

Код
<? // События которые срабатывают при создании или изменении элемента инфоблока AddEventHandler("iblock", "OnAfterIBlockElementAdd", "ResizeUploadedPhoto"); AddEventHandler("iblock", "OnAfterIBlockElementUpdate", "ResizeUploadedPhoto"); function ResizeUploadedPhoto($arFields) { global $APPLICATION; CModule::IncludeModule('iblock'); $IBLOCK_ID = 6; // ID инфоблока свойство которых нуждается в масштабировании $PROPERTY_CODE = "FOTO"; // код свойства $imageMaxWidth = 1000; // Максимальная ширина картинки $imageMaxHeight = 800; // Максимальная высота картинки // для начала убедимся, что изменяется элемент нужного нам инфоблока if($arFields["IBLOCK_ID"] == $IBLOCK_ID) {    $VALUES = $VALUES_OLD = array();    //Получаем свойство значение сво-ва $PROPERTY_CODE    $res = CIBlockElement::GetProperty($arFields["IBLOCK_ID"], $arFields["ID"], "sort", "asc", array("CODE" => $PROPERTY_CODE));    while ($ob = $res->GetNext()) {       $file_path = CFile::GetPath($ob['VALUE']); // Получаем путь к файлу       if($file_path) {          $imsize = getimagesize($_SERVER["DOCUMENT_ROOT"].$file_path); //Узнаём размер файла          // Если размер больше установленного максимума          if($imsize[0] > $imageMaxWidth or $imsize[1] > $imageMaxHeight) {             // Уменьшаем размер картинки             $file = CFile::ResizeImageGet($ob['VALUE'], array(                   'width'=>$imageMaxWidth,                   'height'=>$imageMaxHeight                ), BX_RESIZE_IMAGE_PROPORTIONAL, true);             // добавляем в массив VALUES новую уменьшенную картинку             $VALUES[] = CFile::MakeFileArray($_SERVER["DOCUMENT_ROOT"].$file["src"]);          } else {             // добавляем в массив VALUES старую картинку             $VALUES[] = CFile::MakeFileArray($_SERVER["DOCUMENT_ROOT"].$file_path);          }          // Собираем в массив ID старых файлов для их удаления (чтобы не занимали место)          $VALUES_OLD[] = $ob['VALUE'];       }    }    // Если в массиве есть информация о новых файлах    if(count($VALUES) > 0) {       $PROPERTY_VALUE = $VALUES; // значение свойства       // Установим новое значение для данного свойства данного элемента       CIBlockElement::SetPropertyValuesEx($arFields["ID"], $arFields["IBLOCK_ID"], array($PROPERTY_CODE => $PROPERTY_VALUE));       // Удаляем старые большие изображения       foreach ($VALUES_OLD as $key=>$val) {          CFile::Delete($val);       }    }    unset($VALUES);    unset($VALUES_OLD); } } ?>
 

как бы грамотнее настроить его для обработки нескольких инфоблоков
Сергей Стефанович 06.02.2018
Код
<?
// События которые срабатывают при создании или изменении элемента инфоблока
AddEventHandler("iblock", "OnAfterIBlockElementAdd", "ResizeUploadedPhoto";
AddEventHandler("iblock", "OnAfterIBlockElementUpdate", "ResizeUploadedPhoto";

function ResizeUploadedPhoto($arFields) {
  global $APPLICATION;
  CModule::IncludeModule('iblock');
  $IBLOCK_ID = 6; // ID инфоблока свойство которых нуждается в масштабировании
  $PROPERTY_CODE = "FOTO";  // код свойства
  $imageMaxWidth = 1000; // Максимальная ширина картинки
  $imageMaxHeight = 800; // Максимальная высота картинки
  // для начала убедимся, что изменяется элемент нужного нам инфоблока
  if($arFields["IBLOCK_ID"] == $IBLOCK_ID) {
   $VALUES = $VALUES_OLD = array();
   //Получаем свойство значение сво-ва $PROPERTY_CODE
   $res = CIBlockElement::GetProperty($arFields["IBLOCK_ID"], $arFields["ID"], "sort", "asc", array("CODE" => $PROPERTY_CODE));
   while ($ob = $res->GetNext()) {
      $file_path = CFile::GetPath($ob['VALUE'] // Получаем путь к файлу
      if($file_path) {
         $imsize = getimagesize($_SERVER["DOCUMENT_ROOT"].$file_path); //Узнаём размер файла
         // Если размер больше установленного максимума
         if($imsize[0] > $imageMaxWidth or $imsize[1] > $imageMaxHeight) {
            // Уменьшаем размер картинки
            $file = CFile::ResizeImageGet($ob['VALUE'], array(
                  'width'=>$imageMaxWidth,
                  'height'=>$imageMaxHeight
               , BX_RESIZE_IMAGE_PROPORTIONAL, true);
            // добавляем в массив VALUES новую уменьшенную картинку
            $VALUES[] = CFile::MakeFileArray($_SERVER["DOCUMENT_ROOT"].$file["src"]
         } else {
            // добавляем в массив VALUES старую картинку
            $VALUES[] = CFile::MakeFileArray($_SERVER["DOCUMENT_ROOT"].$file_path);
         }
         // Собираем в массив ID старых файлов для их удаления (чтобы не занимали место)
         $VALUES_OLD[] = $ob['VALUE']; 
      }
   }
   // Если в массиве есть информация о новых файлах
   if(count($VALUES) > 0) {
      $PROPERTY_VALUE = $VALUES;  // значение свойства
      // Установим новое значение для данного свойства данного элемента
      CIBlockElement::SetPropertyValuesEx($arFields["ID"], $arFields["IBLOCK_ID"], array($PROPERTY_CODE => $PROPERTY_VALUE));
      // Удаляем старые большие изображения
      foreach ($VALUES_OLD as $key=>$val) {
         CFile:elete($val);
      }
   }
   unset($VALUES);
   unset($VALUES_OLD);
  }
}
?>
Сергей Стефанович 06.02.2018
Решил вопрос


Код
<?
// События которые срабатывают при создании или изменении элемента инфоблока
AddEventHandler("iblock", "OnAfterIBlockElementAdd", "ResizeUploadedPhoto");
AddEventHandler("iblock", "OnAfterIBlockElementUpdate", "ResizeUploadedPhoto");

function ResizeUploadedPhoto($arFields) {
  global $APPLICATION;
  CModule::IncludeModule('iblock');
  $IBLOCK_ID = 32; // ID инфоблока свойство которых нуждается в масштабировании
  $PROPERTY_CODE = "MORE_PHOTO";  // код свойства
  $imageMaxWidth = 1280; // Максимальная ширина картинки
  $imageMaxHeight = 720; // Максимальная высота картинки
  
  // для начала убедимся, что изменяется элемент нужного нам инфоблока (в данном случае нескольких инфоблоков)

  if(($arFields["IBLOCK_ID"] == 32) || ($arFields["IBLOCK_ID"] == 31) || ($arFields["IBLOCK_ID"] == 17)) { 
   $VALUES = $VALUES_OLD = array();
   //Получаем свойство значение сво-ва $PROPERTY_CODE
   $res = CIBlockElement::GetProperty($arFields["IBLOCK_ID"], $arFields["ID"], "sort", "asc", array("CODE" => $PROPERTY_CODE));
   while ($ob = $res->GetNext()) {
      $file_path = CFile::GetPath($ob['VALUE']); // Получаем путь к файлу
      if($file_path) {
         $imsize = getimagesize($_SERVER["DOCUMENT_ROOT"].$file_path); //Узнаём размер файла
         // Если размер больше установленного максимума
         if($imsize[0] > $imageMaxWidth or $imsize[1] > $imageMaxHeight) {
            // Уменьшаем размер картинки
            $file = CFile::ResizeImageGet($ob['VALUE'], array(
                  'width'=>$imageMaxWidth,
                  'height'=>$imageMaxHeight
               ), BX_RESIZE_IMAGE_PROPORTIONAL, true);
            // добавляем в массив VALUES новую уменьшенную картинку
            $VALUES[] = CFile::MakeFileArray($_SERVER["DOCUMENT_ROOT"].$file["src"]);
         } else {
            // добавляем в массив VALUES старую картинку
            $VALUES[] = CFile::MakeFileArray($_SERVER["DOCUMENT_ROOT"].$file_path);
         }
         // Собираем в массив ID старых файлов для их удаления (чтобы не занимали место)
         $VALUES_OLD[] = $ob['VALUE']; 
      }
   }
   // Если в массиве есть информация о новых файлах
   if(count($VALUES) > 0) {
      $PROPERTY_VALUE = $VALUES;  // значение свойства
      // Установим новое значение для данного свойства данного элемента
      CIBlockElement::SetPropertyValuesEx($arFields["ID"], $arFields["IBLOCK_ID"], array($PROPERTY_CODE => $PROPERTY_VALUE));
      // Удаляем старые большие изображения
      foreach ($VALUES_OLD as $key=>$val) {
         CFile::Delete($val);
      }
   }
   unset($VALUES);
   unset($VALUES_OLD);
  }
}
?>
 
Anna Nazz 23.03.2018
Михаил, добрый день! У меня есть календарь лента с событиями, и  мне нужно что бы там выводились фотографии я делала все как в вашем видео, но у меня недоступны параметры в компоненте календарь, и естественно  я не могу в настройках детального просмотра выбирать свойства. Мне подсказали, что в файле result_modifier.php можно подключить это свойство, но это не работает.

вот что я пишу в result_modifier.php


Код
$GALLERY_ID = '57';
$VALUES = array();
    $res = CIBlockElement::GetProperty($IBLOCKS['15'], $GALLERY_ID, "sort", "asc", array("CODE" => "GALLERY"));
    while ($ob = $res->GetNext())
    {
        $VALUES[] = $ob['VALUE'];
    }



$arResult["GALLERY"] = array();
if(isset($arResult["PROPERTIES"]["GALLERY"]["VALUE"]) && is_array($arResult["PROPERTIES"]["GALLERY"]["VALUE"]))
{
foreach($arResult["PROPERTIES"]["GALLERY"]["VALUE"] as $FILE)
{
$FILE = CFile::GetFileArray($FILE);
if(is_array($FILE))
$arResult["GALLERY"][]=$FILE;
}
} 
 
Дмитрий Гаврилов 23.05.2018
Спасибо огромное, очень помогло!
Виталик Л. 31.03.2019
Добрый вечер. Михаил, а как картинки расположить рядом, горизонтально ?