Битрикс создание формы с загрузкой файлов

Для того, чтобы создать форму с загрузкой файлов нужно:

  • 1. Создать форму и подключить все скрипты валидации формы
  • 2. Создать инфоблок со свойствами, создать почтовый шаблон
  • 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 сообщение на указанный адрес в шаблон. Шаблонов писем может быть несколько и может быть разное содержание.

    Файлы можно прикреплять как вложения, но здесь рассмотрен более простой вариант.

    Дальше уже все проверять и тестировать.

    Скачать исходники Скачать исходники

    Надеюсь статья была полезной, оставьте отзыв или мнение, что можно улучшить.

    Интересные статьи по программированию:

    Уважаемый читатель!

    Ты можешь сделать проект Mirdeveloper.ru лучше!

    Написание статей требует много затрат, времени и сил, ресурсов, в том числе и денежных.

    Оставь чаевые, и будут новые статьи, и появятся видео.

    Это даст новые возможности в улучшении сайта

    Спасибо за то, что Вы с нами!


    Комментарии находятся на модерации или не добавлены.

    Для добавления комментариев необходимо зарегистрироваться и авторизоваться

    Также возможно авторизоваться через Социальную сеть Вконтакте (VK)