<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>php - Qlik Sense - Обучение, учебник, онлайн курс</title>
	<atom:link href="https://qliksense.ivan-shamaev.ru/tag/php/feed/" rel="self" type="application/rss+xml" />
	<link>https://qliksense.ivan-shamaev.ru/tag/php/</link>
	<description>Qlik Sense на русском языке. Пошаговые уроки для изучения Клик Сенс</description>
	<lastBuildDate>Tue, 10 Dec 2019 11:59:16 +0000</lastBuildDate>
	<language>ru-RU</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.8.1</generator>

<image>
	<url>https://qliksense.ivan-shamaev.ru/wp-content/uploads/2018/07/QlikSense_ICON2-150x150.png</url>
	<title>php - Qlik Sense - Обучение, учебник, онлайн курс</title>
	<link>https://qliksense.ivan-shamaev.ru/tag/php/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Загрузка данных из Mango Office в Qlik Sense с помощью PHP</title>
		<link>https://qliksense.ivan-shamaev.ru/loading-data-from-mango-office-to-qlik-sense-using-php/</link>
					<comments>https://qliksense.ivan-shamaev.ru/loading-data-from-mango-office-to-qlik-sense-using-php/#respond</comments>
		
		<dc:creator><![CDATA[qliksense-expert]]></dc:creator>
		<pubDate>Thu, 21 Nov 2019 06:20:31 +0000</pubDate>
				<category><![CDATA[Уровень 2]]></category>
		<category><![CDATA[Mango Office]]></category>
		<category><![CDATA[Mango Office API]]></category>
		<category><![CDATA[Mango Office Qlik Sense]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[php & qlik sense]]></category>
		<category><![CDATA[PHP IIS]]></category>
		<category><![CDATA[Выгрузка данных из API]]></category>
		<category><![CDATA[Выгрузка данных с помощью PHP]]></category>
		<category><![CDATA[Загрузка данных по телефонии в Qlik]]></category>
		<guid isPermaLink="false">https://qliksense.ivan-shamaev.ru/?p=2144</guid>

					<description><![CDATA[<p>В этой статье будет приведен пример загрузки данных из Mango Office в Qlik Sense с помощью PHP. Это не идеальный скрипт, сделана рабочая связка, которая ежедневно выгружает данные в QVD для сквозной аналитики по интернет-проектам. Выгрузка данных / получение данных из Манго Телеком API Интеграция Mango Office и аналитической системы<a class="moretag" href="https://qliksense.ivan-shamaev.ru/loading-data-from-mango-office-to-qlik-sense-using-php/"> Читать дальше&#8230;</a></p>
<p>Сообщение <a href="https://qliksense.ivan-shamaev.ru/loading-data-from-mango-office-to-qlik-sense-using-php/">Загрузка данных из Mango Office в Qlik Sense с помощью PHP</a> появились сначала на <a href="https://qliksense.ivan-shamaev.ru">Qlik Sense - Обучение, учебник, онлайн курс</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>В этой статье будет приведен пример загрузки данных из <strong>Mango Office</strong> в <strong>Qlik Sense</strong> с помощью <strong>PHP</strong>. Это не идеальный скрипт, сделана рабочая связка, которая ежедневно выгружает данные в QVD для сквозной аналитики по интернет-проектам.</p>
<h2>Выгрузка данных / получение данных из Манго Телеком API</h2>
<p>Интеграция <strong>Mango Office</strong> и аналитической системы <strong>Qlik Sense</strong> для получения статистики звонков. Схема настройки ETL процесса может быть изменена.</p>
<p><strong>_settings.php</strong></p>
<pre class="EnlighterJSRAW" data-enlighter-language="null">&lt;?php
  //Берется из личного кабинета Mango Office
  $api_key 		= '7wlk24q8754654654654654654564woat';
  $api_salt 		= 'bm4309d685198198198yHKJh87ggudrde';
?&gt;</pre>
<p><strong>_functions.php</strong></p>
<pre class="EnlighterJSRAW" data-enlighter-language="php">&lt;?php
//=====================================================================================
// ОПИСАНИЕ: 		Файл с функциями для php скриптов обработки данных
// Версия: 			v1
// Дата создания: 	2019.04.16
// Автор: 			Шамаев Иван
//=====================================================================================


function send_request_to_api($url,$data,$api_key,$api_salt){
  //=====================================================================================
  // Дата:		2019.04.16
  // Тек.Версия:	v1
  // Автор:		Иван Шамаев
  // Описание: 	
  // Изменения:	№1 &lt;Дата&gt; &lt;Автор&gt; - &lt;Что изменено&gt;
  //=====================================================================================

  $json = json_encode($data);

  $sign = hash('sha256', $api_key . $json . $api_salt);

  $postdata = array(
   'vpbx_api_key' =&gt; $api_key,
   'sign' =&gt; $sign,
   'json' =&gt; $json
  );

  $post = http_build_query($postdata);

  $opts = array(
   'http' =&gt; array(
   'method' =&gt; 'POST',
   'header' =&gt; 'Content-type: application/x-www-form-urlencoded',
   'content' =&gt; $post
   )
  );
  $context = stream_context_create($opts);
  $response = file_get_contents($url, false, $context);
                             
  $result = json_decode($response,TRUE);
  $key = $result['key'];
  return $key;
}

function get_result_to_api($url,$key,$api_key,$api_salt){
  //===============================================================================================
  // Дата:		2019.04.16
  // Тек.Версия:	v2
  // Автор:		Иван Шамаев
  // Описание: 	Функция получения результатов расчета по запросу к Mango API
  // Изменения:	№1 2019.04.17 Иван Шамаев - При запросе данных за 1 месяц данные 
  //					Данные формируются какое-то время. Соответственно нужно делать 
  //					1 попытку в 5 секунд по запросу результата расчета. Количество попыток 20
  //===============================================================================================

  $data = array(
   "key" =&gt; $key
  );

  $json = json_encode($data);

  $sign = hash('sha256', $api_key . $json . $api_salt);

  $postdata = array(
   'vpbx_api_key' =&gt; $api_key,
   'sign' =&gt; $sign,
   'json' =&gt; $json
  );

  $post = http_build_query($postdata);

  $opts = array(
    'http' =&gt; array(
      'method' =&gt; 'POST',
      'header' =&gt; 'Content-type: application/x-www-form-urlencoded',
      'content' =&gt; $post
    )
  );
  $context = stream_context_create($opts);

  //=========================================================
  // Получаем данные в цикле, т.к. API работает не мгновенно
  //=========================================================

    //Пустая переменная
    $stats_result = NULL; 
    //Ограничиваем количество попыток 20 - максимум
    $i_try_max = 20;
    $i_try = 1;

    //Пока переменная пуста делаем попытки повторного обращения к серверу
    while (empty($stats_result) and $i_try &lt;= $i_try_max) {
      //Забираем данные в формате CSV с разделителем ; и переносом на новую строку \n
      $stats_result = file_get_contents($url, false, $context);
      $i_try++;
      sleep(5);
    }	

    if($i_try&gt;$i_try_max){
      echo '&lt;span style="color:red;"&gt;ПРЕВЫШЕНО КОЛИЧЕСТВО ПОПЫТОК (&gt;'.$i_try_max.' раз) ПОДКЛЮЧЕНИЙ ДЛЯ ПОЛУЧЕНИЯ РЕЗУЛЬТАТА&lt;/span&gt;';
      exit();
    }

  return $stats_result;
}

function put_csv_to_array($result_data,$header_dates,$header_row){
  //=====================================================================================
  // Дата:		2019.04.16
  // Тек.Версия:	v1
  // Автор:		Иван Шамаев
  // Описание: 	
  // Изменения:	№1 &lt;Дата&gt; &lt;Автор&gt; - &lt;Что изменено&gt;
  //=====================================================================================

  //Парсим строку $result_data
  $result_array = array();
  $temp = array();
  $i_flag = 0;

  //Дробим ответ от сервера на отдельные строки с разделителем \n
  $big_parts = explode("\n", $result_data);


  foreach ($big_parts as $big_part){

    //Дробим каждую CSV-строку по разделителю ";"
    $temp = explode(';', $big_part);
    
    //Пишем данные в результирующий массив
    foreach ($temp as $key_temp=&gt;$value_temp){
      //Если название столбца - дата, то изменяем формат
      if (in_array($header_row[$key_temp], $header_dates)) {
          $header_name = $header_row[$key_temp];
          $header_name = preg_replace('/[^a-zA-Zа-яА-Я0-9 \:]/ui', '',$header_name );
          $result_array[$i_flag][$header_name] = date("Y-m-d H:i:s", $value_temp);
      }
      else {
        $result_array[$i_flag][$header_row[$key_temp]] = $value_temp;
      }
    }

    $i_flag++;

  }
  //Возвращаем массив
  return $result_array;
}

function format_timestamp($date,$start_end_property){
  //=====================================================================================
  // Дата:		2019.04.16
  // Тек.Версия:	v1
  // Автор:		Иван Шамаев
  // Описание: 	
  // Изменения:	№1 &lt;Дата&gt; &lt;Автор&gt; - &lt;Что изменено&gt;
  //=====================================================================================
  if($start_end_property==="start") {
    $calc_date = new DateTime($date.' 00:00:00', new DateTimeZone('Europe/Moscow'));
    $return_date = $calc_date-&gt;getTimestamp();
  }
  elseif($start_end_property==="end") {
    $calc_date = new DateTime($date.' 23:59:59', new DateTimeZone('Europe/Moscow'));
    $return_date =  $calc_date-&gt;getTimestamp();
  }
  //Возвращаем массив
  return $return_date;
}


function set_dates_from_url(){
  //=====================================================================================
  // Дата:		2019.04.17
  // Тек.Версия:	v1
  // Автор:		Иван Шамаев
  // Описание: 	Функция для установки переменных $start_date, $end_date из URL запроса
  // Изменения:	№1 &lt;Дата&gt; &lt;Автор&gt; - &lt;Что изменено&gt;
  //=====================================================================================

  //Задаем глобальные переменные
  global $start_date, $end_date;

  //Получаем переменные из URL запроса
  if (isset($_GET['start_date']) and isset($_GET['end_date'])) {
    $start_date = htmlspecialchars($_GET["start_date"]);
    $end_date = htmlspecialchars($_GET["end_date"]);
  }
  else {
    err();
  }
}

?&gt; </pre>
<p><strong>_print_csv.php</strong></p>
<pre class="EnlighterJSRAW" data-enlighter-language="php">&lt;?php
        //-- 2019.04.12 Закомментировал динамические имена, т.к. при изменениях может ломаться Qlik
  //Получаем название файла php
  //$path_parts = $_SERVER['PHP_SELF'];
  //Вычленяем название php
  //$phpScriptName = str_replace('.php','',substr($path_parts, strrpos($path_parts, '/') + 1));

  //-- Единое название файлов csv для всех
    $phpScriptName = 'DataSet';

  // параметр вывода, сделаем так, чтобы файл загружался, а не отображался
  header('Content-Type:text/csv;charset=utf-8');
  header('Content-Disposition: attachment; filename='.$phpScriptName.'.csv');
 
  // создаем указатель файла, подключенный к выходному потоку
  $output = fopen('php://output', 'w');
 
  // Первая строк необходима, чтобы Excel понял, что формат CSV на UTF-8 кодировке
  //fwrite($output,b"\xEF\xBB\xBF" ) ;
  
  // Название колонок (заголовки)
  fputcsv($output, array_keys($result_array[0]), ";");
        
  // Перебираем строки и печатаем в файл csv
  foreach($result_array as $array2){
        	fputcsv($output, $array2, ";");
  }

?&gt; </pre>
<p><strong>get_call_statistics.php</strong></p>
<pre class="EnlighterJSRAW" data-enlighter-language="php">&lt;?php 
//=============================================================================================================================
// ОПИСАНИЕ: 		Файл с функциями для php скриптов обработки данных. Файл полностью построен на функциях, но как выяснилось
//					для API Манго офис это не очень подходящий вариант, т.к. все очень разнообразно для каждой функции
// Версия: 			v1
// Дата создания: 	2019.04.17
// Автор: 			Шамаев Иван
// Пример запроса:	http://your-domain-iis/mango/json/v2/get_call_statistics.php?start_date=2019-03-01&amp;end_date=2019-03-31
//=============================================================================================================================

// ======= БУФЕР =========
//Включение буферизации вывода
ob_start();

//========================================================
// НАСТРОЙКИ: ПОЛУЧАЕМ ОБЩИЕ ПЕРЕМЕННЫЕ
//========================================================
  include '_settings.php';
  $url_request 	= 'https://app.mango-office.ru/vpbx/stats/request';
  $url_result 	= 'https://app.mango-office.ru/vpbx/stats/result';
//========================================================
// ФУНКЦИИ
//========================================================
  include '_functions.php';

  //Создаем переменные даты начала и даты окончания из URL: $start_date, $end_date
  set_dates_from_url();

  //Начало месяца
  $start_date_timestamp = format_timestamp($start_date,"start");
  
  //Конец месяца
  $end_date_timestamp = format_timestamp($end_date,"end");


//========================================================
// НАСТРОЙКА ПАРАМЕТРОВ ЗАПРОСА (можно править)
//========================================================
  //Перечень полей, которые будет выводить API Mango Office
  $header_row = [
    'records','start','finish',
    'answer','from_extension','from_number',
    'to_extension','to_number','disconnect_reason',
    'line_number','location'
  ];
  
  //Задаем поля, которые содержат дату (по другому пока не знаю как это дело пометить)
  $header_dates = ['start','finish','answer'];

  $fields_request 	= implode(",",$header_row);
  $column_name_csv 	= implode(";",$header_row);

  //Параметры запроса
  $request_data = array(
    "date_from" =&gt; $start_date_timestamp,
    "date_to" =&gt; $end_date_timestamp,
    "fields" =&gt; $fields_request,
    "from" =&gt; array(
      "extension"=&gt;"",
      "number" =&gt; ""
    ),
    "to"=&gt; array(
      "extension"=&gt;"",
      "number"=&gt;""
    )
  );

//========================================================
// ФОРМИРОВАНИЕ ЗАПРОСА: POST /stats/request
//========================================================

  //Отправляем запрос и получаем ключ для дальнейшего получения ответа 
  $key = send_request_to_api($url_request,$request_data,$api_key,$api_salt);

//=====================================================
// ЗАБИРАЕМ ДАННЫЕ: POST /stats/result
//=====================================================

  //Забираем данные в формате CSV с разделителем ; и переносом на новую строку \n
  $result_data = get_result_to_api($url_result,$key,$api_key,$api_salt);

//=====================================================
// ПАРСИМ ДАННЫЕ: из-за дат приходится парсить строку
// 				  и в PHP делать перекодировку
// 				  из timestamp в ДатаВремя
//=====================================================

  //Парсим строку
  $result_array = array();
  $result_array = put_csv_to_array($result_data,$header_dates,$header_row);

// ======= БУФЕР =========
//Очищаем все выходные буферы (удаляем весь мусор из страницы перед печатью CSV)
ob_end_clean();

//========================================================
// ПЕЧАТАЕМ МАССИВ ДАННЫХ В CSV
//========================================================
  include '_print_csv.php';

// ======= БУФЕР =========
//Возвращаем содержимое буфера вывода (наш сформированный csv)
ob_get_contents();

?&gt;</pre>
<p><strong>Запрос в Qlik Sense:</strong></p>
<pre class="EnlighterJSRAW" data-enlighter-language="null">Let varMinDate   = Num(MakeDate(2018,2,1));
Let varMaxDate   = Num(Today());
      
TempCalendar:  
LOAD TempDate 				As StartDate,
   MonthEnd(TempDate)		As EndDate
Where TempDate=MonthStart(TempDate);
LOAD 
     Date($(varMinDate) + IterNo() - 1) as TempDate
AutoGenerate 1
While $(varMinDate) + IterNo() -1 &lt;= $(varMaxDate)
;


For j=1 to NoOfRows('TempCalendar')

    LET vStartDate 	= Peek('StartDate',$(j)-1,'TempCalendar');
    LET vEndDate 	= Peek('EndDate',$(j)-1,'TempCalendar');

    [get_call_statistics]:
    LOAD records, 
         start, 
         finish, 
         answer, 
         from_extension, 
         from_number, 
         to_extension, 
         to_number, 
         disconnect_reason, 
         line_number, 
         location
    FROM [lib://test]
    (URL is [http://your-domain-iis/mango/json/v2/get_call_statistics.php?start_date=$(vStartDate)&amp;end_date=$(vEndDate)],txt, utf8, embedded labels, delimiter is ';', msq)
    Where not IsNull(records) and records&lt;&gt;''
    ;

NEXT j

DROP Table TempCalendar;

Store get_call_statistics into [lib://QVDData/get_call_statistics.qvd] (qvd);</pre>
<p>Сообщение <a href="https://qliksense.ivan-shamaev.ru/loading-data-from-mango-office-to-qlik-sense-using-php/">Загрузка данных из Mango Office в Qlik Sense с помощью PHP</a> появились сначала на <a href="https://qliksense.ivan-shamaev.ru">Qlik Sense - Обучение, учебник, онлайн курс</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://qliksense.ivan-shamaev.ru/loading-data-from-mango-office-to-qlik-sense-using-php/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>PHP: Запись данных из скрипта Qlik Sense в MySQL</title>
		<link>https://qliksense.ivan-shamaev.ru/php-writing-data-from-a-qlik-sense-script-to-mysql/</link>
					<comments>https://qliksense.ivan-shamaev.ru/php-writing-data-from-a-qlik-sense-script-to-mysql/#respond</comments>
		
		<dc:creator><![CDATA[qliksense-expert]]></dc:creator>
		<pubDate>Wed, 22 May 2019 11:57:41 +0000</pubDate>
				<category><![CDATA[Qlik Sense Блог]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[php & qlik sense]]></category>
		<category><![CDATA[qlik sense]]></category>
		<category><![CDATA[qliksense]]></category>
		<category><![CDATA[кликсенс]]></category>
		<guid isPermaLink="false">https://qliksense.ivan-shamaev.ru/?p=1040</guid>

					<description><![CDATA[<p>Привет! В этой статье я приведу пример PHP скрипта, который можно использовать для записи данных (каких то параметров) в базу данных MySQL. Для того, чтобы вызвать php-скрипт, его необходимо разместить на сайте или IIS сервере. Вызов из скрипта Qlik Sense осуществляется следующим образом: Замечание: в URL адресе не должно быть<a class="moretag" href="https://qliksense.ivan-shamaev.ru/php-writing-data-from-a-qlik-sense-script-to-mysql/"> Читать дальше&#8230;</a></p>
<p>Сообщение <a href="https://qliksense.ivan-shamaev.ru/php-writing-data-from-a-qlik-sense-script-to-mysql/">PHP: Запись данных из скрипта Qlik Sense в MySQL</a> появились сначала на <a href="https://qliksense.ivan-shamaev.ru">Qlik Sense - Обучение, учебник, онлайн курс</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Привет!</p>



<p>В этой статье я приведу пример PHP скрипта, который можно использовать для записи данных (каких то параметров) в базу данных MySQL.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="php" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">&lt;?php

	//Получаем переменные из URL запроса
	if (isset($_GET['field1']) and isset($_GET['field2']) and isset($_GET['field3'])) {
		$field1 	= htmlspecialchars($_GET["field1"]);
		$field2 	= htmlspecialchars($_GET["field2"]);
		$field3 	= htmlspecialchars($_GET["field3"]);
	}
	else {
		err();
	}                                             

	// Задаем коннекшн
	mysql_connect('ip_server_adress', 'login', 'password');
	//Устанавливаем несколько кодировок, иногда чего-то нехватает, лучше перестраховаться множеством установок
	mysql_query("set collation_connection = 'utf8_general_ci'");
	mysql_query("set character_set_client='utf8'");
	mysql_query("set character_set_results='utf8'");
	mysql_query("set character_set_system='utf8'");
	mysql_query('SET names=utf8');
	mysql_select_db('database_name');

	header('Content-Type: text/csv; charset=utf-8');
	header('Content-Disposition: attachment; filename=result.txt');
	$result = mysql_query(
						"INSERT INTO `mysql_table_name` (`field1`, `field2`, `field3`) 
						VALUES ('".$field1."', '".$field2."', '".$field3."')"
					);
	
	// создаем указатель файла, подключенный к выходному потоку
	$output = fopen('php://output', 'w');

	fwrite($output, "result\r\n");

	if($result){

		fputs($output, "ok");
	}
	else {
		fputs($output, "not ok");
	};

?></pre>



<p>Для того, чтобы вызвать php-скрипт, его необходимо разместить на сайте или IIS сервере. Вызов из скрипта Qlik Sense осуществляется следующим образом:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">MySQL_Temp_Insert_Information:
LOAD result As MySQL_Temp_Insert_Information
FROM
[http://iis-server-website.ru/mysql/insert_info.php?field1=$(vField1)&amp;field2=$(vField2)&amp;field3=$(vField3)]
(txt, codepage is 1251, embedded labels, delimiter is '\t', msq);

DROP TABLE MySQL_Temp_Insert_Information;</pre>



<p><strong>Замечание:</strong> в URL адресе не должно быть пробелов, иначе QlikView или Qlik Sense выдаст ошибку. Не знаю почему такое происходит.</p>
<p>Сообщение <a href="https://qliksense.ivan-shamaev.ru/php-writing-data-from-a-qlik-sense-script-to-mysql/">PHP: Запись данных из скрипта Qlik Sense в MySQL</a> появились сначала на <a href="https://qliksense.ivan-shamaev.ru">Qlik Sense - Обучение, учебник, онлайн курс</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://qliksense.ivan-shamaev.ru/php-writing-data-from-a-qlik-sense-script-to-mysql/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
