Битрикс создание формы с загрузкой файлов
                    - Содержание:
 - 1. 1. Создание формы и подключение всех скриптов для валидации формы
 - 2. 2. Создать инфоблок со свойствами, создать почтовый шаблон
 - 3. 3. Создать скрипт php для проверки файлов, их загрузки, сохранением в инфоблок, отправки на почту уведомлений
 
Для того, чтобы создать форму с загрузкой файлов нужно:
1. Создание формы и подключение всех скриптов для валидации формы
Созданим папку /return/ и поместим туда все файлы с формой.
Файл index.php будет таким:
<?require($_SERVER["DOCUMENT_ROOT"]."/bitrix/header.php");
$APPLICATION->SetPageProperty("title", "Форма с загрузкой файлов Mirdeveloper");
$APPLICATION->SetTitle("Форма с загрузкой файлов");
global $APPLICATION;
////$APPLICATION->AddHeadScript("jquery-3.3.1.min.js");
$APPLICATION->AddHeadScript("/return/jquery.mask.js");
$APPLICATION->AddHeadScript("/return/jquery.validate.min.js");
$APPLICATION->AddHeadScript("/return/script.js");
$APPLICATION->SetAdditionalCSS("/return/style.css");
?>
<div class="container">
    <div class="row">
	<div class="col-xl-12 col-md-4 rules_form_new">
	  <div class="map__feedback" style="position: relative; top: 0px; margin: 15px 0;">
	     <form id="form-rules-return" method="post" enctype="multipart/form-data" style="max-width: 100%;">
	       <div class="form-group">
	            <input class="map__input-text form-control" type="text" name="name" placeholder="ФИО" <?/*required=""*/?>>
	       </div>
	        <div class="form-group">
	          <input class="map__input-text form-control" type="text" name="phone" placeholder="Телефон" required="">
	         </div>
	      <div class="form-group">
	       <input class="map__input-text form-control" type="text" name="email" placeholder="E-mail" required="">
	       </div>
	    <div class="form-group">
	         <span class="file_name_rules">Фото 1</span>
	         <div class="fl_upld">
	             <label><input id="fl_inp" class="map__input-file form-control" type="file" name="file" placeholder="Фото отвеса" >Выберите файл</label>
	               <div id="fl_nm">Файл не выбран</div>
	           </div>
	       </div>
	      <div class="form-group">
	           <span class="file_name_rules">Копия 1</span>
	          <div class="fl_upld">
	             <label><input id="fl_inp1" class="map__input-file form-control" type="file" name="file1"  placeholder="Копия чека" >Выберите файл</label>
	                 <div id="fl_nm1">Файл не выбран</div>
	            </div>
	       </div>
	 <div class="form-group">
	   <input class="map__input-checkbox form-control" type="checkbox" name="terms" id="map__input-checkbox" checked="" required="">
	    <label class="map__input-checkbox-label terms_l" for="map__input-checkbox">Оставляя свои данные я соглашаюсь с
	     <a class="map__input-link" href="/privacy/">Политикой конфиденциальности</a>
	   </label>
	</div>
	                
	  <div class="result error"  hidden></div>
	 <button class="button_fill map__button modal__button" type="submit">Отправить</button>
	</form>
<!-- loader -->
   <div class="formStatus-loaded">
	  <img class="formStatus-loaded-icon" id="loadImg" src="load.gif">
</div>
</div>
</div>
<img style="display: none;" id="loadImg" src="load.gif" />
	</div>
</div>
<div class="modal fade modal__registration modal__call" id="myModalCall-done" tabindex="-1" role="dialog" aria-labelledby="myModalCallLabel">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
                <h4 class="modal-title map__heading" id="myModaCalllLabel">Уведомление</h4>
            </div>
            <div class="modal-body">
                <span class="result done">
                    Ваша заявка успешно отправлена.
                    
                </span>
            </div>
            <div class="modal-footer">
                <button class="button_fill map__button modal__button" data-dismiss="modal" aria-label="Close">Ок</button>
            </div>
        </div>
    </div>
</div>
<?require($_SERVER["DOCUMENT_ROOT"]."/bitrix/footer.php");?>
 
Скрипты и стили подключены через методы Битрикс. В форме с файлами будет сделана подмена стандартной кнопки (свой стили), чтобы кнопка была более презентабельной.
Далее необходимо создать файл со скриптом, script.js с содержимым кода.
	$(document).ready(function(){
    //добавляем маску на поле телефон
    var customOptions = {
      onKeyPress: function(val, e, field, options) {
        if (val.replace(/\D/g, '').length===2)
        {
            val = val.replace('8','');    
            field.val(val);
         }
         field.mask("+7 (999) 999-99-99", options);
        },
        placeholder: "+7 (___) ___-__-__" 
    };
    $("input[name=phone]").mask("+7 (999) 999-99-99", customOptions);
const formAnimationLoader = () => {
  // найдем элемент с изображением загрузки и уберем невидимость:
  var loaderBox = $(".formStatus-loaded");
  loaderBox.toggleClass('fs-show');
}
function preg_match (regex, str) {
  return (new RegExp(regex).test(str))
}
    //  страница c формой
$("#form-rules-return").validate({
    errorPlacement: function(error, element) {
        error.insertBefore(element);
    },
    rules: {
        name:{
            required: true,
            minlength: 4
        },
        phone:{
            required: true,
            minlength: 5
        },
        
        email:{
            required: true,
        },
        file:{
            required: true,
        },
        file1:{
            required: true,
        },
    },
    messages: {
        name: {
            required: "Поле имя компании обязательно для заполнения",
            minlength: jQuery.validator.format("Длина названия компании должна быть больше 4-ти символов")
        },
        phone:{
            required: "Поле 'Телефон' обязательно для заполнения",
            minlength: jQuery.validator.format("Проверьте правильность заполнения поля")
        },
        email:{
            required: "Поле 'Email' обязательно для заполнения",
        },
        file:{
            required: "Поле 'Фото 1' обязательно для заполнения",
        },
        file1:{
            required: "Поле 'Копия 1' обязательно для заполнения",
        },
    },
    submitHandler: function(form) {
        var form = $('#form-rules-return')[0];
        console.log(form);
        console.log("=====");
        formAnimationLoader();
      
        $.ajax({
            type: 'post',
            url: '/return/ajax_form.php',
            //dataType: 'json',
            type: 'POST',
            data: new FormData(form),
            processData: false,
            contentType: false,
           
            success: function(response) {
                formAnimationLoader();
                
              //// console.log("response=" + JSON.stringify(response, null, 4));
               
                 if (response==='INVALID FILE SIZE'){
                    // здесь ставим своё уведомление о том, что превышен размер файла
                    var err_text_size = "Превышен размер файла";
                    //$('#form-rules-return').children('.result').text(response).show();
                    $('#form-rules-return').children('.result').text(err_text_size).show();
                    return;
                }
                if (response==='INVALID FILE TYPE'){
                    // здесь ставим своё уведомление о том, что не тот тип файла (не картинка)
                    var err_text = "Неверный формат файла, необходимо загружать изображения";
                    // $('#form-rules-return').children('.result').text(response).show();
                     $('#form-rules-return').children('.result').text(err_text).show();
                    return;
                }
                //получаем ответ и разбираем его, преобразуя в объект
                var data_response = JSON.parse(response);// response["data"];
                var data = Number(data_response["data"]);
                var data_id = data_response["id"];
                /*console.log(data_response);
                 console.log(data);
                 */
                if (data==1){
                    console.log('response='+response);
                    grecaptcha.reset();
                    $('#form-rules-return').children('.result').text('').hide();
                    $('#form-rules-return').each(function(indx){        
                        $('input , textarea').removeClass("error , valid");
                    });
                    $('#form-rules-return').trigger('reset');
                    //$('#modal_create_act').modal('toggle');
$('#myModalCall-done span.result').html('Ваша заявка № '+data_id+' успешно отправлена. Уведомление отправлено на Ваш email адрес');
                    $('#myModalCall-done').modal('show');   
                }
                else{
                    $('#form-rules-return').children('.result').text(response).show();
                    return;
                }
            }
        });
        //successForm(form);
    }
});
});
$(document).ready( function() {
    $("#fl_inp").change(function(){
         var filename = $(this).val().replace(/.*\\/, "");
         $("#fl_nm").html(filename);
    });
    $("#fl_inp1").change(function(){
         var filename = $(this).val().replace(/.*\\/, "");
         $("#fl_nm1").html(filename);
    });
});
 
Пояснения по файлам:для валидации форм используется jquery validate. Для телефона используется маска, jquery input mask.
Если форма не заполнена, то валидатор сообщит об этом:

2. Создать инфоблок со свойствами, создать почтовый шаблон
Далее переходим в админ панель Битрикс и создаем свойства: имя, телефон, фотография, копия. Будет 2 файла с картинками.
Переходим в Настройки-Почтовые и смс события-Типы событий в меню админки Битрикс. Или по адресу: /bitrix/admin/type_edit.php?lang=ru и создаем следующее содержание.
Создаем новое событие: FORM_RULES_RETURN с памятку с полями:
#NAME# - ФИО #EMAIL# - Email #PHONE# - Телефон #PHOTO# - Фото #PHOTO1# - Фото копии
В почтовых шаблонах выбираем созданное событие FORM_RULES_RETURN и добавляем поля, которые есть в форме.
Сообщение почтового шаблона будет таким.
<table style="border-collapse: collapse; width: 378pt;"> <tbody> <tr style="height: 0pt;"> <td> <p> <span style="color: #353744;">ФИО: #NAME# </span> </p> </td> </tr> <tr style="height: 0pt;"> <td> <p> <span style="color: #353744;">Телефон: #PHONE# </span> </p> </td> </tr> <tr style="height: 0pt;"> <td> <p> <span style="color: #353744;">Электронная почта: #EMAIL# </span> </p> </td> </tr> <tr style="height: 0pt;"> <td> <p> <span style="color: #353744;"> Фото: #PHOTO#</span> </p> </td> </tr> <tr style="height: 0pt;"> <td> <p> <span style="color: #353744;"> Копия: #PHOTO1#</span> </p> </td> </tr> </tbody> </table>
3. Создать скрипт php для проверки файлов, их загрузки, сохранением в инфоблок, отправки на почту уведомлений
Скрипт называется ajax_form.php и будет со следующим содержимым.
<?
require_once($_SERVER['DOCUMENT_ROOT'] . "/bitrix/modules/main/include/prolog_before.php");
?>
<?
//проверяем размер файла
if ($_FILES['file']['error']=='1'){
    echo 'INVALID FILE SIZE';
    die();
}
if ($_FILES['file1']['error']=='1'){
    echo 'INVALID FILE SIZE';
    die();
}
// если есть вложение
if (!empty($_FILES['file']['tmp_name']) && !empty($_FILES['file1']['tmp_name'])) {    
    //здесь проверяем расширение (картинка):
    if(strripos($_FILES['file']['type'], 'image')!==false 
and strripos($_FILES['file1']['type'], 'image')!==false){
	  // echo json_encode($_FILES);
	  // Закачиваем файл в /tmp_img
      //для этого в корне создаем папку tmp_img
        $name_file = $_FILES['file']['name'];
        $name_file1 = $_FILES['file1']['name'];
        $uploads_dir = $_SERVER['DOCUMENT_ROOT'].'/tmp_img';
        $is_moved = move_uploaded_file($_FILES['file']['tmp_name'], "$uploads_dir/$name_file");
        $is_moved1 = move_uploaded_file($_FILES['file1']['tmp_name'], "$uploads_dir/$name_file1");
	
        if ($is_moved && $is_moved1){
            // если всё ок:
            // действия...
            CModule::IncludeModule("iblock");
            $name = $_POST["name"];
            $phone = $_POST["phone"];
            $email = $_POST["email"];
            $el = new CIBlockElement;
            $props = array();
            $props['IBLOCK_ID'] = 52; // ID инфоблока
            $props['ACTIVE'] = 'Y';
            $props['NAME'] = 'Обращение от '.$name.' '.date('d.m.Y H:i:s');
            $props['ACTIVE_FROM'] = date('d.m.Y H:i:s');
            $arParams = array("replace_space" => "-", "replace_other" => "-");
			$trans = Cutil::translit($name, "ru", $arParams);
			$props["CODE"] = $trans.mt_rand();
            $property_values = array();
            //PHOTO
            $property_values['PHOTO'] = CFile::MakeFileArray( $uploads_dir."/".$name_file);
            $property_values['PHOTO1'] = CFile::MakeFileArray( $uploads_dir."/".$name_file1);
            $property_values['PHONE'] = $phone;
            $property_values['MAIL'] = $email;
            $props['PROPERTY_VALUES'] = $property_values;
         
            //добавляем элемент в инфоблок:
           // unlink ($uploads_dir."/".$name_file);
            if($new_el = $el->Add($props)){
            	unlink ($uploads_dir."/".$name_file);
            	unlink ($uploads_dir."/".$name_file1);
            	$resItemsList = CIBlockElement::GetList(
		array(),
		 Array("IBLOCK_ID"=>52, "CODE" => $props["CODE"]),
		 false,
		 false,
		 array()
		);
		while($item = $resItemsList->GetNextElement())
		{
		$element = $item->GetFields();
    		$element['PROPERTIES'] = $item->GetProperties();
	        $arElems = $element; // соответствие XML_ID => ID
		}
	$photo_one =CFile::GetPath($arElems['PROPERTIES']['PHOTO']['VALUE']);
	$photo_one_min = CFile::ResizeImageGet(
        $arElems['PROPERTIES']['PHOTO']['VALUE'],
         array(
          'width'=>200,
            'height'=>200
           ),
        BX_RESIZE_IMAGE_PROPORTIONAL,
      Array(
    "name" => "sharpen",
      "precision" => 0
    )
  );
				
$photo_one = "<a style='color: #4c5d68;' href='https://".$_SERVER["HTTP_HOST"].$photo_one."'>
<img style='width:200px; ' src='https://".$_SERVER["HTTP_HOST"].$photo_one_min['src']."'></a>";
$photo_to = CFile::GetPath($arElems['PROPERTIES']['PHOTO1']['VALUE']);
$photo_to_min = CFile::ResizeImageGet(
 $arElems['PROPERTIES']['PHOTO1']['VALUE'],
array(
 'width'=>200,
'height'=>200
 ),
 BX_RESIZE_IMAGE_PROPORTIONAL,
 Array(
 "name" => "sharpen",
  "precision" => 0
  )
 );
				//$photo_to = 'https://'.$_SERVER["HTTP_HOST"].$photo_to;
$photo_to = "<a  style='color: #4c5d68;' href='https://".$_SERVER["HTTP_HOST"].$photo_to."'>
<img style='width:200px; ' src='https://".$_SERVER["HTTP_HOST"].$photo_to_min['src']."'></a>";
            	// Отправка письма клиенту
	$sitename = 's1';
	$emailEvent = "FORM_RULES_RETURN";
	$arEventFields = array(
	 'NAME' => $name,
	 'EMAIL' => $email,
	 'PHONE' => $phone,
	 'PHOTO' => $photo_one,
	'PHOTO1' => $photo_to,
					    
);
$return['id'] = $arElems["ID"];
$return['data'] = 1;
					
CEvent::SendImmediate($emailEvent, $sitename, $arEventFields);
                echo json_encode($return);//'OK';
            }
            else{
            	unlink ($uploads_dir."/".$name_file);
            	unlink ($uploads_dir."/".$name_file1);
				echo "Error: ".$el->LAST_ERROR;
            }
            // удаляем темповый файл:
        }else{
            echo 'ERROR FILE MOVED';
        }
    }else{
        echo 'INVALID FILE TYPE';
    }
}
 
Здесь необходимо ввести номер информационного блока, чтобы все было корректно. В данном случае это 52 инфоблок.
Также нужно создать в корне папку для временного сохранения файлов картинок: tmp_img
Вначале происходит запись в инфоблок. Затем получение файлов из инфоблока. В письме уже создается мини-версия картинок(превью) и загруженные изображения. После отсылается email сообщение на указанный адрес в шаблон. Шаблонов писем может быть несколько и может быть разное содержание.
Файлы можно прикреплять как вложения, но здесь рассмотрен более простой вариант.
Дальше уже все проверять и тестировать.
Надеюсь статья была полезной, оставьте отзыв или мнение, что можно улучшить.
                            
                        
                                
                                
                                
                                
          
                        
Комментарии находятся на модерации или не добавлены.
Для добавления комментариев необходимо зарегистрироваться и авторизоваться
Также возможно авторизоваться через Социальную сеть Вконтакте (VK)