diff options
Diffstat (limited to 'admin/survey/modules/mod_advanced_paradata')
7 files changed, 2018 insertions, 0 deletions
diff --git a/admin/survey/modules/mod_advanced_paradata/class.SurveyAdvancedParadata.php b/admin/survey/modules/mod_advanced_paradata/class.SurveyAdvancedParadata.php new file mode 100644 index 0000000..5368909 --- /dev/null +++ b/admin/survey/modules/mod_advanced_paradata/class.SurveyAdvancedParadata.php @@ -0,0 +1,145 @@ +<?php
+
+/*
+ * Modul za pregledovanje in urejanje nastavitev naprednih parapodatkov
+ *
+ */
+
+
+class SurveyAdvancedParadata {
+
+ var $anketa; # id ankete
+
+
+ function __construct($anketa){
+
+ // Ce imamo anketo
+ if ((int)$anketa > 0){
+ $this->anketa = $anketa;
+ }
+ }
+
+
+ public function displaySettings(){
+ global $lang;
+
+ $settings = $this->getSettings();
+
+ echo '<fieldset><legend>'.$lang['settings'].'</legend>';
+
+ // Belezenje post time-a
+ echo '<span class="nastavitveSpan1" >'.$lang['srv_advanced_paradata_collect_post_time'].':</span>';
+ echo '<label for="collect_post_time_0"><input type="radio" name="collect_post_time" id="collect_post_time_0" value="0" '.(($settings['collect_post_time'] == 0) ? ' checked="checked" ' : '').' />'.$lang['no1'].'</label>';
+ echo '<label for="collect_post_time_1"><input type="radio" name="collect_post_time" id="collect_post_time_1" value="1" '.(($settings['collect_post_time'] == 1) ? ' checked="checked" ' : '').' />'.$lang['yes'].'</label>';
+
+ echo '<br />';
+
+ echo '</fieldset>';
+
+
+ // Gumb shrani
+ echo '<br class="clr" />';
+ echo '<span class="floatLeft spaceRight"><div class="buttonwrapper"><a class="ovalbutton ovalbutton_orange btn_savesettings" href="#" onclick="advanced_paradata_save_settings(); return false;"><span>';
+ echo $lang['edit1337'] . '</span></a></div></span>';
+ echo '<div class="clr"></div>';
+ echo '<div id="success_save"></div>';
+
+ echo '<br />';
+
+
+ // Prikazemo parapodatke
+ $this->displayParadata();
+ }
+
+ // Pridobimo trenutne nastavitve za anketo
+ public function getSettings(){
+
+ $settings = array();
+
+ // Default vrednosti
+ $settings['collect_post_time'] = '1';
+
+ $sql = sisplet_query("SELECT * FROM srv_advanced_paradata_settings WHERE ank_id='".$this->anketa."'");
+ if(mysqli_num_rows($sql) > 0){
+ $row = mysqli_fetch_array($sql);
+
+ $settings['collect_post_time'] = $row['collect_post_time'];
+ }
+
+ return $settings;
+ }
+
+
+ private function displayParadata(){
+ global $lang;
+ global $site_url;
+
+ $sape = new SurveyAdvancedParadataExport($this->anketa);
+
+ echo '<fieldset><legend>'.$lang['srv_results'].'</legend>';
+
+ // Opcija za brisanje loga
+ echo '<p>';
+ echo ' <a href="#" onClick="advanced_paradata_data_delete(); return false;">Delete all data</a>';
+ echo '</p>';
+
+ // Po sejah po straneh
+ echo '<span class="bold">Seja na strani</span>';
+ $href_csv = 'izvoz.php?m=advanced_paradata_csv&table=srv_advanced_paradata_page&anketa=' . $this->anketa;
+ echo ' <span class="spaceLeft">(<a href="'.$href_csv.'">CSV izvoz</a>)</span>';
+ $sape->displayPageTable();
+
+ // Po vprasanjih
+ echo '<span class="bold">Vprašanja</span>';
+ $href_csv = 'izvoz.php?m=advanced_paradata_csv&table=srv_advanced_paradata_question&anketa=' . $this->anketa;
+ echo ' <span class="spaceLeft">(<a href="'.$href_csv.'">CSV izvoz</a>)</span>';
+ $sape->displayQuestionTable();
+
+ // Po vrednostih
+ echo '<span class="bold">Vrednosti</span>';
+ $href_csv = 'izvoz.php?m=advanced_paradata_csv&table=srv_advanced_paradata_vrednost&anketa=' . $this->anketa;
+ echo ' <span class="spaceLeft">(<a href="'.$href_csv.'">CSV izvoz</a>)</span>';
+ $sape->displayVrednostTable();
+
+ // Ostalo
+ echo '<span class="bold">Ostalo</span>';
+ $href_csv = 'izvoz.php?m=advanced_paradata_csv&table=srv_advanced_paradata_other&anketa=' . $this->anketa;
+ echo ' <span class="spaceLeft">(<a href="'.$href_csv.'">CSV izvoz</a>)</span>';
+ $sape->displayOtherTable();
+
+ // Premiki miske
+ echo '<span class="bold">Premiki miške</span>';
+ $href_csv = 'izvoz.php?m=advanced_paradata_csv&table=srv_advanced_paradata_movement&anketa=' . $this->anketa;
+ echo ' <span class="spaceLeft">(<a href="'.$href_csv.'">CSV izvoz</a>)</span>';
+ $sape->displayMovementTable();
+
+ // Alerti
+ echo '<span class="bold">Alerti</span>';
+ $href_csv = 'izvoz.php?m=advanced_paradata_csv&table=srv_advanced_paradata_alert&anketa=' . $this->anketa;
+ echo ' <span class="spaceLeft">(<a href="'.$href_csv.'">CSV izvoz</a>)</span>';
+ $sape->displayAlertTable();
+
+ echo '</fieldset>';
+ }
+
+
+ public function ajax() {
+
+ // Brisanje logov
+ if (isset($_GET['a']) && $_GET['a'] == 'logDataDelete') {
+
+ $sql = sisplet_query("DELETE FROM srv_advanced_paradata_page WHERE ank_id='".$this->anketa."'");
+ }
+
+ // Shranjevanje nastavitev
+ if(isset($_GET['a']) && $_GET['a'] == 'save_settings'){
+
+ $collect_post_time = isset($_POST['collect_post_time']) ? $_POST['collect_post_time'] : '1';
+
+ $sql = sisplet_query("INSERT INTO srv_advanced_paradata_settings
+ (ank_id, collect_post_time) VALUES ('".$this->anketa."', '".$collect_post_time."')
+ ON DUPLICATE KEY UPDATE collect_post_time='".$collect_post_time."'");
+ if (!$sql) echo mysqli_error($GLOBALS['connect_db']);
+ }
+ }
+}
\ No newline at end of file diff --git a/admin/survey/modules/mod_advanced_paradata/class.SurveyAdvancedParadataExport.php b/admin/survey/modules/mod_advanced_paradata/class.SurveyAdvancedParadataExport.php new file mode 100644 index 0000000..7055b07 --- /dev/null +++ b/admin/survey/modules/mod_advanced_paradata/class.SurveyAdvancedParadataExport.php @@ -0,0 +1,559 @@ +<?php
+
+/*
+ * Modul za pripravo izvoza naprednih parapodatkov
+ *
+ */
+
+
+class SurveyAdvancedParadataExport {
+
+ var $anketa; // ID ankete
+
+ var $limit = 100; // Max vrstic pri izpisu
+
+
+ function __construct($anketa){
+ global $site_url;
+
+ // Ce imamo anketo
+ if ((int)$anketa > 0){
+ $this->anketa = $anketa;
+ }
+ }
+
+
+ // Izvozimo ustrezno tabelo v csv
+ public function exportTable($table_name='srv_advanced_paradata_page'){
+ global $site_path;
+
+ ini_set('memory_limit', '4048M');
+
+ // Dobimo naslove stolpcev
+ $header = $this->getHeader($table_name);
+
+
+ // Pripravimo datoteko za izvoz
+ $file = $site_path.'admin/survey/modules/mod_advanced_paradata/temp/'.$table_name.'_'.$this->anketa.'.csv';
+ $fd = fopen($file, "w");
+
+ $convertTypes = array('charSet' => 'windows-1250',
+ 'delimit' => ',',
+ 'newLine' => "\n",
+ 'BOMchar' => "\xEF\xBB\xBF");
+ # dodamo boomchar za utf-8
+ fwrite($fd, $convertTypes['BOMchar']);
+
+ // Zapisemo header row
+ $header_line = '';
+ foreach($header as $col){
+ $header_line .= $col.',';
+ }
+ $header_line = substr($header_line, 0, -1);
+ fwrite($fd, $header_line."\r\n");
+
+ // Zapisemo vsako vrstico posebej
+ // Dobimo vrstice s podatki
+ switch($table_name){
+
+ case 'srv_advanced_paradata_question':
+ $data = $this->writeQuestionParadata($fd, $header);
+ break;
+
+ case 'srv_advanced_paradata_vrednost':
+ $data = $this->writeVrednostParadata($fd, $header);
+ break;
+
+ case 'srv_advanced_paradata_other':
+ $data = $this->writeOtherParadata($fd, $header);
+ break;
+
+ case 'srv_advanced_paradata_movement':
+ $data = $this->writeMovementParadata($fd, $header);
+ break;
+
+ case 'srv_advanced_paradata_alert':
+ $data = $this->writeAlertParadata($fd, $header);
+ break;
+
+ default:
+ $data = $this->writePageParadata($fd, $header);
+ break;
+ }
+
+ fclose($fd);
+
+
+ // Pripravimo file za download
+ if(file_exists($file)){
+
+ header('Content-Description: File Transfer');
+ //header('Content-Type: application/octet-stream');
+ header('Content-Disposition: attachment; filename='.basename(''.$table_name.'_'.$this->anketa.'.csv'.''));
+
+ header("Content-type: text/x-csv; charset=utf-8");
+ //header("Content-type: text/csv");
+
+ header('Content-Transfer-Encoding: binary');
+ header('Expires: 0');
+ header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
+ header('Pragma: public');
+ header('Content-Length: ' . filesize($file));
+
+ ob_clean();
+ flush();
+
+ readfile($file);
+ }
+
+ // Na koncu pobrisemo zacasne datoteke
+ if (file_exists($file)) {
+ unlink($file);
+ }
+
+ // Ugasnemo skripto:)
+ die();
+ }
+
+
+ // Izpisemo tabelo parapodatkov vezanih na strani
+ public function displayPageTable(){
+ global $lang;
+
+ $data = $this->getPageParadata();
+
+ echo '<table class="advanced_paradata_table page_paradata styled_table">';
+
+ echo '<tr>';
+ echo '<th>ID</th>';
+ echo '<th>User ID</th>';
+ echo '<th>Page ID</th>';
+ echo '<th>Recnum</th>';
+ echo '<th>Load time</th>';
+ echo '<th>Post time</th>';
+ echo '<th>User Agent</th>';
+ echo '<th>Device pixel ratio</th>';
+ echo '<th>width x height</th>';
+ echo '<th>availWidth x availHeight</th>';
+ echo '<th>jQuery windowWidth x windowHeight</th>';
+ echo '<th>jQuery documentWidth x documentHeight</th>';
+ echo '<th>Language</th>';
+ echo '</tr>';
+
+ foreach($data as $row){
+
+ echo '<tr>';
+
+ echo '<td>'.$row['id'].'</td>';
+ echo '<td>'.$row['usr_id'].'</td>';
+ echo '<td>'.$row['gru_id'].'</td>';
+ echo '<td>'.$row['recnum'].'</td>';
+ echo '<td>'.$row['load_time'].'</td>';
+ echo '<td>'.$row['post_time'].'</td>';
+ echo '<td>'.$row['user_agent'].'</td>';
+ echo '<td>'.$row['devicePixelRatio'].'</td>';
+ echo '<td>'.$row['width'].'px X '.$row['height'].'px</td>';
+ echo '<td>'.$row['availWidth'].'px X '.$row['availHeight'].'px</td>';
+ echo '<td>'.$row['jquery_windowW'].'px X '.$row['jquery_windowH'].'px</td>';
+ echo '<td>'.$row['jquery_documentW'].'px X '.$row['jquery_documentH'].'px</td>';
+ echo '<td>'.$row['language'].'</td>';
+
+ echo '</tr>';
+ }
+
+ echo '</table>';
+ }
+ // Izpisemo tabelo parapodatkov vezanih na vprasanja
+ public function displayQuestionTable(){
+
+ $data = $this->getQuestionParadata();
+
+ echo '<table class="advanced_paradata_table question_paradata styled_table">';
+
+ echo '<tr>';
+ echo '<th>Page session ID</th>';
+ echo '<th>Question ID</th>';
+ echo '<th>Order</th>';
+ echo '</tr>';
+
+ foreach($data as $row){
+
+ echo '<tr>';
+
+ echo '<td>'.$row['page_id'].'</td>';
+ echo '<td>'.$row['spr_id'].'</td>';
+ echo '<td>'.$row['vre_order'].'</td>';
+
+ echo '</tr>';
+ }
+
+ echo '</table>';
+ }
+
+ // Izpisemo tabelo parapodatkov vezanih na vredosti
+ public function displayVrednostTable(){
+
+ $data = $this->getVrednostParadata();
+
+ echo '<table class="advanced_paradata_table vrednost_paradata styled_table">';
+
+ echo '<tr>';
+ echo '<th>Page session ID</th>';
+ echo '<th>Question ID</th>';
+ echo '<th>Vrednost ID</th>';
+ echo '<th>Time</th>';
+ echo '<th>Event</th>';
+ echo '<th>Value</th>';
+ echo '</tr>';
+
+ foreach($data as $row){
+
+ echo '<tr>';
+
+ echo '<td>'.$row['page_id'].'</td>';
+ echo '<td>'.$row['spr_id'].'</td>';
+ echo '<td>'.$row['vre_id'].'</td>';
+ echo '<td>'.$row['time'].'</td>';
+ echo '<td>'.$row['event'].'</td>';
+ echo '<td>'.$row['value'].'</td>';
+
+ echo '</tr>';
+ }
+
+ echo '</table>';
+ }
+
+ // Izpisemo tabelo ostalih parapodatkov
+ public function displayOtherTable(){
+
+ $data = $this->getOtherParadata();
+
+ echo '<table class="advanced_paradata_table other_paradata styled_table">';
+
+ echo '<tr>';
+ echo '<th>Page session ID</th>';
+ echo '<th>Time</th>';
+ echo '<th>Event</th>';
+ echo '<th>Value</th>';
+ echo '<th>Position</th>';
+ echo '<th>Element type</th>';
+ echo '<th>Element id</th>';
+ echo '<th>Element class</th>';
+ echo '</tr>';
+
+ foreach($data as $row){
+
+ echo '<tr>';
+
+ echo '<td>'.$row['page_id'].'</td>';
+ echo '<td>'.$row['time'].'</td>';
+ echo '<td>'.$row['event'].'</td>';
+ echo '<td>'.$row['value'].'</td>';
+ echo '<td>X: '.$row['pos_x'].', Y: '.$row['pos_y'].'</td>';
+ echo '<td>'.$row['div_type'].'</td>';
+ echo '<td>'.$row['div_id'].'</td>';
+ echo '<td>'.$row['div_class'].'</td>';
+
+ echo '</tr>';
+ }
+
+ echo '</table>';
+ }
+
+ // Izpisemo tabelo premikov miske
+ public function displayMovementTable(){
+
+ $data = $this->getMovementParadata();
+
+ echo '<table class="advanced_paradata_table movement_paradata styled_table">';
+
+ echo '<tr>';
+ echo '<th>Page session ID</th>';
+ echo '<th>Time start</th>';
+ echo '<th>Time end</th>';
+ echo '<th>Position start</th>';
+ echo '<th>Position end</th>';
+ echo '<th>Distance traveled</th>';
+ echo '</tr>';
+
+ foreach($data as $row){
+
+ echo '<tr>';
+
+ echo '<td>'.$row['page_id'].'</td>';
+ echo '<td>'.$row['time_start'].'</td>';
+ echo '<td>'.$row['time_end'].'</td>';
+ echo '<td>X: '.$row['pos_x_start'].', Y: '.$row['pos_y_start'].'</td>';
+ echo '<td>X: '.$row['pos_x_end'].', Y: '.$row['pos_y_end'].'</td>';
+ echo '<td>'.$row['distance'].'</td>';
+
+ echo '</tr>';
+ }
+
+ echo '</table>';
+ }
+
+ // Izpisemo tabelo ostalih parapodatkov
+ public function displayAlertTable(){
+
+ $data = $this->getAlertParadata();
+
+ echo '<table class="advanced_paradata_table alert_paradata styled_table">';
+
+ echo '<tr>';
+ echo '<th>Page session ID</th>';
+ echo '<th>Display time</th>';
+ echo '<th>Close time</th>';
+ echo '<th>Type</th>';
+ echo '<th>Trigger ID</th>';
+ echo '<th>Trigger type</th>';
+ echo '<th>Ignorable</th>';
+ echo '<th>Alert text</th>';
+ echo '<th>User action</th>';
+ echo '</tr>';
+
+ foreach($data as $row){
+
+ echo '<tr>';
+
+ echo '<td>'.$row['page_id'].'</td>';
+ echo '<td>'.$row['time_display'].'</td>';
+ echo '<td>'.$row['time_close'].'</td>';
+ echo '<td>'.$row['type'].'</td>';
+ echo '<td>'.$row['trigger_id'].'</td>';
+ echo '<td>'.$row['trigger_type'].'</td>';
+ echo '<td>'.$row['ignorable'].'</td>';
+ echo '<td>'.$row['text'].'</td>';
+ echo '<td>'.$row['action'].'</td>';
+
+ echo '</tr>';
+ }
+
+ echo '</table>';
+ }
+
+
+ // Pridobimo naslove parapodatkov vezane na strani
+ private function getHeader($table_name='srv_advanced_paradata_page'){
+
+ $header = array();
+
+ $sql = sisplet_query("SHOW columns FROM ".$table_name."");
+ while($row = mysqli_fetch_array($sql)){
+ $header[] = $row['Field'];
+ }
+
+ return $header;
+ }
+
+ // Pridobimo parapodatke vezane na strani
+ private function getPageParadata($all=false){
+
+ $data = array();
+
+ $limit = $all ? '' : ' LIMIT '.$this->limit;
+
+ $sql = sisplet_query("SELECT * FROM srv_advanced_paradata_page
+ WHERE ank_id='".$this->anketa."'
+ ORDER BY id DESC ".$limit."");
+ while($row = mysqli_fetch_array($sql)){
+ $data[] = $row;
+ }
+
+ return $data;
+ }
+
+ // Pridobimo parapodatke vezane na vprasanja
+ private function getQuestionParadata($all=false){
+
+ $data = array();
+
+ $limit = $all ? '' : ' LIMIT '.$this->limit;
+
+ $sql = sisplet_query("SELECT q.* FROM srv_advanced_paradata_question q, srv_advanced_paradata_page p
+ WHERE p.ank_id='".$this->anketa."' AND q.page_id=p.id
+ ORDER BY id DESC ".$limit."");
+ while($row = mysqli_fetch_array($sql)){
+ $data[] = $row;
+ }
+
+ return $data;
+ }
+
+ // Pridobimo parapodatke vezane na vrednosti v vprasanju
+ private function getVrednostParadata($all=false){
+
+ $data = array();
+
+ $limit = $all ? '' : ' LIMIT '.$this->limit;
+
+ $sql = sisplet_query("SELECT v.* FROM srv_advanced_paradata_vrednost v, srv_advanced_paradata_page p
+ WHERE p.ank_id='".$this->anketa."' AND v.page_id=p.id
+ ORDER BY id DESC ".$limit."");
+ while($row = mysqli_fetch_array($sql)){
+ $data[] = $row;
+ }
+
+ return $data;
+ }
+
+ // Pridobimo ostale parapodatke
+ private function getOtherParadata($all=false){
+
+ $data = array();
+
+ $limit = $all ? '' : ' LIMIT '.$this->limit;
+
+ $sql = sisplet_query("SELECT o.* FROM srv_advanced_paradata_other o, srv_advanced_paradata_page p
+ WHERE p.ank_id='".$this->anketa."' AND o.page_id=p.id
+ ORDER BY id DESC ".$limit."");
+ while($row = mysqli_fetch_array($sql)){
+ $data[] = $row;
+ }
+
+ return $data;
+ }
+
+ // Pridobimo parapodatke premikov miske
+ private function getMovementParadata($all=false){
+
+ $data = array();
+
+ $limit = $all ? '' : ' LIMIT '.$this->limit;
+
+ $sql = sisplet_query("SELECT m.* FROM srv_advanced_paradata_movement m, srv_advanced_paradata_page p
+ WHERE p.ank_id='".$this->anketa."' AND m.page_id=p.id
+ ORDER BY id DESC ".$limit."");
+ while($row = mysqli_fetch_array($sql)){
+ $data[] = $row;
+ }
+
+ return $data;
+ }
+
+ // Pridobimo parapodatke alertov
+ private function getAlertParadata($all=false){
+
+ $data = array();
+
+ $limit = $all ? '' : ' LIMIT '.$this->limit;
+
+ $sql = sisplet_query("SELECT a.* FROM srv_advanced_paradata_alert a, srv_advanced_paradata_page p
+ WHERE p.ank_id='".$this->anketa."' AND a.page_id=p.id
+ ORDER BY id DESC ".$limit."");
+ while($row = mysqli_fetch_array($sql)){
+ $data[] = $row;
+ }
+
+ return $data;
+ }
+
+
+ // Zapisemo v datoteko parapodatke vezane na strani
+ private function writePageParadata($fd, $header){
+
+ $sql = sisplet_query("SELECT * FROM srv_advanced_paradata_page
+ WHERE ank_id='".$this->anketa."'
+ ORDER BY id DESC ".$limit."");
+ while($row = mysqli_fetch_array($sql)){
+
+ $data_line = '';
+ foreach($header as $col){
+ $data_line .= '\''.$row[$col].'\',';
+ }
+ $data_line = substr($data_line, 0, -1);
+
+ fwrite($fd, $data_line."\r\n");
+ }
+ }
+
+ // Zapisemo v datoteko parapodatke vezane na vprasanja
+ private function writeQuestionParadata($fd, $header){
+
+ $sql = sisplet_query("SELECT q.* FROM srv_advanced_paradata_question q, srv_advanced_paradata_page p
+ WHERE p.ank_id='".$this->anketa."' AND q.page_id=p.id
+ ORDER BY id DESC ".$limit."");
+ while($row = mysqli_fetch_array($sql)){
+
+ $data_line = '';
+ foreach($header as $col){
+ $data_line .= '\''.$row[$col].'\',';
+ }
+ $data_line = substr($data_line, 0, -1);
+
+ fwrite($fd, $data_line."\r\n");
+ }
+ }
+
+ // Zapisemo v datoteko parapodatke vezane na vrednosti v vprasanju
+ private function writeVrednostParadata($fd, $header){
+
+ $sql = sisplet_query("SELECT v.* FROM srv_advanced_paradata_vrednost v, srv_advanced_paradata_page p
+ WHERE p.ank_id='".$this->anketa."' AND v.page_id=p.id
+ ORDER BY id DESC ".$limit."");
+ while($row = mysqli_fetch_array($sql)){
+
+ $data_line = '';
+ foreach($header as $col){
+ $data_line .= '\''.$row[$col].'\',';
+ }
+ $data_line = substr($data_line, 0, -1);
+
+ fwrite($fd, $data_line."\r\n");
+ }
+ }
+
+ // Zapisemo v datoteko ostale parapodatke
+ private function writeOtherParadata($fd, $header){
+
+ $sql = sisplet_query("SELECT o.* FROM srv_advanced_paradata_other o, srv_advanced_paradata_page p
+ WHERE p.ank_id='".$this->anketa."' AND o.page_id=p.id
+ ORDER BY id DESC ".$limit."");
+ while($row = mysqli_fetch_array($sql)){
+
+ $data_line = '';
+ foreach($header as $col){
+ $data_line .= '\''.$row[$col].'\',';
+ }
+ $data_line = substr($data_line, 0, -1);
+
+ fwrite($fd, $data_line."\r\n");
+ }
+ }
+
+ // Zapisemo v datoteko parapodatke premikov miske
+ private function writeMovementParadata($fd, $header){
+
+ $sql = sisplet_query("SELECT m.* FROM srv_advanced_paradata_movement m, srv_advanced_paradata_page p
+ WHERE p.ank_id='".$this->anketa."' AND m.page_id=p.id
+ ORDER BY id DESC ".$limit."");
+ while($row = mysqli_fetch_array($sql)){
+
+ $data_line = '';
+ foreach($header as $col){
+ $data_line .= '\''.$row[$col].'\',';
+ }
+ $data_line = substr($data_line, 0, -1);
+
+ fwrite($fd, $data_line."\r\n");
+ }
+ }
+
+ // Zapisemo v datoteko parapodatke alertov
+ private function writeAlertParadata($fd, $header){
+
+ $sql = sisplet_query("SELECT a.* FROM srv_advanced_paradata_alert a, srv_advanced_paradata_page p
+ WHERE p.ank_id='".$this->anketa."' AND a.page_id=p.id
+ ORDER BY id DESC ".$limit."");
+ while($row = mysqli_fetch_array($sql)){
+
+ $data_line = '';
+ foreach($header as $col){
+ $data_line .= '\''.$row[$col].'\',';
+ }
+ $data_line = substr($data_line, 0, -1);
+
+ fwrite($fd, $data_line."\r\n");
+ }
+ }
+}
\ No newline at end of file diff --git a/admin/survey/modules/mod_advanced_paradata/class.SurveyAdvancedParadataLog.php b/admin/survey/modules/mod_advanced_paradata/class.SurveyAdvancedParadataLog.php new file mode 100644 index 0000000..267231a --- /dev/null +++ b/admin/survey/modules/mod_advanced_paradata/class.SurveyAdvancedParadataLog.php @@ -0,0 +1,309 @@ +<?php
+
+/*
+ * Modul za beleženje naprednih parapodatkov med izpolnjevanjem ankete
+ *
+ */
+
+class SurveyAdvancedParadataLog {
+
+
+ private static $instance = false;
+
+ private $collectParadata = false;
+
+ private $anketa = 0;
+ private $session_id = 0;
+
+
+ // Privatni construct, ki ga 1x poklice getInstance
+ private function __construct (/*$anketa*/) {
+
+ /*ini_set('display_errors', 1);
+ ini_set('display_startup_errors', 1);
+ error_reporting(E_ALL);*/
+
+ // Ce imamo anketo
+ /*if ((int)$anketa > 0){
+ $this->anketa = $anketa;
+ }*/
+
+ $this->anketa = (int)$_REQUEST['anketa'];
+ //$this->anketa = $anketa_id;
+
+ if($this->anketa > 0){
+ SurveyInfo::getInstance()->SurveyInit($this->anketa);
+ $this->collectParadata = (SurveyInfo::getInstance()->checkSurveyModule('advanced_paradata')) ? true : false;
+ }
+ else
+ throw new Exception('Survey ID not set in class.SurveyAdvancedParadataLog.php !');
+ }
+
+ // Vrne instanco classa - da mamo singleton
+ public static function getInstance () {
+
+ if (!self::$instance)
+ self::$instance = new SurveyAdvancedParadataLog();
+
+ return self::$instance;
+ }
+
+ // Vrne ce zbiramo napredne parapodatke
+ public function paradataEnabled(){
+ return $this->collectParadata;
+ }
+
+ // Vrne ce zbiramo post time
+ public function collectPostTime(){
+
+ $collectPostTime = true;
+
+ $sql = sisplet_query("SELECT collect_post_time FROM srv_advanced_paradata_settings WHERE ank_id='".$this->anketa."'");
+ if(mysqli_num_rows($sql) > 0){
+
+ $row = mysqli_fetch_array($sql);
+
+ if($row['collect_post_time'] == '0')
+ $collectPostTime = false;
+ }
+
+ return $collectPostTime;
+ }
+
+
+ // Ustvarimo polje v bazi za session (vezan na load posamezne strani) in nastavimo session_id za js
+ public function prepareLogging () {
+
+ $user_agent = $_SERVER['HTTP_USER_AGENT'];
+
+ // Vstavimo v bazo novo polje za session na strani
+ $sql = sisplet_query("INSERT INTO srv_advanced_paradata_page (ank_id, load_time, user_agent) VALUES ('".$this->anketa."', NOW(3), '".$user_agent."')");
+
+ if (!$sql){
+ echo mysqli_error($GLOBALS['connect_db']);
+ }
+ else{
+ // Nastavimo session_id
+ $this->session_id = mysqli_insert_id($GLOBALS['connect_db']);
+
+ // Nastavimo session_id se za JS
+ echo '<script> var _session_id = '.$this->session_id.'; </script>';
+ }
+ }
+
+ // Zapiše log v bazo
+ public function logData ($event_type, $event, $data) {
+
+ switch ($event_type) {
+
+ case 'page':
+ $this->logDataPage($event, $data);
+ break;
+
+ case 'question':
+ $this->logDataQuestion($event, $data);
+ break;
+
+ case 'vrednost':
+ $this->logDataVrednost($event, $data);
+ break;
+
+ case 'other':
+ $this->logDataOther($event, $data);
+ break;
+
+ case 'movement':
+ $this->logDataMovement($event, $data);
+ break;
+
+ case 'alert':
+ $this->logDataAlert($event, $data);
+ break;
+ }
+ }
+
+ // Zabelezimo dogodek na nivoju strani
+ private function logDataPage($event, $data){
+
+ $update = '';
+
+ // Nastavimo katere parametre updatamo
+ switch($event){
+ case 'load_page':
+ $update = " gru_id = '".$data['page']."',
+ usr_id = '".$data['usr_id']."',
+ recnum = '".$data['recnum']."',
+ language = '".$data['language']."',
+ load_time = '".$data['timestamp']."',
+ devicePixelRatio = '".$data['data']['devicePixelRatio']."',
+ width = '".$data['data']['width']."',
+ height = '".$data['data']['height']."',
+ availWidth = '".$data['data']['availWidth']."',
+ availHeight = '".$data['data']['availHeight']."',
+ jquery_windowW = '".$data['data']['jquery_windowW']."',
+ jquery_windowH = '".$data['data']['jquery_windowH']."',
+ jquery_documentW = '".$data['data']['jquery_documentW']."',
+ jquery_documentH = '".$data['data']['jquery_documentH']."'";
+ break;
+
+ case 'unload_page':
+ $update = " post_time='".$data['timestamp']."' ";
+ break;
+ }
+
+ $sql = sisplet_query("UPDATE srv_advanced_paradata_page SET ".$update." WHERE id='$this->session_id'");
+ if (!$sql) echo mysqli_error($GLOBALS['connect_db']);
+
+ /*var_dump($data);
+ echo "UPDATE srv_advanced_paradata_page SET ".$update." WHERE id='$this->session_id'";*/
+ }
+
+ // Zabelezimo dogodek na nivoju vprasanja
+ private function logDataQuestion($event, $data){
+
+ // Preverimo, ce gre ya vprasanje v ifu - potem se preveri da se zapise samo 1x
+ $sqlU = sisplet_query("SELECT p.id
+ FROM srv_advanced_paradata_page p, srv_advanced_paradata_question q
+ WHERE p.usr_id='".$data['usr_id']."' AND p.id=q.page_id AND q.spr_id='".$data['data']['spr_id']."'
+ ");
+
+ // Ce se nimamo vnosa za vprasanje in userja zapisemo
+ if(mysqli_num_rows($sqlU) == 0){
+
+ $sql = sisplet_query("INSERT INTO srv_advanced_paradata_question
+ (page_id, spr_id, vre_order)
+ VALUES
+ ('".$this->session_id."', '".$data['data']['spr_id']."', '".$data['data']['vre_order']."')");
+ if (!$sql) echo mysqli_error($GLOBALS['connect_db']);
+ }
+ }
+
+ // Zabelezimo dogodek na nivoju vrednosti vprasanja
+ private function logDataVrednost($event, $data){
+
+ $value = isset($data['data']['value']) ? $data['data']['value'] : '';
+
+ $sql = sisplet_query("INSERT INTO srv_advanced_paradata_vrednost
+ (page_id, spr_id, vre_id, time, event, value)
+ VALUES
+ ('".$this->session_id."', '".$data['data']['spr_id']."', '".$data['data']['vre_id']."', '".$data['timestamp']."', '".$event."', '".$value."')");
+ if (!$sql) echo mysqli_error($GLOBALS['connect_db']);
+ }
+
+ // Zabelezimo ostale dogodke
+ private function logDataOther($event, $data){
+
+ $value = isset($data['data']['value']) ? $data['data']['value'] : '';
+ $pos_x = isset($data['data']['pos_x']) ? $data['data']['pos_x'] : '';
+ $pos_y = isset($data['data']['pos_y']) ? $data['data']['pos_y'] : '';
+ $div_type = isset($data['data']['div_type']) ? $data['data']['div_type'] : '';
+ $div_id = isset($data['data']['div_id']) ? $data['data']['div_id'] : '';
+ $div_class = isset($data['data']['div_class']) ? $data['data']['div_class'] : '';
+
+ $sql = sisplet_query("INSERT INTO srv_advanced_paradata_other
+ (page_id, time, event, value, pos_x, pos_y, div_type, div_id, div_class)
+ VALUES
+ ('".$this->session_id."', '".$data['timestamp']."', '".$event."', '".$value."', '".$pos_x."', '".$pos_y."', '".$div_type."', '".$div_id."', '".$div_class."')");
+ if (!$sql) echo mysqli_error($GLOBALS['connect_db']);
+ }
+
+ // Zabelezimo premike miske
+ private function logDataMovement($event, $data){
+
+ $time_start_raw = mysqli_real_escape_string($GLOBALS['connect_db'], $data['data']['time_start']);
+ $time_start = date("Y-m-d H:i:s", $time_start_raw/1000).'.'.substr($time_start_raw, -3);
+
+ $time_end_raw = mysqli_real_escape_string($GLOBALS['connect_db'], $data['data']['time_end']);
+ $time_end = date("Y-m-d H:i:s", $time_end_raw/1000).'.'.substr($time_end_raw, -3);
+
+ $pos_x_start = isset($data['data']['pos_x_start']) ? $data['data']['pos_x_start'] : '';
+ $pos_y_start = isset($data['data']['pos_y_start']) ? $data['data']['pos_y_start'] : '';
+ $pos_x_end = isset($data['data']['pos_x_end']) ? $data['data']['pos_x_end'] : '';
+ $pos_y_end = isset($data['data']['pos_y_end']) ? $data['data']['pos_y_end'] : '';
+ $distance = isset($data['data']['distance']) ? $data['data']['distance'] : '';
+
+ $sql = sisplet_query("INSERT INTO srv_advanced_paradata_movement
+ (page_id, time_start, time_end, pos_x_start, pos_y_start, pos_x_end, pos_y_end, distance)
+ VALUES
+ ('".$this->session_id."', '".$time_start."', '".$time_end."', '".$pos_x_start."', '".$pos_y_start."', '".$pos_x_end."', '".$pos_y_end."', '".$distance."')");
+ if (!$sql) echo mysqli_error($GLOBALS['connect_db']);
+ }
+
+ // Zabelezimo alerte
+ private function logDataAlert($event, $data){
+
+ $type = isset($data['data']['type']) ? $data['data']['type'] : '';
+ $trigger_id = isset($data['data']['trigger_id']) ? $data['data']['trigger_id'] : 0;
+ $trigger_type = isset($data['data']['trigger_type']) ? $data['data']['trigger_type'] : '';
+ $ignorable = isset($data['data']['ignorable']) ? $data['data']['ignorable'] : 0;
+ $text = isset($data['data']['text']) ? $data['data']['text'] : '';
+ $action = isset($data['data']['action']) ? $data['data']['action'] : '';
+
+ $timestamp_display_raw = isset($data['data']['time_display']) ? $data['data']['time_display'] : '';
+ $timestamp_display = date("Y-m-d H:i:s", $timestamp_display_raw/1000).'.'.substr($timestamp_display_raw, -3);
+
+ $sql = sisplet_query("INSERT INTO srv_advanced_paradata_alert
+ (page_id, time_display, time_close, type, trigger_id, trigger_type, ignorable, text, action)
+ VALUES
+ ('".$this->session_id."', '".$timestamp_display."', '".$data['timestamp']."', '".$type."', '".$trigger_id."', '".$trigger_type."', '".$ignorable."', '".$text."', '".$action."')");
+ if (!$sql) echo mysqli_error($GLOBALS['connect_db']);
+ }
+
+
+ // Izpise link na javascript datoteko v header htmlja
+ public function linkJavaScript() {
+ global $site_url;
+
+ // Osnovni js za belezenje parapodatkov
+ echo ' <script src="'.$site_url.'admin/survey/modules/mod_advanced_paradata/js/advanced_paradata.js"></script>'."\n";
+
+ // Belezenje post tima (upocasni prehode cez strani)
+ if($this->collectPostTime())
+ echo ' <script src="'.$site_url.'admin/survey/modules/mod_advanced_paradata/js/advanced_paradata_postTime.js"></script>'."\n";
+
+ // JS za belezenje alertov
+ echo ' <script src="'.$site_url.'admin/survey/modules/mod_advanced_paradata/js/sledenjeOpozoril.js"></script>'."\n";
+ }
+
+ // Izpise trenutno grupo v JS
+ public function displayGrupa ($grupa) {
+
+ echo '<script> var srv_meta_grupa_id = '.$grupa.'; </script>';
+ }
+
+
+ // Ajax klici
+ public function ajax() {
+
+ if ($_GET['a'] == 'logData') {
+ $this->ajax_logData();
+ }
+ }
+
+ // Logiranje eventa
+ private function ajax_logData () {
+
+ $this->session_id = $_POST['session_id'];
+
+ $event_type = mysqli_real_escape_string($GLOBALS['connect_db'], $_POST['event_type']);
+ $event = mysqli_real_escape_string($GLOBALS['connect_db'], $_POST['event']);
+
+ $timestamp_raw = mysqli_real_escape_string($GLOBALS['connect_db'], $_POST['timestamp']);
+ $timestamp = date("Y-m-d H:i:s", $timestamp_raw/1000).'.'.substr($timestamp_raw, -3);
+
+ $data_array = array(
+ 'page' => mysqli_real_escape_string($GLOBALS['connect_db'], $_POST['page']),
+ 'usr_id' => mysqli_real_escape_string($GLOBALS['connect_db'], $_POST['usr_id']),
+ 'recnum' => mysqli_real_escape_string($GLOBALS['connect_db'], $_POST['recnum']),
+ 'language' => mysqli_real_escape_string($GLOBALS['connect_db'], $_POST['language']),
+ 'timestamp' => $timestamp,
+ 'data' => $_POST['data']
+ );
+
+ var_dump($_POST);
+
+ $this->logData($event_type, $event, $data_array);
+ }
+}
+
+?>
\ No newline at end of file diff --git a/admin/survey/modules/mod_advanced_paradata/docs/Specifikacija parapodatkov.xml b/admin/survey/modules/mod_advanced_paradata/docs/Specifikacija parapodatkov.xml new file mode 100644 index 0000000..4481add --- /dev/null +++ b/admin/survey/modules/mod_advanced_paradata/docs/Specifikacija parapodatkov.xml @@ -0,0 +1,165 @@ +<!--
+ - Zaenkrat je specifikacija v XML formatu, ampak to je samo za prikaz,
+ kaj bi radi imeli. O končnem formatu izvoza se bomo še zmenili.
+ - Kjerkoli se beleži čas dogodka (timestamp), naj se kolikor natančno JavaScript omogoča.
+ Če lahko v milisekundah, naj bodo milisekunde. Tako kot je zdaj, ko se beležijo
+ sekunde, je premalo natančno in je težko dogodke razvrstit po času.
+ - Format timestampa naj bo standarden (recimo YYYY-MM-DD hh:mm:ss.sss)
+ - Stvari označene z (?) niso tako bistvene ali pa jih je treba še bolj definirat,
+ zato te zaenkrat pustimo. Razen, če je kaj čisto trivialnega za naredit. -->
+
+<respondent id="" recnum="">
+ <page id="">
+ <!-- Timestamp, ko se je stran naložila-->
+ <load_time></load_time>
+
+ <!-- (?) Ali se je stran naložila zaradi refresha -->
+ <refresh>True | False</refresh>
+
+ <!-- Jezik ankete, ki je uporabljen na tej strani. V principu lahko
+ vmes spremeni jezik in je kul, da vemo, če se to zgodi. -->
+ <language></language>
+
+ <!-- A se da prebrati nek ID sessiona? Recimo, vidim da:
+ - je v anketi brez kukijev nek dolg parameter v URL (6a515eaaa86e2cfdd207b56fb25352d2)
+ - je v anketi s kukiji podoben parameter v contentu kukija (194ca1f075ca168711b93f3168d4f868)
+ Če bi nam to pomagalo kasneje pri definiranju sessionov, bi bilo zelo fajn
+ shranit tak parameter. -->
+ <session_id></session_id>
+
+ <!-- uas, screen_resolution, window_size, screen_orientation,
+ device_orientation so zaenkrat predvideni, da se zabeležijo samo
+ ob nalaganju strani. Kasneje morda dodamo tudi sproti ob vsaki
+ spremembi, zato že zdaj shranimo tudi čas, ko se ta podatek
+ zabeleži. -->
+
+ <!-- Celoten user-agent string -->
+ <uas></uas>
+
+ <!-- Ločljivost zaslona. -->
+ <screen_resolution>
+ <time></time>
+ <res>h_res, v_res</res>
+ </screen_resolution>
+
+ <!-- Velikost okna brskalnika. -->
+ <window_size>
+ <time></time>
+ <size>h_size, v_size</size>
+ </window_size>
+
+ <!-- (?) Orientacija zaslona.
+ Vprašanje je, ali to sploh rabimo eksplicitno zabeležit ob prihodu na stran.
+ To lahko namreč raberemo iz h_res in v_res zgoraj. Drugo je, če bi to
+ kasneje naredili, da se zabeleži real-time ob vsaki spremembi. -->
+ <screen_orientation>
+ <time></time>
+ <orient>portrait | landscape</orient>
+ </screen_orientation>
+
+ <!-- (?) TABLICA/TELEFON: Orientacija naprave. -->
+ <device_orientation>
+ <time></time>
+ <orient>x_coord, y_coord, z_coord</orient>
+ </device_orientation>
+
+ <!-- (?) Zaporedje prikaza randomiziranih vprašanj na strani.
+ Zapišejo se IDji vprašanj v takšnem zaporedju kot so prikazana na strani. -->
+ <rand_q_order>q_id_3, q_id_1, q_id_2</rand_q_order>
+
+ <!-- Zaporedje prikaza randomiziranih odgovorov na strani.
+ Vnos se naredi za vsako vprašanje z randomizacijo odgovorov posebej.
+ Pri randomiziranih vrsticah v gridih so navedeni IDji spremenljivk (vrstic). -->
+ <rand_resp_order q_id="">val_3, val_1, val_2, val_5, val_4</rand_resp_order>
+ <rand_resp_order q_id="">var_id_3, var_id_4, var_id_2, var_id_1</rand_resp_order>
+
+ <!-- Izbor odgovora (zaprt tip vprašanja). Shrani se ob vsakem izboru
+ odgovora, da lahko tako sledimo vse spremembe odgovorov.
+ q_id: id vprašanja
+ var_id: id spremenljivke
+ Če lahko question id dobimo iz id spremenljivke, lahko q_id izpustimo.
+ -->
+ <response q_id ="" var_id="">
+ <!-- Timestamp, ko je izbral določen odgovor -->
+ <time></time>
+
+ <!-- Vrednost odgovora kot je določena v 1KA. Za checkbox je 1: označil, 0: odznačil -->
+ <value></value>
+
+ </response>
+
+ <!-- Vnos odgovora (odprt tip vprašanja). Shrani se ob vsakem izboru / kliku
+ na vnosno polje.
+ Če lahko question id dobimo iz id spremenljivke, lahko q_id izpustimo.
+ -->
+ <response q_id ="" var_id="">
+ <!-- Timestamp vstopa v vnosno polje -->
+ <focus_in_time></focus_in_time>
+
+ <!-- Timestamp izstopa iz vnosnega polja -->
+ <focus_out_time></focus_out_time>
+
+ <!-- Vnesen tekst ob izstopu iz polja -->
+ <text></text>
+ </response>
+
+ <!-- Lost in got fokus za okno browserja oziroma za tab. Shrani se vsakič, ko
+ anketiranec zapusti oziroma pride nazaj v browser/tab z anketo-->
+ <lost_focus_time></lost_focus_time>
+ <got_focus_time></got_focus_time>
+
+ <!-- Prikaz sporočil (alertov) anketirancu. Zabeleži se ob vsakem
+ prikazu sporočila. -->
+ <message>
+ <time></time>
+
+ <!-- Za kateri tip alerta gre (neodgovor, neveljaven številski vnos, validacija...) -->
+ <type>nonresponse | num range | validation</type>
+
+ <!-- Kaj je sprožilo to obvestilo (npr. katero vprašanje
+ ali katera validacija. -->
+ <trigger_type>question | variable | validation</trigger_type>
+ <trigger>q_id | var_id | validaton_id</trigger>
+
+ <!-- A lahko skensla obvestilo. V bistvu soft alert = True, hard alert = False -->
+ <ignorable>True | False</ignorable>
+
+ <!-- (?) Besedilo prikazanega obvestila -->
+ <text>Message text</text>
+
+ <!-- (?) Kateri gumb je kliknil - relevantno samo za soft alerte -->
+ <action>ok | cancel</action>
+ </message>
+
+ <!-- Klik kjerkoli na strani. Zabeleži se vsak klik event, s katerimkoli
+ gumbom miške. Če je to problem, lahko zaenkrat samo leve klike,
+ toliko da testiramo. -->
+ <click>
+ <time></time>
+
+ <!-- (?) Za kakšen klik gre. S tem se bomo ubadali kasneje, ko bomo
+ videli, kako ta reč deluje in kako je na mobilnih napravah. Če je pa to
+ dokaj trivialno zabeležit, se lahko tudi kar doda. -->
+ <type>single | double | right | middle | tap</type>
+
+ <!-- Koordinate klika na strani. -->
+ <location>X, Y</location>
+
+ <!-- Kaj je tam, kjer je kliknil. Zanekrat se mi zdi najlažje, da vrne
+ div_class in div_id po potrebi pa kasneje spremenimo v kaj bolj
+ user-friendly. -->
+ <div_class></div_class>
+ <div_id></div_id>
+ </click>
+
+ <!-- Timestamp, ko je stran postana -->
+ <post_time></post_time>
+
+
+ </page>
+</respondent>
+
+
+
+
+
diff --git a/admin/survey/modules/mod_advanced_paradata/js/advanced_paradata.js b/admin/survey/modules/mod_advanced_paradata/js/advanced_paradata.js new file mode 100644 index 0000000..eb93c09 --- /dev/null +++ b/admin/survey/modules/mod_advanced_paradata/js/advanced_paradata.js @@ -0,0 +1,556 @@ +// Glavna funkcija, ki se vedno klice za logiranje
+function logEvent(event_type, event, data){
+
+ //console.log(event_type + ' ' + event + ' ' + _session_id);
+
+ // Pridobimo id sessiona na strani
+ var session_id = _session_id;
+
+ // Pridobimo id ankete
+ var anketa = $('#srv_meta_anketa_id').val();
+
+ // Pridobimo trenutno stran
+ if (typeof srv_meta_grupa_id != 'undefined'){
+ var page = srv_meta_grupa_id;
+ }
+ else if ($('#outercontainer').hasClass('intro')){
+ var page = '-1';
+ }
+ else if ($('#outercontainer').hasClass('concl')){
+ var page = '-2';
+ }
+ else{
+ var page = '0';
+ }
+
+ // Pridobimo user id, recnum in jezik
+ var user = _usr_id;
+ var recnum = _recnum;
+ var language = _lang;
+
+ // Zabelezimo cas dogodka
+ var timestamp = Date.now();
+
+ // Opcijski parameter data
+ data = data || '';
+
+
+ // Pri submit oz unload eventu mora biti klic sinhron
+ if(event == 'unload_page'){
+ $.ajax({
+ type: 'POST',
+ url: '../main/survey/ajax.php?t=parapodatki&a=logData',
+ data: {
+ session_id: session_id,
+ anketa: anketa,
+ page: page,
+ usr_id: user,
+ recnum: recnum,
+ language: language,
+
+ event_type: event_type,
+ event: event,
+ timestamp: timestamp,
+
+ data: data
+ },
+ /*success: success,
+ dataType: dataType,*/
+ async: false
+ });
+ }
+ else{
+ $.post('../main/survey/ajax.php?t=parapodatki&a=logData', {
+ session_id: session_id,
+ anketa: anketa,
+ page: page,
+ usr_id: user,
+ recnum: recnum,
+ language: language,
+
+ event_type: event_type,
+ event: event,
+ timestamp: timestamp,
+
+ data: data
+ });
+ }
+}
+
+
+// EVENTI, KI JIH SPREMLJAMO
+$(function () {
+
+ // LOAD PAGE
+ window.addEventListener('load', function () {
+
+ var event_type = 'page';
+ var event = 'load_page';
+
+ // Belezimo parametre za velikost in zoom
+ var data = {
+ devicePixelRatio: window.devicePixelRatio,
+ width: window.screen.width,
+ height: window.screen.height,
+ availWidth: window.screen.availWidth,
+ availHeight: window.screen.availHeight,
+ jquery_windowW: $(window).width(),
+ jquery_windowH: $(window).height(),
+ jquery_documentW: $(document).width(),
+ jquery_documentH: $(document).height(),
+ }
+
+ // Logiramo load
+ logEvent(event_type, event, data);
+
+ // Logiramo vidna vprasanja
+ //visibleQuestions();
+ });
+
+
+ // RESIZE
+ window.addEventListener('resize', function () {
+
+ var data = {
+ pos_x: $(window).width(),
+ pos_y: $(window).height(),
+ value: window.devicePixelRatio
+ }
+
+ var event_type = 'other';
+ var event = 'resize';
+
+ // Logiramo scroll
+ logEvent(event_type, event, data);
+
+ // Logiramo vidna vprasanja
+ //visibleQuestions();
+ });
+
+ // PINCH ZOOM
+ var pinch_scaling = false;
+ var pinch_distance = 0;
+ window.addEventListener('touchstart', function (e) {
+
+ // Zaznamo 2 prsta
+ if (e.touches.length === 2) {
+ pinch_scaling = true;
+
+ // Izracunamo razdaljo med prstoma
+ pinch_distance = Math.hypot(
+ e.touches[0].screenX - e.touches[1].screenX,
+ e.touches[0].screenY - e.touches[1].screenY
+ );
+ }
+ });
+ window.addEventListener('touchend', function (e) {
+
+ if(pinch_scaling){
+ pinch_scaling = false;
+
+ // Izracunamo razdaljo med prstoma
+ var pinch_distance2 = Math.hypot(
+ e.touches[0].screenX - e.changedTouches[0].screenX,
+ e.touches[0].screenY - e.changedTouches[0].screenY
+ );
+
+ // Preracunamo razliko v razdalji
+ var diff = pinch_distance2 - pinch_distance;
+ var zoom = Math.round((diff / pinch_distance * 100));
+
+ var data = {
+ value: zoom
+ }
+
+ var event_type = 'other';
+ var event = 'pinch_resize';
+
+ // Logiramo scroll
+ logEvent(event_type, event, data);
+ }
+ });
+
+
+ // ORIENTATION CHANGE
+ window.addEventListener('orientationchange', function () {
+
+ var value = '';
+
+ if(window.orientation == 90 || window.orientation == -90)
+ value = 'landscape';
+ else
+ value = 'portrait';
+
+ var data = {
+ value: value
+ }
+
+ var event_type = 'other';
+ var event = 'orientation_change';
+
+ // Logiramo scroll
+ logEvent(event_type, event, data);
+ });
+
+ // SCROLL
+ var scroll_time_prev = 0;
+ window.addEventListener('scroll', function () {
+
+ // Dobimo trenuten cas
+ var scroll_time = new Date().getTime();
+
+ // Ce je ze poteklo dovolj casa od prejsnjega zaznavanja
+ if ((scroll_time - scroll_time_prev > 50) || scroll_time_prev == 0) {
+
+ var event_type = 'other';
+ var event = 'scroll_page';
+
+ var data = {
+ pos_x: (window.pageXOffset || document.documentElement.scrollLeft) - (document.documentElement.clientLeft || 0),
+ pos_y: (window.pageYOffset || document.documentElement.scrollTop) - (document.documentElement.clientTop || 0)
+ }
+
+ // Logiramo scroll
+ logEvent(event_type, event, data);
+
+ // Logiramo vidna vprasanja
+ //visibleQuestions();
+
+ // Shranimo cas za interval
+ scroll_time_prev = scroll_time;
+ }
+ });
+
+ // BLUR (leave to another tab etc..)
+ window.addEventListener('blur', function () {
+
+ var event_type = 'other';
+ var event = 'blur';
+
+ logEvent(event_type, event);
+ });
+
+ // FOCUS
+ window.addEventListener('focus', function () {
+
+ var event_type = 'other';
+ var event = 'focus';
+
+ logEvent(event_type, event);
+ });
+
+ // MOUSE CLICK
+ window.addEventListener('click', function (event) {
+
+ var div_id = $(event.target).attr('id');
+
+ // Ce je id prazen najdemo prvega parenta z id-jem
+ if(div_id == null){
+ div_id = $(event.target).closest('[id]').attr('id') + ' (parent)';
+ }
+
+ var data = {
+ pos_x: event.pageX,
+ pos_y: event.pageY,
+ div_type: event.target.tagName,
+ div_id: div_id,
+ div_class: $(event.target).attr('class')
+ }
+
+ var event_type = 'other';
+ var event_name = 'click';
+
+ logEvent(event_type, event_name, data);
+
+ // Posebej shranimo se mouse movement do tega klika
+ movementClickEvent(event);
+ });
+
+
+
+ // INPUT TEXT, TEXTAREA FOCUS
+ $('input[type=text], textarea').bind('focus', function () {
+
+ // Ce gre za textbox v selectu ga ignoriramo
+ if(!$(this).parent().hasClass('chzn-search')){
+
+ var event_type = 'vrednost';
+ var event = 'text_enter';
+
+ var id = $(this).attr('id');
+ var id_array = id.split('_');
+ var spr_id = id_array[1];
+ var vre_id = id_array[3];
+
+ var data = {
+ spr_id: spr_id,
+ vre_id: vre_id,
+ value: $(this).val()
+ }
+
+ logEvent(event_type, event, data);
+
+
+ // Preverimo ce gre za polje drugo - potem oznacimo tudi checkbox/radio
+ if($(this).parent().parent().parent().hasClass('tip_1') || $(this).parent().parent().parent().hasClass('tip_2')){
+
+ event = 'radio_checkbox_change';
+
+ data = {
+ spr_id: spr_id,
+ vre_id: vre_id,
+ value: 1
+ }
+
+ logEvent(event_type, event, data);
+ }
+ }
+ });
+ // INPUT TEXT, TEXTAREA BLUR
+ $('input[type=text], textarea').bind('blur', function () {
+
+ // Ce gre za textbox v selectu ga ignoriramo
+ if(!$(this).parent().hasClass('chzn-search')){
+
+ var event_type = 'vrednost';
+ var event = 'text_leave';
+
+ var id = $(this).attr('id');
+ var id_array = id.split('_');
+ var spr_id = id_array[1];
+ var vre_id = id_array[3];
+
+ var data = {
+ spr_id: spr_id,
+ vre_id: vre_id,
+ value: $(this).val()
+ }
+
+ logEvent(event_type, event, data);
+ }
+ });
+
+ // INPUT RADIO, CHECKBOX CHANGE
+ $('input[type=radio], input[type=checkbox]').bind('click', function () {
+
+ var event_type = 'vrednost';
+ var event = 'radio_checkbox_change';
+
+ var id = $(this).attr('id');
+ var id_array = id.split('_');
+
+ // Ce gre za tabelo
+ if(id_array[2] == 'grid' || id_array[0] == 'grid'){
+ var spr_id = id_array[1];
+ var vre_id = id_array[3];
+
+ // Ce je 'value' gre za missing
+ if(spr_id == 'missing'){
+ spr_id = id_array[3];
+ vre_id = id_array[5];
+ }
+ }
+ // Navadni radio oz. checkbox
+ else{
+ var spr_id = id_array[1];
+ var vre_id = id_array[3];
+
+ // Ce je 'value' gre za missing
+ if(spr_id == 'value'){
+ spr_id = id_array[3];
+ vre_id = id_array[5];
+ }
+ }
+
+ var val;
+ if ($(this).is(':checked'))
+ val = 1;
+ else
+ val = 0
+
+ var data = {
+ spr_id: spr_id,
+ vre_id: vre_id,
+ value: val
+ }
+
+ logEvent(event_type, event, data);
+ });
+
+ // SELECT CHANGE
+ $('select').bind('change', function () {
+
+ var event_type = 'vrednost';
+ var event = 'select_change';
+
+ var id = $(this).attr('id');
+ var id_array = id.split('_');
+ var spr_id = id_array[1];
+ var vre_id = $(this).val();
+
+ var data = {
+ spr_id: spr_id,
+ vre_id: vre_id,
+ value: vre_id
+ }
+
+ logEvent(event_type, event, data);
+ });
+
+
+
+ // MOUSE MOVE
+ var movements = [];
+ var currentMovement = {
+ timeStart: 0,
+ timeEnd: 0,
+ duration: 0,
+
+ startPosX: 0,
+ startPosY: 0,
+ endPosX: 0,
+ endPosY: 0,
+
+ distance_traveled: 0,
+ prevPosX: 0,
+ prevPosY: 0
+ }
+
+ // Lovimo vse preimke miske
+ window.addEventListener('mousemove', function (event) {
+ var clicked = false;
+ movementTrack(event, clicked);
+ });
+
+ // Belezimo premik v array objektov
+ var time_prev = new Date().getTime();
+ function movementTrack(event, clicked){
+
+ // Dobimo trenuten cas
+ var time = new Date().getTime();
+
+ // Ce je ze poteklo dovolj casa od prejsnjega zaznavanja
+ if (time - time_prev > 50 || clicked) {
+
+ // Preverimo, ce je to ze nov premik - zaenkrat tretiramo nov premik ce je pavze vec kot 300ms
+ if(time - currentMovement.timeEnd > 300 || clicked){
+
+ // Dodamo trenuten premik v array premikov - trik da ne insertamo reference ampak dejansko kopijo objekta
+ if(currentMovement.timeStart !== 0 && currentMovement.startPosX !== undefined && currentMovement.endPosX !== undefined){
+ movements.push(JSON.parse(JSON.stringify(currentMovement)));
+ }
+
+ // Resetiramo trenuten premik in mu nastavimo vse parametre
+ currentMovement.timeStart = time;
+ currentMovement.timeEnd = time;
+
+ currentMovement.startPosX = event.pageX;
+ currentMovement.startPosY = event.pageY;
+
+ currentMovement.endPosX = event.pageX;
+ currentMovement.endPosY = event.pageY;
+
+ currentMovement.distance_traveled = 0;
+ currentMovement.prevPosX = event.pageX;
+ currentMovement.prevPosY = event.pageY;
+ }
+ // Gre se za star premik - samo posodobimo end time in end position
+ else{
+ currentMovement.timeEnd = time;
+ currentMovement.duration = time - currentMovement.timeStart;
+
+ currentMovement.endPosX = event.pageX;
+ currentMovement.endPosY = event.pageY;
+
+ // Izracunamo razdaljo prepotovano od prejsnjega premika
+ var a = currentMovement.prevPosX - event.pageX;
+ var b = currentMovement.prevPosY - event.pageY;
+ var distance = Math.sqrt(a*a + b*b);
+
+ currentMovement.distance_traveled += distance;
+ currentMovement.prevPosX = event.pageX;
+ currentMovement.prevPosY = event.pageY;
+ }
+
+ // Shranimo cas za interval
+ time_prev = time;
+
+ /*console.log(currentMovement);*/
+ }
+ }
+
+ // Poklicemo ob vsakem kliku in shranimo podatke o premikanju med klikoma
+ function movementClickEvent(event) {
+
+ var event_type = 'movement';
+ var event = 'mouse_move';
+
+ var clicked = true;
+ movementTrack(event, clicked);
+
+ // Loop cez vse premike
+ for (var i=0; i<movements.length; i++) {
+
+ var data = {
+ time_start: movements[i].timeStart,
+ time_end: movements[i].timeEnd,
+ pos_x_start: movements[i].startPosX,
+ pos_y_start: movements[i].startPosY,
+ pos_x_end: movements[i].endPosX,
+ pos_y_end: movements[i].endPosY,
+ distance: movements[i].distance_traveled
+ }
+
+ logEvent(event_type, event, data);
+ }
+
+ // Pocitstimo array vseh premikov
+ movements = [];
+ }
+
+
+
+ // VISIBLE
+ /*function visibleQuestions() {
+
+ var event_type = 'other';
+ var event = 'visible_question';
+
+ var q = $('.grupa').find('.spremenljivka');
+ var arr = [];
+
+ $.each(q, function (i, val) {
+ if ($(val).is(':visible') && isVisible(val)) {
+ if ($(val).attr('id'))
+ arr[arr.length] = $(val).attr('id').substring(14);
+ }
+ })
+
+ var log = "" + arr;
+
+ if (log != prev_log) {
+
+ var data = {
+ log: log
+ }
+
+ logEvent(event_type, event, data);
+
+ prev_log = log;
+ }
+ }
+ var prev_log = '';
+
+ // Vrnemo ce je element viden
+ function isVisible(elem) {
+
+ var containerTop = $(window).scrollTop();
+ var containerBottom = containerTop + $(window).height();
+
+ var elemTop = $(elem).offset().top;
+ var elemBottom = elemTop + $(elem).height();
+
+ return ((elemBottom >= containerTop) && (elemTop <= containerBottom)
+ && (elemBottom <= containerBottom) && (elemTop >= containerTop) );
+ }*/
+})
\ No newline at end of file diff --git a/admin/survey/modules/mod_advanced_paradata/js/advanced_paradata_postTime.js b/admin/survey/modules/mod_advanced_paradata/js/advanced_paradata_postTime.js new file mode 100644 index 0000000..cc9d46b --- /dev/null +++ b/admin/survey/modules/mod_advanced_paradata/js/advanced_paradata_postTime.js @@ -0,0 +1,20 @@ +// EVENT LEAVE PAGE, ki se mora izvajati sinhrono (drugace se pri nekaterih browserjih izgubi)
+$(function () {
+
+ // LEAVE PAGE (gledamo unload, beforeunload, klik na submit, klik na back)
+ var leavePageFunction_called = false;
+ var leavePageFunction = function (){
+ var event_type = 'page';
+ var event = 'unload_page';
+
+ if(!leavePageFunction_called){
+ logEvent(event_type, event);
+ leavePageFunction_called = true;
+ }
+ }
+ window.addEventListener('beforeunload', leavePageFunction);
+ window.addEventListener('unload', leavePageFunction);
+ $("input.next:submit").bind('click', leavePageFunction);
+ $("input.prev:button").bind('click', leavePageFunction);
+
+})
\ No newline at end of file diff --git a/admin/survey/modules/mod_advanced_paradata/js/sledenjeOpozoril.js b/admin/survey/modules/mod_advanced_paradata/js/sledenjeOpozoril.js new file mode 100644 index 0000000..899bc5e --- /dev/null +++ b/admin/survey/modules/mod_advanced_paradata/js/sledenjeOpozoril.js @@ -0,0 +1,264 @@ +
+var spr_id_variable = []; //za sledenje opozoril: polje, ki hrani spr_id, kjer se pojavijo opozorila
+var tip_opozorila = []; //za sledenje opozoril: polje, ki hrani tip reminderja/opozorila
+var spr_id_indeks = 0; //za sledenje opozoril: indeks za polja, ki hranita spr_id, kjer se pojavijo opozorila in tip reminderja
+var opozorila_sum = []; //za sledenje opozoril
+var opozorila_num = []; //za sledenje opozoril
+var opozorila_validation = []; //za sledenje opozoril
+
+var tip_opozorila_temp = [];
+var validacijaZabelezena = [];
+var zacetnaValidacijaZabelezena = 1; //belezi, ce se je zabelezila validacija ne dinamicno, brez da bi respondent kliknu na bilo kateri odgovor in sel neposredno na naslednjo stran ankete
+var spremenljivkaVal = []; //polje, ki belezi katere spremenljivke imajo opozorilo val
+
+
+
+// ZAZNAMO PROŽENJE ALERTA
+$(function () {
+
+ var time_display;
+
+ // remember the normal alert
+ var oldAlert = (function(){ return this.alert; }()),
+ oldConfirm = (function(){ return this.confirm; }());
+
+ // inject ourself into the window.alert and window.confirm globals
+ alert = function (msg) {
+ time_display = Date.now();
+
+ oldAlert.call(window, msg);
+ window.onAlert(msg);
+ };
+ confirm = function (msg) {
+ time_display = Date.now();
+
+ var result = oldConfirm.call(window, msg);
+ window.onConfirm(msg, result);
+
+ return result;
+ };
+
+ // these just chill and listen for events
+ window.onAlert = function (text) {
+ logAlert({text:text, type:'alert box', ignorable:0, action:'ok', time_display:time_display});
+ };
+ window.onConfirm = function (text, result) {
+ var action = result ? 'yes' : 'no';
+ logAlert({text:text, type:'confirm box', ignorable:1, action:action, time_display:time_display});
+ };
+});
+
+
+
+// Logiramo alert (ob submitu)
+function logAlert(box_data){
+
+ //console.log("Trenutna dolzina polja: "+spr_id_variable.length);
+ //console.log(box_data);
+
+ var spremenljivkaVal = []; //polje, ki shranjuje spr_id spremenljivk s sprozenim val opozorilom
+ var tip_opozorila_tmp = [];
+
+ spr_id_variable.forEach(function(variable, index) {
+
+ // ce tip opozorila vsebuje vejico, pomeni, da belezi dva opozorila hkrati
+ // razbij opozorilo na dva dela
+ if(tip_opozorila[variable].includes(",")){
+ var opozorilo = tip_opozorila[variable].split(",");
+ opozorilo[1] = opozorilo[1].substring(1); //odstrani presledek na zacetku opozorila
+
+ //$.post('../main/survey/ajax.php?t=parapodatki&a=logData', {usr_id: _usr_id, what: opozorilo[0], what2: opozorilo[1], gru_id: page, anketa: srv_meta_anketa_id, spr_id_variable: variable});
+ var event_type = 'alert';
+ var event = 'alert';
+
+ opozorilo_type[0] = opozorilo[0].substring(4);
+ opozorilo_trigger_type[0] = opozorilo[0].substring(0, 3);
+ opozorilo_type[1] = opozorilo[1].substring(4);
+ opozorilo_trigger_type[1] = opozorilo[1].substring(0, 3);
+
+ var data = {
+ type: opozorilo_type[0] + ' ' + opozorilo_type[1] + ' (' + box_data.type + ')',
+ trigger_id: variable,
+ trigger_type: opozorilo_trigger_type[0] + ' ' + opozorilo_trigger_type[1],
+ text: box_data.text,
+ ignorable: box_data.ignorable,
+ action: box_data.action,
+ time_display: box_data.time_display
+ };
+
+ logEvent(event_type, event, data);
+ }
+ else{
+ //$.post('../main/survey/ajax.php?t=parapodatki&a=logData', {usr_id: _usr_id, what: tip_opozorila[variable], gru_id: page, anketa: srv_meta_anketa_id, spr_id_variable: variable});
+ var event_type = 'alert';
+ var event = 'alert';
+
+ var opozorilo_type = tip_opozorila[variable].substring(4);
+ var opozorilo_trigger_type = tip_opozorila[variable].substring(0, 3);
+
+ // Ce gre za multigrid zabelezimo samo id vprasanja
+ if(variable.substring(0, 12) == '#vrednost_if'){
+
+ var spremenljivka_id = $(""+variable).closest('.spremenljivka').attr('id').substring(14);
+
+ //variable = spremenljivka_id + '_' + variable.substring(13);
+ variable = spremenljivka_id;
+ }
+
+ var data = {
+ type: opozorilo_type + ' (' + box_data.type + ')',
+ trigger_id: variable,
+ trigger_type: opozorilo_trigger_type,
+ text: box_data.text,
+ ignorable: box_data.ignorable,
+ action: box_data.action,
+ time_display: box_data.time_display
+ };
+
+ logEvent(event_type, event, data);
+ }
+
+ //console.log("Spr_id opozorila: "+variable+", indeks "+index+", tip:"+tip_opozorila[variable]+" za user: "+_usr_id+" zacetnaValidacijaZabelezena: "+zacetnaValidacijaZabelezena);
+
+ //ce se ne belezi prvic validacije in tip opozorila je validacija
+ if(zacetnaValidacijaZabelezena == 0 && tip_opozorila[variable].includes("val"))
+ {
+ spremenljivkaVal.push(variable);
+
+ //ce se belezi dvojno opozorilo
+ if(tip_opozorila[variable].includes(",")){
+ tip_opozorila_tmp[variable] = opozorilo[0];
+ }
+ else{
+ tip_opozorila_tmp[variable] = tip_opozorila[variable];
+ }
+ }
+ });
+
+ spr_id_variable = []; // pucanje polja
+ tip_opozorila = [];
+
+ if(spremenljivkaVal.length != 0){
+ spremenljivkaVal.forEach(function(valSprem) {
+ spr_id_variable.push(valSprem);
+ tip_opozorila[valSprem] = tip_opozorila_tmp[valSprem];
+ });
+ }
+
+ //console.log("Polje spremenljivkaVal: "+spremenljivkaVal.length);
+}
+
+
+
+function dodaj_opozorilo_val(bol, id){
+
+ var spr_id = id.replace('#spremenljivka_', '');
+
+ //console.log("Tip opozorila prej:" + tip_opozorila[spr_id]);
+
+ if(zacetnaValidacijaZabelezena == 1){
+ zacetnaValidacijaZabelezena = 0;
+ }
+ else{
+ }
+
+ if(!validacijaZabelezena[spr_id]){
+ spr_id_variable.push(spr_id);
+ }
+
+
+ var tip_alerta = '';
+
+ tip_alerta = 'val';
+ validacijaZabelezena[spr_id] = 1;
+ spremenljivkaVal[spr_id] = spr_id;
+
+ tip_opozorila[spr_id] = tip_alerta + ' ' + bol + ' alert';
+}
+
+function dodaj_opozorilo(alert_sum, alert_num, alert_validation, bol, id){
+
+ //console.log("Dodaj opozorilo");
+
+ var spr_id = id.replace('#spremenljivka_', '');
+
+ var tip_alerta = '';
+
+ if(alert_sum) tip_alerta = 'sum';
+ if(alert_num) tip_alerta = 'num';
+
+ if(tip_alerta == ''){
+
+ // ce ni se nobenega opozorila zabelezenega za to spremenljivko
+ if(tip_opozorila[spr_id] == undefined){
+ tip_opozorila[spr_id] = bol+' alert';
+ spr_id_variable.push(spr_id);
+ }
+ else{
+ //drugace, ce je zabelezeno kaksno opozorilo, po navadi, ko je validation
+ tip_opozorila_temp[spr_id] = bol+' alert';
+
+ //ce je prejsnje opozorilo enako trenutnemu
+ if(tip_opozorila[spr_id] == tip_opozorila_temp[spr_id]){
+
+ tip_opozorila[spr_id] = tip_opozorila_temp[spr_id];
+ tip_opozorila_temp[spr_id] = '';
+
+ spr_id_variable.push(spr_id);
+ }
+ // drugace imamo dva razlicna opozorila, ki ju je potrebno zabeleziti
+ else if(validacijaZabelezena[spr_id] == 1){
+
+ tip_opozorila[spr_id] = tip_opozorila[spr_id]+', '+bol+' alert';
+ tip_opozorila_temp[spr_id] = '';
+
+ //console.log("Dvojno opozorilo");
+ }
+ }
+ }
+ else{
+ // ce ni se nobenega opozorila zabelezenega za to spremenljivko
+ if(tip_opozorila[spr_id] == undefined){
+
+ tip_opozorila[spr_id] = tip_alerta+' '+bol+' alert';
+ spr_id_variable.push(spr_id);
+ }
+ //drugace, ce je zabelezeno kaksno opozorilo, po navadi, ko je validation
+ else{
+ tip_opozorila_temp[spr_id] = tip_alerta+' '+bol+' alert';
+
+ // ce je prejsnje opozorilo enako trenutnemu
+ if(tip_opozorila[spr_id] == tip_opozorila_temp[spr_id]){
+ tip_opozorila[spr_id] = tip_opozorila_temp[spr_id];
+ tip_opozorila_temp[spr_id] = '';
+ spr_id_variable.push(spr_id);
+ }
+ // drugace imamo dva razlicna opozorila, ki ju je potrebno zabeleziti
+ else if(validacijaZabelezena[spr_id] == 1){
+ tip_opozorila[spr_id] = tip_opozorila[spr_id]+', '+tip_alerta+' '+bol+' alert';
+ tip_opozorila_temp[spr_id] = '';
+ }
+ }
+ }
+}
+
+function odstrani_opozorilo(id, alert_sum, alert_num, alert_validation){
+
+ //console.log("Odstrani");
+
+ var spr_id = id.replace('#spremenljivka_', '');
+
+ tip_opozorila.splice(spr_id, 1); //odstrani opozorilo iz polja
+
+ if(alert_validation){
+
+ //odstrani iz polja zabelezeno validacijo
+ spr_id_variable.forEach(function(variable, index) {
+ if(variable == spremenljivkaVal[variable]){
+ spr_id_variable.splice(index, 1);
+ }
+ });
+
+ validacijaZabelezena[spr_id] = 0;
+ }
+}
|