Отправка результатов MyTestXPro методом POST на веб-сервер в Интернет

Материал из MyTestXPro Wiki Help
Перейти к навигации Перейти к поиску

Если программа используется в компьютерном классе, то удобно раздавать тесты и принимать результаты с помощью модуля Журнал. Но может возникнуть необходимость получать результаты с удаленных компьютеров (самостоятельное выполнение тестов дома или дистанционное обучение). Модуль Журнал может работать не только в локальной сети, но и через сеть Интернет. Но возникают дополнительные сложности - например, как минимум, Ваш компьютер должен быть виден модулям тестирования через Интернет (т.е. иметь внешний "белый" IP)...

В этом случае можно организовать отправку результатов по электронной почте или на web-сервер. Настроить отправку по электронной почте проще, но собирать результаты таким способом не очень удобно. Для отправки результатов на web-сервер надо повозиться чуть дольше, но результат стоит затраченных усилий.

Result2web2.png

Итак, Вы решили собирать результаты тестирования таким способом. Рассмотрим как это можно организовать. Конечно, неплохо бы иметь некоторые знания по программированию и размещению сайтов в Интернет, но можно обойтись и без них и использовать готовые скрипты. Если у Вас возникнуть вопросы, то задать их можно в vk.com/MyTestXPro

Алгоритм действий:

1) Зарегистрироваться на хостинге с поддержкой PHP. Это самый длительный этап.


Для начала можно, например, на бесплатном https://ru.000webhost.com 

2) Закинуть архив со скриптами ab5ff96b-afc0-48e6-8157-39ee02df3ce9.zip на сервер в public_html (корневую папку для веб-страниц).

3) Распаковать этот архив в текущую папку (поставить путь "." (точку без кавычек)). Если в другую папку, то потом не забудьте поменять пути для результатов.

4) Зайти в папку ab5ff96b-afc0-48e6-8157-39ee02df3ce9 и папке results поставить права неё запись (755).

5) В настройках POST программы тестирования указать адрес отправки http://ВАШСАЙТ/ab5ff96b-afc0-48e6-8157-39ee02df3ce9/save.php и галочку "отправлять результаты в web".

5) Проверить, что в параметрах теста стоит "отправлять результаты в web".

1. веб-сервер 2. настроить 3. настроить программу

(или, если уже есть, использовать свой хостинг).

Отправка результатов на веб-сервер требуется наличия веб-сервера, где можно организовать прием, все нужные права доступа и знания по программированию для веб, например на PHP.

Примеры скриптов для версии 11.0.0.60 доступны по ссылке https://yadi.sk/d/E_D8jXf5pycoNg.


Логика приема и обработки результатов на веб-сервере может быть у каждого своя, в этом разделе приведем один из примеров от которого можно отталкиваться. В данном примере не будем использовать базы данных, а для простоты только файлы, вы же можете организовывать работу более сложным и гибким образом.

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

Для того чтобы модуль тестирования мог отправлять результаты на веб-сервер необходимо в параметрах теста разрешить данную операцию – Параметры теста → Сохранение и вывод результатов → Отправлять результаты в веб.

Так же необходимо настроить модуль тестирования. В настройках нужно установить переключатель "Разрешить отправлять результаты в web" и указать адрес (URL) страницы, которой будут передаваться результаты. Так же можно задать параметры прокси-сервера (через правку файла настроек). В настройках модуля тестирования и настройках автономного теста данные опции (в этой версии) находятся на вкладке с настройками отправки данных по эл. почте.

И, естественно, у вас должен быть веб-сервер, где вы разместите страницу (скрипт) приема и обработки результатов.

Например, скрипт на PHP для приема и сохранения результатов может выглядеть так:

<?php
  ## MyTestXPro http://mytestx.pro
  ## скрипт для приёма и сохранения результатов тестирования от модуля тестирования или автономного теста MyTestXPro методом POST
  ## в настройках программы MyTestXPro (точнее в модуле тестирования) в "настройки POST" адрес указываем типа 
  ## http://ВАШ-САЙТ/7D70493E-1D0B-4DCA-9E23-BE0046879A4B/SaveResult.php?key=8F480FED-621A-41E1-8CB7-E6D4CC9DB76B

  # можно проверить ключ (произвольная переменная (метод GET) в адресе скрипта)
  //if ($_GET['key'] != '8F480FED-621A-41E1-8CB7-E6D4CC9DB76B') return; 

  # проверка связи
  if(isset($_POST['Test']) and $_POST['Test'] == 'Test'){ 
    echo 'OK';
    return;
  }
  # проверка данных
  if(!isset($_POST['UId'])){
    echo 'Нет данных!';
    return;
  } 

  # временная зона
  date_default_timezone_set('Europe/Moscow');  
  
  # папка с результатами (не забудьте задать права доступа 766 к этой папке, чтобы можно было в нее записывать файлы)
  # можно задать как-то, например, $_SERVER['DOCUMENT_ROOT'].'/results/' 
  $file_dir = $_SERVER['DOCUMENT_ROOT'].'/ab5ff96b-afc0-48e6-8157-39ee02df3ce9/results/';
  # текстовый файл с результатами (в папке с результатами)
  $file_name = $file_dir . 'data.txt';
  //$file_name_csv = $file_dir . 'data.csv';
  # папка для файлов результатов *.mtxpr 
  $upload_path_files = $_SERVER['DOCUMENT_ROOT'].'/ab5ff96b-afc0-48e6-8157-39ee02df3ce9/results/';    
  
  # секретный ключ должен быть такой как в программе (задается в настройках ini-файла, для защиты необходимо указать/изменить)
  $SecretKey = '858374A9-EB92-4DAE-AF9C-C3D917C6E152'; 
  $md5SecretKey = md5($SecretKey);
  
  
  # получаем данные, отправленные методом POST  
  $Key0 = $_POST['Key0']; //случайная строка от программы для проверки Key1 и Key2
  $md5Key0 = md5($Key0);  
  $Key1 = $_POST['Key1']; //Key1 - проверка хеша файла теста = md5(md5(файла теста).md5(SecretKey).md5(Key0))
  $Key2 = $_POST['Key2']; //Key2 - проверка хеша UId теста = md5(md5(UId теста).md5(SecretKey).md5(Key0))
  $Key3 = $_POST['Key3']; //Key3 - проверка хеша = md5(UTF8(UID теста, имя, оценка, секрет, key0))
  
  # текст полей в кодировке UTF-8  
  $UId = $_POST['UId'];   
  $UserName = $_POST['UserName'];
  if ($UserName == '') return;  
  $UserGroup = $_POST['UserGroup'];  
  $Mark = $_POST['Mark'];
  $Result = $_POST['Result'];  
  $MaskOfResult = $_POST['MaskOfResult']; 
  
  $ip = $_SERVER['REMOTE_ADDR'];
  $today = date("d.m.Y H:i:s");  
  
  //$Version = $_POST['Version']; 

  # строка с данными разделенными ";", можно открыть в электронных таблицах или разобрать как-то самому
  $CSV = $_POST['CSV'];  
  
  # для защиты нужно раскомментировать нужные строки
  //$_Key2 = md5(md5($UId).$md5SecretKey.$md5Key0);  
  //if ($Key2 != $_Key2) return;  
  
  //$_Key3 = md5($UId.$UserName.$Mark.$SecretKey.$Key0); 
  //if ($_Key3 != $Key3) return;   	
  
  # файл с результатами
  if(isset($_FILES['file']['name']) && !empty($_FILES['file']['name'])){
    # проверка, что нет ошибок при загрузке
    if($_FILES['file']['error'] != UPLOAD_ERR_OK) return; 
  
    # проверка расширения файла результатов
    $upload_fn = explode(".", $_FILES['file']['name']);
    if(empty($upload_fn[1]) || ($upload_fn[1] != 'mtxpr')) return;   
    
    # загружаемый файл превысил допустимое значение ... байт
    if($_FILES['file']['size'] > 1000000) return;    

    # проверка что файл результатов начинается с MyTestXResult
    $handle = fopen($_FILES['file']['tmp_name'], "r");
    $contents = fread($handle, 13);
    fclose($handle);  
    if ($contents != 'MyTestXResult') return;
    
    # имя файла под которым сохраним результат
    $upload_file_name = time() . '_' . $_FILES['file']['name']; 
    $upload_file_name = str_replace('/', '', $upload_file_name);
    $upload_file_name = str_replace('\\', '', $upload_file_name);
    $upload_new_file_name = $upload_path_files . $upload_file_name;
  
    # добавляем файл в каталог (сохраняем файл с результатами)
    if(!move_uploaded_file($_FILES['file']['tmp_name'], $upload_new_file_name)) $upload_new_file_name = '';  
  } 
  //$_Key1 =  md5(md5_file($upload_new_file_name).$md5SecretKey.$md5Key0);
  //if ($Key1 != $_Key1) return;  
  
  # теперь сохраним данные в текстовый файл (или можно сделать сохранение в БД)
  
  # имя файла результатов запишем с путем от корня сайта
  $upload_new_file_name = str_replace($_SERVER['DOCUMENT_ROOT'], '', $upload_new_file_name);
  $upload_size = $_FILES['file']['size'];
  
  $str = $today . "\t" . $ip . "\t" . $UserName . "\t" . $UserGroup . "\t" . $Mark . "\t" . $Result . "\t" . $MaskOfResult . "\t" . $upload_new_file_name . "\t" . $upload_size . "\t" . $CSV . "\r\n";   
  # если файл должен быть в кодировке Windows-1251, то строки с iconv нужно убрать или закомментировать  
  //$str = iconv("UTF-8", "Windows-1251", $str);
  
  # пишем результаты в текстовый файл
  $fd = fopen($file_name, 'a') or die('error');
  flock($fd,2);
  
  fputs($fd,$str);

  flock($fd,3);
  fclose($fd);  
  
  # если все хорошо, отправим обратно ОК
  echo 'OK'; 
?>

Данный скрипт сохранит результаты в текстовый файл и сохранит файл с (защищенными) результатами. Данные передаются методом POST, как обычной формой.

Пример скрипта, который отображает полученные результаты таблицей и дает скачать каждый отдельный результат:

<?php
  ## MyTestXPro http://mytestx.pro
  ## скрипт показа результатов

  echo '<!DOCTYPE HTML>';
  echo '<html>';
  echo ' <head>';
  echo '  <title>Результаты</title>';
  echo '  <meta charset="UTF-8">';
  echo '  <link rel="stylesheet" type="text/css" href="style.css">';
  echo ' </head>';
  echo ' <body>';
  
  
  # папка с результатами
  $file_dir = $_SERVER['DOCUMENT_ROOT'].'/ab5ff96b-afc0-48e6-8157-39ee02df3ce9/results/';
  # текстовый файл с результатами (в папке с результатами)
  $file_name = $file_dir . 'data.txt';
  
  # открываем файл и формируем таблицу  
  $f = file($file_name);
  $table = '<table>';
  $table .= '<tr><th>№</th><th>Дата</th><th>IP</th><th>Имя</th><th>Группа</th><th>Оценка</th><th>Результат в % от макс. баллов</th><th>Маска результата</th><th>Файл результата</th><th>Размер файла</th><tr>'; //+<th>CSV</th>

  $count_res = count($f);
  for($i=0; $i<$count_res; $i++){
    //$line = iconv('utf-8', 'windows-1251', trim($f[$i]));  
    $line = trim($f[$i]);
    $r = explode("\t", $line);
    $count_col = count($r);
    $tr = '<td>'.strval($i+1).'</td>';
    for($j=0; $j<$count_col-1; $j++){
      if($j==$count_col-3) {
        $url = 'http://'.$_SERVER['HTTP_HOST'].$r[$j];
        $str = '<a href="'.$url.'">Скачать</a>';
      }else 
        $str = $r[$j];
        $tr .= '<td>'.$str.'</td>';
      }
    $table .= '<tr>'.$tr.'</tr>';
  } 
  $table .= '<table>';
  echo $table; 
  
  echo ' </body>';
  echo '</html>';  
?>

Или еще один вариант:

<?php
  ## MyTestXPro http://mytestx.pro
  ## скрипт показа результатов 2

  echo '<!DOCTYPE HTML>';
  echo '<html>';
  echo ' <head>';
  echo '  <title>Результаты</title>';
  echo '  <meta charset="UTF-8">';
  echo '  <link rel="stylesheet" type="text/css" href="style.css">';
  echo '  <script src="sorttable.js" type="text/javascript"></script>';
  echo ' </head>';
  echo ' <body>';
  
  # данные в таблице 
  $title = 'Today,IP,UserName,UserGroup,Mark,Result,MaskOfResult,FileName,FileSize';
  $a_title = explode(",", $title);    
  
  # заголовок для csv  
  $csv_title = 'Uid,Date,Time,UserName,UserGroup,Mark,Result,ScoreMax,ScoreMax2,Score,CountTask,CountAskTask,CountCheckTask,CountCorrectTask,CountPartiallyTask,CountErrorTask,CountMissTask,CountUsePrompt,CountUsePrompt2,CorrectByCount,TimeBegin,TimeEnd,Duration,TestTitle,TestFileName,CRCFile,TetUId,ModeEnd,ComputerNetName,IP,ComputerUserName,Note';
  $a_csv_title = explode(",", $csv_title);    
  
  
  # папка с результатами
  $file_dir = $_SERVER['DOCUMENT_ROOT'].'/ab5ff96b-afc0-48e6-8157-39ee02df3ce9/results/';
  # текстовый файл с результатами (в папке с результатами)
  $file_name = $file_dir . 'data.txt';
  
  # открываем файл и формируем таблицу  
  $f = file($file_name);
  $table = '<table>';
  $table .= '<thead><tr><th>№</th><th>Дата</th><th>IP/комп</th><th>Имя/Группа</th><th>Оценка</th><th>Результат</th><th>Файл результата</th><th>Тест</th><tr></thead><tbody>';


  $count_res = count($f);
  for($i=0; $i<$count_res; $i++){
    //$line = iconv('utf-8', 'windows-1251', trim($f[$i]));  
    $line = trim($f[$i]);
    $r = explode("\t", $line);
    $count_col = count($r);
    $csv_data = $r[$count_col-1];
    array_splice($r, $count_col-1);

    $a1 = array_combine($a_title, $r);
    $a_csv = str_getcsv($csv_data, ';');    
    $a2 = array_combine($a_csv_title, $a_csv);

    $a1['Today'] = str_replace(' ', '<br>', $a1['Today']) . '<br> ~' . $a2['Duration'] . '~';
    $a1['UserName'] .= '<br>' . $a1['UserGroup'];       
    $a1['IP'] .= '<br>' . $a2['ComputerNetName'] . '<br>' . $a2['ComputerUserName'];
    $a1['Result'] .= '%' . '<br>' . $a2['Score'] . ' из '. $a2['ScoreMax'] . '<br>' . $a1['MaskOfResult']; 
    
    $url2 = 'http://'.$_SERVER['HTTP_HOST'] . $a1['FileName'];
    $a1['FileName'] = '<a href="'.$url2.'">Скачать</a>';
    $a1['FileName'] .= '<br>' . $a1['FileSize'] . ' Байт' . '<br>' . $a2['ModeEnd'];
    
    $a1['Test'] = $a2['TestFileName'] . '<br>' . $a2['TestTitle'] . '<br>' .  $a2['CRCFile'];
    
    unset($a1['UserGroup']);
    unset($a1['MaskOfResult']);
    unset($a1['FileSize']);    

    $tr = '<td>'.strval($i+1).'</td>';
    foreach ($a1 as $key => $value) {
      $tr .= '<td>'.$value.'</td>';
    }    
    $table .= '<tr>'.$tr.'</tr>';
  } 
  $table .= '</tbody></table>';
  echo $table; 
  
  echo ' </body>';
  echo '</html>';  
?>


Вот пример его работы:

Post show2.png


Save 48.png

Образец файлов можно скачать по ссылке https://yadi.sk/d/L6BSvAmdgfNqlA В архиве папка. Поместите эту папку в корень вашего сайта. Возможно потребуется для вложенной папки для результатов задать права на запись.

Алгоритм действий: