Тема: Дополнительный функционал на странице - проверка накоплений

Всем привет.
Стоит следующая задача..
Из 1С приходит на сервер xml файл, где есть поля фамилия, номер карты и сумма накопления.
Пользователь на странице должен ввести свои данные и получить сумму накопления.
С помощью js реализовал это за 5 минут, но в файле 56000 строк, тормозит.
Переделываю на php. И тут у меня проблемы.

Создал в functions.php функцию - парсер xml, работает прекрасно.
Создал стандартную страницу из админки.
Добавил туда форму https://yadi.sk/i/CCK-Es1w3Q9sab

И что делать дальше, даже не могу предположить..
Подскажите, пожалуйста, как передать данные из input в функцию парсера?
Может я не в том направлении двигаюсь и эту функцию нужно было создавать не в файле functions.php?

Thumbs up Thumbs down

2

Re: Дополнительный функционал на странице - проверка накоплений

Offtopic

Роман пишет:

С помощью js реализовал это за 5 минут, но в файле 56000 строк

Вашей плодовитости (работоспособности), можно только позавидовать!

Разрабатываю модули для ImageCMS Corporate (оплата PayPal).

3

Re: Дополнительный функционал на странице - проверка накоплений

Sempai пишет:

Offtopic

Роман пишет:

С помощью js реализовал это за 5 минут, но в файле 56000 строк

Вашей плодовитости (работоспособности), можно только позавидовать!

Точнее на  jQuery и действительно быстро. В спойлере сам код, может кому-то поможет, код из файла можно просто вставить в страничку в редакторе текста.

+ открыть спойлер
<div id="proverka">
<input placeholder="Введите фамилию" id="chek_сustomer"/>
<input placeholder="Введите № карты" id="chek_id"/>
<input type="button" value="Проверить" id="chek_btn"/>
<div id="content_div"></div>
<span id="loadImg">Пожалуйста, подождите, идёт обработка запроса.</span>
<script> 

jQuery(document).ready(function() {
        jQuery('#chek_btn').click(function(){
                ajaxGetXML();
        });
});
function ajaxGetXML(){
    
    if(jQuery('#chek_сustomer').val() ==  '' || jQuery('#chek_id').val() ==  ''){
        var html = "";
        html += "<span>Поалуйста, заполните все поля.</span>";
        jQuery('#content_div').html(html); // выводим данные
    }
    else
    {
            var html = "";
            html += "<span>Пожалуйста, подождите, идёт обработка запроса.</span>";
            jQuery('#content_div').html(html); // выводим данные
            jQuery.ajax({
                    type: "POST", // метод передачи данных
                    url: "/export.xml", // путь к xml файлу
                    dataType: "xml", // тип данных
                    // если получили данные из файла
                    success: function(data) {
                            var html = "";
                            // перебираем все теги discont
                    g_Percent = '';
                    g_Amount = '';
                    g_ID = '';
                                g_Customer = 'false';
                            jQuery(data).find('discont').each(function(){
                    
                    var Customer = jQuery(this).find('Customer').text(); // получаем значение тега Customer
                    var ID = jQuery(this).find('ID').text(); // получаем значение тега ID
                                    var Amount = jQuery(this).find('Amount').text(); // получаем значение тега Amount
                                    var Percent = jQuery(this).find('Percent').text(); // получаем значение тега Percent
                    
                    //проверка совпадений
                    if(Customer == jQuery('#chek_сustomer').val() && ID == jQuery('#chek_id').val() ){
                        g_Percent = Percent;
                        g_Amount = Amount;
                        g_ID = ID;
                        g_Customer = Customer;
                    }
                    
                            });
                
                if(g_Customer != 'false'){
                    html += "<p>";
                    html += "<hr/>";
                    html += "<label>Номер карты: "+g_ID+"</label>";
                        html += "<label>Фамилия: "+g_Customer+"</label>";
                    html += "<label>Сумма накопления: "+g_Amount+"</label>";   
                    html += "<label>Процент скидки: "+g_Percent+"</label>"; 
                    html += "<hr/>";
                    html += "</p>";
                    jQuery('#content_div').html(html);// выводим данные
                    
                }
                else {
                    html += "<span>Совпадений не найдено, попробуйте ещё раз.</span>";
                    jQuery('#content_div').html(html); // выводим данные
                    
                }
                    },
                    // если произошла ошибка при получении файла
                    error: function(){
                            alert('ERROR');
                    }
                     
            });
    }
}
</script> 
</div>

Thumbs up Thumbs down

4

Re: Дополнительный функционал на странице - проверка накоплений

Минусы этого метода: файл доступен для скачивания любому пользователю; долгая обработка при большом объёме самого файла.

Может всё таки кто-то подскажет, как лучше реализовывать свои php скрипты с формами на любой странице?

Thumbs up Thumbs down

5 Отредактировано Fire_Horse (30-11-2017 20:40:27)

Re: Дополнительный функционал на странице - проверка накоплений

https://yadi.sk/d/d2J-ssE03QCSnz

Кидаете в папку /application/modules/

Устанавливаете модуль:
- в главном меню в админке -> "Модули" -> "Все модули"
- на табах -> "Установить модули"
- "установить" напротив модуля Ajax

Открываете код модуля - должно быть все понятно.

Соответственно путь для отправки формы из примера будет:
/ajax_api/someform

Thumbs up Thumbs down

6

Re: Дополнительный функционал на странице - проверка накоплений

Fire_Horse пишет:

https://yadi.sk/d/d2J-ssE03QCSnz

Кидаете в папку /application/modules/

Устанавливаете модуль:
- в главном меню в админке -> "Модули" -> "Все модули"
- на табах -> "Установить модули"
- "установить" напротив модуля Ajax

Открываете код модуля - должно быть все понятно.

Соответственно путь для отправки формы из примера будет:
/ajax_api/someform

Fire_Horse, огромное спасибо, отличное решение.

Единственное, я не разобрался, как вернуть результат из обработчика на страницу с формой. Пока выкрутился с помощью моих любимых js костылей)))
Страница:

+ открыть спойлер

<div id="proverka">
<div id="chek_msg"></div>
<form action="/ajax_api/someform" method="get">
<input placeholder="Введите фамилию" name="chek_customer_inpt" id="chek_сustomer"/>
<input placeholder="Введите № карты" name="chek_id_inpt" id="chek_id"/>
<input type="submit" value="Проверить" id="chek_btn"/>
</form>
</div>
<script>
    var url=location.href.split('?');
    if (url[1]!=undefined) {
        discount=location.href.split('=')
        if (discount[1]!=undefined) {
            if (discount[1] != 0){
                document.getElementById('chek_msg').textContent = discount[1];
            }
            else{
                document.getElementById('chek_msg').textContent = 'Совпадений не найдено, попробуйте ещё раз.';
            }
        }
    }
</script>

Мой ajax_api.php

+ открыть спойлер

<?php

if (!defined('BASEPATH'))
    exit('No direct script access allowed');

class Ajax_api extends MY_Controller {
    public function __construct()
    {
        parent::__construct();
    }

    public function someform()
    {
        $customer_name=$_GET['chek_customer_inpt'];
        $customer_id=$_GET['chek_id_inpt'];
        $sxe =  simplexml_load_file("/exp.xml");
        $customer=NULL;
        $percent=0;
        foreach($sxe->discont as $item) {
            //var_dump($item);
            //echo '1<br>';
            if ($customer_name == $item->Customer && $customer_id == $item->ID) {
                $customer = $item->Customer;
                $percent = $item->Percent;
                //echo '-finish';
                //echo $customer;
            }
        }
        //var_dump($sxe);
        //echo '<script>alert(1)</script>';
        header('Location: /proverka?discount='.$percent);
    }

    /******************************************************/

    public function _install() {
        $this->db
            ->where('name', 'ajax_api')
            ->update('components', [
                'autoload' => 0,
                'enabled' => '1',
                'in_menu' => 0
            ]);
    }

    public function _deinstall() {}
}

Thumbs up Thumbs down

7

Re: Дополнительный функционал на странице - проверка накоплений

Ниже примеры. Могут быть ошибки - не проверял. Просто способы обработки формы.

С перезагрузкой страницы

+ открыть спойлер
<?php
// ajax_api
public function someform()
{
    $data = [];

    if ($postData = $this->input->post()) {
        $customer_name = $postData('chek_customer_inpt');
        $customer_id   = $postData('chek_id_inpt');
        $sxe           = simplexml_load_file("/exp.xml");
        $customer      = NULL;
        $percent       = 0;

        $data['dataHandleResult'] = [
            'status'  => 'error',
            'message' => "Совпадений не найдено, попробуйте ещё раз."
        ];

        foreach ($sxe->discont as $item) { 
            if ($customer_name == $item->Customer && $customer_id == $item->ID) {
                $customer = $item->Customer; 
                $percent  = $item->Percent; 

                $data['dataHandleResult'] = [
                    'status'  => 'success',
                    'message' => "Процент скидки составляет: {$percent}"
                ];
            }
        }
    }

    \CMSFactory\assetManager::create()
            ->setData($data)
            ->render('someform', true);
}
?>

Текущий шаблон вашей формы меняете на

{echo $CI->load->module('ajax_api')->someform()}

Создаете tpl-файл: /templates/имя_вашего_шаблона/ajax_api/someform.tpl

<div id="proverka">
  {if $dataHandleResult}
  <div id="chek_msg" class="{$dataHandleResult['status']}">{$dataHandleResult['message']}</div>
  {/if}
  <form action="/" method="get">
    <input placeholder="Введите фамилию" name="chek_customer_inpt" id="chek_сustomer" value="{$CI->input->post('chek_customer_inpt')}" required>
    <input placeholder="Введите № карты" name="chek_id_inpt" id="chek_id" value="{$CI->input->post('chek_id_inpt')}" required>
    <input type="submit" value="Проверить" id="chek_btn"/>
  </form>
</div>

Таким образом из текущего файла шаблона будет вызываться метод, который будет отрисовывать и обрабатывать форму.


Без перезагрузки на jquery:

+ открыть спойлер
<?php
// ajax_api
public function someform()
{
    $customer_name = $this->input->post('chek_customer_inpt');
    $customer_id   = $this->input->post('chek_id_inpt');
    $sxe           = simplexml_load_file("/exp.xml");
    $customer      = NULL;
    $percent       = 0;

    foreach ($sxe->discont as $item) { 
        if ($customer_name == $item->Customer && $customer_id == $item->ID) {
            $customer = $item->Customer; 
            $percent  = $item->Percent; 

            exit(json_encode([
                'status'  => 'success',
                'message' => "Процент скидки составляет: {$percent}"
            ]));
        }
    }

    exit(json_encode([
        'status'  => 'error',
        'message' => "Совпадений не найдено, попробуйте ещё раз."
    ]));
}
?>
<div id="proverka">
  <div id="chek_msg" class="js-check-msg"></div>
  <form action="/ajax_api/someform" method="get" class="js-my-form">
    <input placeholder="Введите фамилию" name="chek_customer_inpt" id="chek_сustomer" required>
    <input placeholder="Введите № карты" name="chek_id_inpt" id="chek_id" required>
    <input type="submit" value="Проверить" id="chek_btn"/>
  </form>
</div>

<script>
  $('.js-my-form').on('submit', function(e) {
    e.preventDefault();
    var $this = $(this);

    $.post(this.action, $this.serialize(), function(response) {
      $('.js-check-msg').html(response.message);
    }, 'json');
  });
</script>

Без перезагрузки на чистом js:

+ открыть спойлер
<?php
// ajax_api
public function someform()
{
    $customer_name = $this->input->post('chek_customer_inpt');
    $customer_id   = $this->input->post('chek_id_inpt');
    $sxe           = simplexml_load_file("/exp.xml");
    $customer      = NULL;
    $percent       = 0;

    foreach ($sxe->discont as $item) { 
        if ($customer_name == $item->Customer && $customer_id == $item->ID) {
            $customer = $item->Customer; 
            $percent  = $item->Percent; 

            exit(json_encode([
                'status'  => 'success',
                'message' => "Процент скидки составляет: {$percent}"
            ]));
        }
    }

    exit(json_encode([
        'status'  => 'error',
        'message' => "Совпадений не найдено, попробуйте ещё раз."
    ]));
}
?>
<div id="proverka">
  <div id="chek_msg" class="js-check-msg"></div>
  <form action="/ajax_api/someform" method="get" class="js-my-form">
    <input placeholder="Введите фамилию" name="chek_customer_inpt" id="chek_сustomer" required>
    <input placeholder="Введите № карты" name="chek_id_inpt" id="chek_id" required>
    <input type="submit" value="Проверить" id="chek_btn"/>
  </form>
</div>

<script>
  (function () {
    var myForm   = document.querySelector('.js-my-form');
    var checkMsg = document.querySelector('.js-check-msg');

    if (! (myForm && checkMsg)) return;

    var showMessage = function(message) {
      checkMsg.textContent = message;
    }

    myForm.addEventListener('submit', function (e) {
      e.preventDefault();
      var request = new XMLHttpRequest();
      request.send(new FormData(myForm));

      request.open('POST', myForm.action, true);
      request.setRequestHeader("X-Requested-With", "XMLHttpRequest");

      request.onload = function() {
        if (this.status >= 200 && this.status < 400) {
          try {
            var responseData = JSON.parse(this.responseText);

            showMessage(responseData.message);
            return;
          } catch(e) {}
        }

        showMessage('Техническая ошибка. Попробуйте позднее.');
      }
    });
  }());
</script>

Thumbs up Thumbs down

8

Re: Дополнительный функционал на странице - проверка накоплений

Fire_Horse, спасибо огромное ещё раз, выбрал вариант на чистом js, всё работает. Я как раз боролся с проблемами кодировки в моём решении. В Вашем этих вопросов нет. Очень интересно и полезно на примере этой задачи, освоить работу с imagecms.

Thumbs up Thumbs down