﻿<?php

/*
 * This file is part of the Voxibot Studio project
 * Copyright (c) 2019 Ulex Innovative Systems
 * Author: Borja SIXTO
 *
 * This program can not be copied and/or distributed without the express
 * permission of Ulex Innovative Systems
 *
 */

$rootdir=dirname(__DIR__);
require_once($rootdir."/voxibot.php");

// URL Example :
// https://dev3.voxibot.net:44236/api/session.php?token=1234&sessionid=auto&context=popo&result=momo
// https://dev3.voxibot.net:44236/api/session.php?token=1234&phone=1234&context=popo&result=momo
// https://dev3.voxibot.net:44236/api/session.php?token=1234&phone=1234


function voxibot_session($value, $index, $datas=[], $context=null)
{
  global $config;
  
  $table = 'sessions';
  $parameters = false;
  
  //voxibot_debug("SESSION : datas = ".print_r($datas, TRUE));  
  
  $type = gettype($context);
  if ($type == "array" || $type =="object")
  {
    $context = json_encode($context, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
  }
  
  // Database connection
  $link = mysqli_connect($config['database']['hostname'], $config['database']['user'], $config['database']['password']);
  if (!$link)
  {
    voxibot_error('Database error:'.mysqli_error());
    mysqli_close($link); 
    return false;
  }
  if (!mysqli_select_db($link, $config['database']['name']))
  {
    voxibot_error('SESSION: Cannot select database:'.$config['database']['name']);
    mysqli_close($link); 
    return false;
  }
  mysqli_set_charset($link, 'utf8');
  
  voxibot_debug("DATABASE : session uses index = ".$index);      
  
  $champs = explode(',', $index);
  
  // Purge old session
  if (true)
  if (isset($config['database']['duration']) && $config['database']['duration']>0)
  {
    $query = "DELETE FROM sessions WHERE date_creation  < (NOW() - INTERVAL ".$config['database']['duration']." SECOND)";
    
    voxibot_debug("SESSION : query(duration) = ".$query);
    
    $result = mysqli_query($link, $query);
    if (!$result)
    voxibot_result(null, mysqli_error($link));    
  }
  if (true)
  if (isset($config['database']['expiration']) && $config['database']['expiration']>0)
  {
    $query = "DELETE FROM sessions WHERE date_update < (NOW() - INTERVAL ".$config['database']['expiration']." SECOND)";
    
    voxibot_debug("SESSION : query(expiration) = ".$query);
    
    $result = mysqli_query($link, $query);
    if (!$result)
    voxibot_result(null, mysqli_error($link));    
  }  
  
  $where = null;
      
  if (isset($value) && $value != '')
  foreach ($champs as $nom_champs)
  {    
    if (isset($where))
    $where .= ' OR';
    else
    $where = '';
    
    if ($value[0]=='*') 
    { 
      $value2 = substr($value, 1);
      $where .= ' RIGHT('.$nom_champs.', '.strlen($value2).') = \''.$value2.'\'';
    }
    else
    {
      $where .= ' '.$nom_champs.' = \''.$value.'\'';
    }
  }

  $count = 0;

  if ($where != '')
  {
    $query = 'SELECT * FROM '.$table.' WHERE '.$where;
    $query .= ' ORDER BY date_creation DESC LIMIT 1';
    voxibot_debug("SESSION : query = ".$query);
    $result = mysqli_query($link, $query);
    if (!$result) {
      voxibot_error("DB: query failed: " . mysqli_error($link) . " | query: " . $query);
      voxibot_result(null, mysqli_error($link));
    }

    $count = mysqli_num_rows($result);
    voxibot_debug("SESSION : count = ".$count);   
  }

  if ($count > 1)
  {
    voxibot_error("Match too much sessions!");
    $result = false; 
  }
  
  voxibot_debug("SESSION : count datas = ".count($datas));   

  if ($count == 1)
  if (count($datas) || isset($context))
  {
    voxibot_debug("SESSION : Update datas/context in the session");    
  
    $datas['date_update'] = date('Y-m-d H:i:s');
      
    if (isset($datas['sessionid']))
    unset($datas['sessionid']);
    if (isset($datas['pin']))
    unset($datas['pin']);    
      
    $num_fields = mysqli_num_fields( $result );

    for ( $i = 0; $i < $num_fields; $i++ ) {
        $fields[] = mysqli_fetch_field_direct($result, $i)->name; 
    }
    
    voxibot_debug("DATABASE : fields = ".print_r($fields, TRUE));
          
    $query = "UPDATE `".$table."` SET ";

    $i = 0;
    $f = true;
    
    if (count($datas))
    foreach($datas as $key => $val) {
        voxibot_debug("Check : datas field = ".$key." = ".$val);    
        $val = str_replace("'"," ",$val);
        if (in_array($key, $fields))
        {
          if (!$f) {
            $query.= " , ";
          }
          $query.= $key." = '".$val."'";
          $f = false;
        }
        else
        {
          voxibot_debug("DATABASE : field not exists = ".$key);      
        }
        $i++;
    } 
    
    if (isset($context))
    {
      //$context = json_encode($context, JSON_PRETTY_PRINT);  
      $context = str_replace("'","\'",$context);
      $context = str_replace("\\\"","\\\\\"",$context);   // !!!!!!!!!
      if (!$f) {
        $query.= " , ";
      }
      $query .= "context = '".$context."'";
      $f = false;        
    }     
     
    if ($where != '')
    {
      $query .= ' WHERE '.$where;
      $query .= ' ORDER BY date_creation DESC LIMIT 1';
      voxibot_debug("DATABASE : query = ".$query);
      $result2 = mysqli_query($link, $query);
      if (!$result2)         
      {
        voxibot_error('Database error:'.mysqli_error($link));
      }                                             

      // Refresh updated results
      $query = 'SELECT * FROM '.$table.' WHERE '.$where;
      $query .= ' ORDER BY date_creation DESC LIMIT 1';
      voxibot_debug("SESSION : query = ".$query);
      $result = mysqli_query($link, $query);
      if (!$result)
      voxibot_result(null, mysqli_error($link));
      
      $count = mysqli_num_rows($result);
      voxibot_debug("SESSION : count = ".$count);  
    }
    else
    {
      $result = false;
    }
  }
  else
  if (isset($config['database']['duration']) && $config['database']['duration']==0)
  {
    voxibot_debug("SESSION : Remove item by configuration");  
          
    $datas['date_access'] = date('Y-m-d H:i:s');
    
    $query = "DELETE FROM `".$table."`"; 
    $query .= ' WHERE '.$where;
    
    voxibot_debug("DATABASE : query = ".$query);
    $result2 = mysqli_query($link, $query);
    if (!$result2)         
    {
      voxibot_error('Database error:'.mysqli_error($link));
    }   
  }  
  else
  {
    voxibot_debug("SESSION : Update access date");  
          
    $datas['date_access'] = date('Y-m-d H:i:s');
    
    $query = "UPDATE `".$table."` SET date_access = '".$datas['date_access']."'";
    
    $query .= ' WHERE '.$where;
    
    voxibot_debug("DATABASE : query = ".$query);
    $result2 = mysqli_query($link, $query);
    if (!$result2)         
    {
      voxibot_error('Database error:'.mysqli_error($link));
    }  
  }

  //if ($count == 0 && isset($context))
  if ($count == 0) 
  { 
    //if (isset($config['database']['autoinsert']) && $config['database']['autoinsert'])
    if (isset($context))
    {
      $pin = '';
      
      voxibot_debug("DATABASE : autoinsert ".$value);
      
      $datas['date_creation'] = date('Y-m-d H:i:s');    
      
      if ($index == 'pin' && $value != '')
      $pin = $value;
      
      if (isset($config['database']['pin']) && $config['database']['pin'])
      if (!$pin)    
      {
        do
        {
          $pin = mt_rand(1000, 9999);
          voxibot_debug("Random PIN generated ".$pin);
          
          $query = 'SELECT * FROM '.$table.' WHERE pin='.$pin;
          voxibot_debug("DATABASE : query = ".$query);
          $result = mysqli_query($link, $query);
          if (!$result)
          voxibot_result(null, mysqli_error($link));
          
          $count = mysqli_num_rows($result);
          voxibot_debug("DATABASE : count = ".$count);     
        }
        while ($count);
        
        $datas['pin'] = $pin;
      }
    
      if ((($index=="sessionid") && $value=='auto6') || (isset($datas['sessionid']) && $datas['sessionid']=='auto6'))
      {
        do
        {
          $sessionid = bin2hex(random_bytes(6));
          voxibot_debug("Random sessionid generated ".$sessionid);
          
          $query = 'SELECT * FROM '.$table.' WHERE sessionid=\''.$sessionid.'\'';
          voxibot_debug("DATABASE : query = ".$query);
          $result = mysqli_query($link, $query);
          if (!$result)
          voxibot_result(null, mysqli_error($link));
          
          $count = mysqli_num_rows($result);
          voxibot_debug("DATABASE : count = ".$count);     
        }
        while ($count);  
        
        $datas['sessionid'] = $sessionid;
      }    
      
      if (($index=="sessionid") && $value=='auto')
      $datas['sessionid'] = uniqid('ID_', true);
      else
      if (isset($datas['sessionid']) && $datas['sessionid']=='auto')
      $datas['sessionid'] = uniqid('ID_', true);
        
      if ($result)
      {
        $num_fields = mysqli_num_fields( $result );    
        for ( $i = 0; $i < $num_fields; $i++ ) {
            $fields[] = mysqli_fetch_field_direct($result, $i)->name; 
        }
      }
      
      mysqli_free_result($result);
      
      $query2 = '';

      $query = "INSERT INTO `".$table."` (";
      $i = 0;
      $f = true;

      foreach($datas as $key => $val) {
          voxibot_debug("Check : datas field = ".$key." = ".$val); 
               
          //$val = str_replace("'","\'",$val);
          $val = mysqli_real_escape_string($link, $val);
          
          if (in_array($key, $fields))
          {
            if (!$f) {
              $query.= " , ";
              $query2.= " , ";
            }
            $query.= $key;
            $query2.= "'".$val."'";
            $f = false;
          }
          else
          {
            voxibot_debug("DATABASE : field not exists = ".$key);      
          }
          $i++;
      }
      
      if (isset($context))
      {
        if ($datas != '') 
        $query .= " , context ";
        else
        $query .= " context ";
        
        //$query2 .= " , '".json_encode($context, JSON_PRETTY_PRINT)."'";
        
        //$context = str_replace("'","\'",$context);        
        //$context = str_replace("\\\"","\\\\\"",$context);   
        
        $context = mysqli_real_escape_string($link, $context);
        
        if ($datas != '') 
        $query2 .= " , '".$context."'";
        else
        $query2 .= " '".$context."'";
      }  
      
      if (($index) && (!isset($datas[$index])))
      {
        voxibot_debug("DATABASE : add index because not in datas = ".$index);          
        
        voxibot_debug("DATABASE : add index champs[0] = ".$champs[0]);    
      
        $query.= ",";
        $query2.= ",";  
        $val = str_replace("'","\'",$value);
        $query.= "".$champs[0];
        $query2.= " '".$val."'";
      }

      $query.=  ') VALUES ('.$query2.')';

      voxibot_debug("DATABASE : query = ".$query);
      
      $result2 = mysqli_query($link, $query);
      if (!$result2)
      voxibot_result(null, mysqli_error($link));
      
       // Récupération de l'ID inséré
      $last_id = mysqli_insert_id($link);

      voxibot_debug("Last ID inserted : " . $last_id);     
      
      // Refresh updated results
      $query = 'SELECT * FROM '.$table.' WHERE id='.$last_id;
      voxibot_debug("SESSION : query = ".$query);
      $result = mysqli_query($link, $query);
      if (!$result)
      voxibot_result(null, mysqli_error($link));
      
      $count = mysqli_num_rows($result);
      voxibot_debug("SESSION : count = ".$count);  
    }
    else
    {
      voxibot_debug("SESSION : Session not found");  
      $result = false;
    }
  }
  
  voxibot_debug("SESSION : count=".$count);  

  if ($count == 1)
  {
    voxibot_debug("SESSION : Dump final session");  
        
    while ($line = mysqli_fetch_assoc($result)) { 
    
      //$result = array(); 

      foreach($line as $name => $type) {
          if (isset($types[$name]))
          if ($types[$name] == 'datetime')
          $line[$name] = str_replace('-', '/', $line[$name]);
          else
          settype($line[$name], $types[$name]);
          
          if (($name == 'context') && ($line[$name][0]=='{'))
          {        
            voxibot_debug("JSON VALUE ".$line[$name]);  
            //$line[$name] = str_replace('u0', '\u0', $line[$name]);
            $line[$name] = json_decode($line[$name]);
          }    
      }
      $result2 = $line;    
      
      voxibot_debug("VALUES ".json_encode($result2, JSON_PRETTY_PRINT));  
    }
    
    $result = $result2;
    
    voxibot_debug("VALUES ".json_encode($result, JSON_PRETTY_PRINT));  
  }

  mysqli_close($link);

  return $result;  
}

/*
if ($call)
{
  header("Location: tel:".$call);
  exit();
}
*/

// Execution
if($_SERVER['SCRIPT_FILENAME']==__FILE__)
{
  if (isset($config['database']['sessionkey']))
  {
    voxibot_debug("Use session key : ".$config['database']['sessionkey']);  
      
    $index = $config['database']['sessionkey'];
  }
  else
  $index = "id";
  
  $value =  voxibot_parameter($index, false);
      
  if (!$value)
  {
    if (!$value)
    {
      $value =  voxibot_parameter('sessionid', false);
      if ($value)
      $index = "sessionid";
    } 
    
    if (!$value)
    {
      $value =  voxibot_parameter('pin', false);
      if ($value)
      $index = "pin";
    }     
      
    if (!$value)
    {
      $value =  voxibot_parameter('phone', false);
      if ($value)
      $index = "phone";
    } 
    
    if (!$value)
    {
      $value =  voxibot_parameter('uniqueid', false);
      if ($value)
      $index = "uniqueid";
    }  
    
    $value = voxibot_parameter($index, $value);  
  }  
  
  $datas = voxibot_parameter('set', array());
  $datas = voxibot_parameter('datas', $datas);
  $datas[$index] = $value;  
  $context = voxibot_parameter('context', null);
  $result = voxibot_parameter('result', null);  
  
  if (isset($result))
  $datas['result'] = $result;
  
  if ($index != 'sessionid')
  {
    $result = voxibot_parameter('sessionid', null);
    if (!isset($datas['sessionid']))
    if ($result)
    $datas['sessionid'] = $result; 
  }   

  if ($index != 'uniqueid')
  {
    $result = voxibot_parameter('uniqueid', null);
    if (!isset($datas['uniqueid']))
    if ($result)
    $datas['uniqueid'] = $result;  
  }
  
  if ($index != 'phone')
  {
    $result = voxibot_parameter('phone', null);
    if (!isset($datas['phone']))
    if ($result)
    $datas['phone'] = $result;
  }  
  
  if ($index != 'pin')
  {
    $result = voxibot_parameter('pin', null);
    if (!isset($datas['pin']))
    if ($result)
    $datas['pin'] = $result;
  }    
    
  /* $call = voxibot_parameter('call', false); */
  
  if (false)
  if (count($datas)>0)
  {
    if ($index)
    $datas[$index]=$value;
    $index= false;
  }
  
  voxibot_debug("datas: ".json_encode($datas, JSON_PRETTY_PRINT)); 
  
  $result = voxibot_session($value, $index, $datas, $context);
  
  if ($result === false)
  {
    if (isset($datas['phone']))
    if ($index != 'phone')
    {
      $value = '*'.substr($datas['phone'], -9);
      unset($datas["phone"]);
      $result = voxibot_session($value, 'phone', $datas, $context); 
    }
  }
  
  voxibot_result($result, $result==false);
}

?>
