<?php
/************************************************************************/
/* common.php                                                           */
/*----------------------------------------------------------------------*/
/* Defines Forward, Player, AppMode, Cookie, GetLocale,                 */
/* SessionHandler, Themes and AuthHandler, ErrorToHtml                  */
/* Copyright (c) 2008-2009 Avaya Inc.                                   */
/************************************************************************/

// IIS doesn't provide REQUEST_URI, so we reconstruct it here.
if( !isset( $_SERVER['REQUEST_URI'] ) )
{
  $arr = explode( "/", $_SERVER['PHP_SELF'] );
  $_SERVER['REQUEST_URI'] = "/" . $arr[count($arr)-1];
  if( array_key_exists('ARGV',$_SERVER) )
  {
    if( $_SERVER['ARGV'][0] != "" )
    {
      $_SERVER['REQUEST_URI'] .= "?" . $_SERVER['ARGV'][0];
    }
  }
}

// The version of the application. Appears in error messages for field support.
define( 'VERSION', '9.1.400.7' );

// The name that titles the web page
define( 'WEB_APPLICATION_NAME', 'Avaya Voicemail Pro' );

// Implements interface to the voicemail server.
require_once('mailserver.php');

// Unescape '|' and ';' characters as these are used as separators in our delimited text
function UnescapeDelimiters( $s )
{
  $r = "";
  if( $s )
  {
    $esc = 0;
    for( $i=0; $i<strlen($s); ++$i )
    {
      $c = $s{$i};
      if( $esc )
      {
        if( $c == 'p' )
        {
          $c = '|';
        }
        if( $c == 's' )
        {
          $c = ';';
        }
      }
      if( !$esc && $c == '_' )
      {
        $esc = 1;
      }
      else
      {
        $r .= $c;
        $esc = 0;
      }
    }
  }
  return $r;
}

// Escape '|' and ';' characters as these are used as separators in our delimited text.
// Note: There is an identical function in the VMPro C++ code.
function EscapeDelimiters( $s )
{
  $r = str_replace( "_", "__", $s);
  $r = str_replace( ";", "_s", $r);
  $r = str_replace( "|", "_p", $r);
  return $r;
}

function TextToHtml( $str )
{
  $str = str_replace( "&", "&amp;", $str );
  $str = str_replace( "<", "&lt;", $str );
  $str = str_replace( ">", "&gt;", $str );
  $str = str_replace( "\"", "&quot;", $str );
  $str = str_replace( "'", "&#39;", $str );
  return $str;
}


// Prepare error message for document. Messages should be translated for user's locale before
// calling this function.
function ErrorToHtml( $message, $additional_info )
{
  $errmsg = TextToHtml($message. " " . $additional_info);
  return '<div class="ErrorMsg Centred" id="error_msg">'.$errmsg.'</div>';
}
// Prepare info message for document. Messages should be translated for user's locale before
// calling this function.
function InfoToHtml( $message, $additional_info )
{
  $errmsg = TextToHtml($message. " " . $additional_info);
  return '<div class="InfoMsg Centred" id="error_msg">'.$errmsg.'</div>';
}
// Strip slashes added by magic_quotes_gpc
// Disinfect input from $_GET and $_POST
function Disinfect( $text ) {
  $text = str_replace( "\r\n", "", $text );
  $text = str_replace( "\r", "", $text );
  $text = str_replace( "\n", "", $text );
  return $text;
}

function ClientTime()
{
  global $ajax_timestamp;

  $clienttime = $_SERVER['REQUEST_TIME'];
  if( !$clienttime )
  {
    $clienttime = $ajax_timestamp;
  }
  if( !$clienttime )
  {
    $clienttime = time();
  }
  return $clienttime;
}

class Forward
{
  const EXTN = 1; // Must match TYPE_USER in WebVoicemail.h
  const HUNT_GROUP = 2; // Must match TYPE_HUNTGROUP in WebVoicemail.h
  const EMAIL = 8; // Must match TYPE_EMAIL in WebVoicemail.h
}
class Player
{
  const DEFAULT_PLAYER = 'WMP';
  const VLC_PLAYER = 'VLC';
  const WIN_MEDIA_PLAYER = 'WMP';
  const EXTENSION = 'EXTN';
  const CALL_EXTENSION_TIMEOUT = 20000;
}

class Cookie
{
  const VMPRO_user_name = 'VMPRO_user_name';
  const VMPRO_user_voucher = 'VMPRO_user_voucher';
  const VMPRO_user_lang = 'VMPRO_user_lang';
  const VMPRO_msg_per_page = 'VMPRO_msg_per_page';
  const VMPRO_hide_to_col = 'VMPRO_hide_to_col';
  const VMPRO_media_player = 'VMPRO_media_player';
  const VMPRO_extension_number = 'VMPRO_extension_number';
  const VMPRO_forward_option = 'VMPRO_forward_option';
  const VMPRO_theme = 'VMPRO_theme';
  const VMPRO_block_redirection = 'VMPRO_block_redirection';
  const VMPRO_media_volume = 'VMPRO_media_volume';

  static function SetCookie($name, $value)
  {
    $expiretime = ClientTime() + 60*60*24*365; //expires in a year
    setcookie($name, $value, $expiretime);
  }
  static function ExpireCookie($name)
  {
    $expiretime = ClientTime() - 60*60*24*365; // overcompensate for variations in clients' system time
    setcookie($name, 0, $expiretime);
  }
  static function GetCookie($name)
  {
    $retval = null;
    if(isset($_COOKIE[$name]))
    {
      $retval = $_COOKIE[$name];
    }
    return $retval;
  }
}

function GetSystemLocale()
{
	$SystemLocale = 'enu';
 
 	// open the registry key 
	try
	{
		$Wshshell= new COM('WScript.Shell');
		$SystemLocale = $Wshshell->regRead('HKEY_LOCAL_MACHINE\SOFTWARE\Avaya\Media Services\Directories\SystemLocale');
	}
	catch (Exception $e) {
		GetEventLog()->WriteInfo( " Can not read registry entry SystemLocale." );	
	}
	return $SystemLocale;

}

// Get user's locale, from either GET data , or from Cookie, or from Browser preference/
// When selecting from browser preference, don't try to be smart and substitute en-us for en-gb,
// pt-pt for pt-br etc. Let user do it themself in their browser settings.
// If locale is selected from GET it is stored in a cookie and in the session. This means
// that changing locale in the browser will not have an effect until end of session and
// also cookie must be deleted.
function GetLocale()
{
  $locale = 'en_US';

  // 1. Try GET
  if (isSet($_GET['lang']))
  {
    //set language setting if it was passed in
    $locale = $_GET['lang'];
    Cookie::SetCookie(Cookie::VMPRO_user_lang, $locale);
    GetSessionHandler()->SetSessionVar(SessionHandler::CURRENT_LANG, $locale);
    GetEventLog()->WriteInfo( "Locale ".$locale. " selected from GET request" );
  }
  else
  { // 2. Try session
    $ses_lang = null;
    GetSessionHandler()->GetSessionVar(SessionHandler::CURRENT_LANG, $ses_lang);
    if ($ses_lang != null)
    {
      $locale = $ses_lang;
      GetEventLog()->WriteInfo( "Locale ".$locale. " selected from session" );
    }
    else
    { // 3. Try cookie
      $cookie_locale = (Cookie::GetCookie(Cookie::VMPRO_user_lang ));
      if ($cookie_locale)
      {
        $locale = $cookie_locale;
        GetEventLog()->WriteInfo( "Locale ".$locale. " selected from cookie" );
      }
      else if( isset( $_SERVER['HTTP_ACCEPT_LANGUAGE'] ) )
      {
        // 4. Try browser
        $langs = $_SERVER['HTTP_ACCEPT_LANGUAGE'];   // e.g. en-gb,en;q=0.7,en-us;q=0.3
        $lang_array = explode(',', $langs );
        $qual = 0.0;
        foreach( $lang_array as $lang )
        {
          if( preg_match('/([A-Za-z\-]+)(;q=([0-9\.]+))?/', $lang, $matches) )
          {
            if( !isset( $matches[3] ) )
            {
              $matches[3] = '1.0';
            }
            switch( strtolower($matches[1]) )
            {
//da_DK
              case 'da':
              case 'da-dk':
                if( ((float)$matches[3]) > $qual )
                {
                  $qual = (float)$matches[3];
                  $locale = 'da_DK';
                }
                break;

//de_DE
              case 'de':
              case 'de-de':
              case 'de-at':
              case 'de-ch':
              case 'de-li':
              case 'de-lu':
                if( ((float)$matches[3]) > $qual )
                {
                  $qual = (float)$matches[3];
                  $locale = 'de_DE';
                }
                break;

//el_GR
              case 'el':
              case 'el-gr':
                if( ((float)$matches[3]) > $qual )
                {
                  $qual = (float)$matches[3];
                  $locale = 'el_GR';
                }
                break;
//en_GB
              case 'en':
              case 'en-au':
              case 'en-bz':
              case 'en-gb':
              case 'en-ie':
              case 'en-jm':
              case 'en-nz':
              case 'en-ph':
              case 'en-tt':
              case 'en-za':
              case 'en-zw':
                if( ((float)$matches[3]) > $qual )
                {
                  $qual = (float)$matches[3];
                  $locale = 'en_GB';
                }
                break;
//en_US
              case 'en-ca':
              case 'en-us':
                if( ((float)$matches[3]) > $qual )
                {
                  $qual = (float)$matches[3];
                  $locale = 'en_US';
                }
                break;

//es_ES
              case 'es':
              case 'es-es':
              case 'es-ar':
              case 'es-bo':
              case 'es-cl':
              case 'es-co':
              case 'es-cr':
              case 'es-do':
              case 'es-ec':
              case 'es-gt':
              case 'es-hn':
              case 'es-ni':
              case 'es-pa':
              case 'es-pe':
              case 'es-pr':
              case 'es-py':
              case 'es-sv':
              case 'es-us':
              case 'es-uy':
              case 'es-ve':
                if( ((float)$matches[3]) > $qual )
                {
                  $qual = (float)$matches[3];
                  $locale = 'es_ES';
                }
                break;

//es_MX
              case 'es-mx':
                if( ((float)$matches[3]) > $qual )
                {
                  $qual = (float)$matches[3];
                  $locale = 'es_MX';
                }
                break;
//fi_FI
              case 'fi':
              case 'fi-fi':
                if( ((float)$matches[3]) > $qual )
                {
                  $qual = (float)$matches[3];
                  $locale = 'fi_FI';
                }
                break;
//fr_FR
              case 'fr':
              case 'fr-fr':
              case 'fr-be':
              case 'fr-ch':
              case 'fr-lu':
              case 'fr-mc':
                if( ((float)$matches[3]) > $qual )
                {
                  $qual = (float)$matches[3];
                  $locale = 'fr_FR';
                }
                break;
//fr_CA
              case 'fr-ca':
                if( ((float)$matches[3]) > $qual )
                {
                  $qual = (float)$matches[3];
                  $locale = 'fr_CA';
                }
                break;

//hu_HU
              case 'hu':
              case 'hu-hu':
                if( ((float)$matches[3]) > $qual )
                {
                  $qual = (float)$matches[3];
                  $locale = 'hu_HU';
                }
                break;


//it_IT
              case 'it':
              case 'it-it':
              case 'it-ch':
                if( ((float)$matches[3]) > $qual )
                {
                  $qual = (float)$matches[3];
                  $locale = 'it_IT';
                }
                break;


//ko_KR
              case 'ko':
              case 'ko-kr':
                if( ((float)$matches[3]) > $qual )
                {
                  $qual = (float)$matches[3];
                  $locale = 'ko_KR';
                }
                break;


//no_NO
              case 'nb-no':
              case 'nn-no':
              case 'no':
              case 'no-no':
                if( ((float)$matches[3]) > $qual )
                {
                  $qual = (float)$matches[3];
                  $locale = 'no_NO';
                }
                break;

//nl_NL
              case 'nl':
              case 'nl-nl':
              case 'nl-be':
                if( ((float)$matches[3]) > $qual )
                {
                  $qual = (float)$matches[3];
                  $locale = 'nl_NL';
                }
                break;

//pt_PT
              case 'pt':
              case 'pt-pt':
                if( ((float)$matches[3]) > $qual )
                {
                  $qual = (float)$matches[3];
                  $locale = 'pt_PT';
                }
                break;

//pt_BR
              case 'pt-br':
                if( ((float)$matches[3]) > $qual )
                {
                  $qual = (float)$matches[3];
                  $locale = 'pt_BR';
                }
                break;

//ru_RU
              case 'ru':
              case 'ru-ru':
              case 'ru-md':
                if( ((float)$matches[3]) > $qual )
                {
                  $qual = (float)$matches[3];
                  $locale = 'ru_RU';
                }
                break;

//sv_SE
              case 'sv':
              case 'sv-se':
              case 'sv-fi':
                if( ((float)$matches[3]) > $qual )
                {
                  $qual = (float)$matches[3];
                  $locale = 'sv_SE';
                }
                break;

//zh_CN
              case 'zh':
              case 'zh-cn':
              case 'zh-hk':
              case 'zh-mo':
              case 'zh-sg':
              case 'zh-tw':
                if( ((float)$matches[3]) > $qual )
                {
                  $qual = (float)$matches[3];
                  $locale = 'zh_CN';
                }
                break;
            }
          }
        }
        GetEventLog()->WriteInfo( "Locale ".$locale. " selected from HTTP_ACCEPT_LANGUAGE ".$_SERVER['HTTP_ACCEPT_LANGUAGE'] );
      }
      else
      {
        GetEventLog()->WriteInfo( "Locale ".$locale. " selected by default" );
      }
    }
  }
  return $locale;
}


// Singleton accessor
function GetSessionHandler()
{
  static $handler;
  if( !$handler )
  {
    $handler = new SessionHandler();
  }
  return $handler;
}

class SessionHandler
{
  const USER_ID = 'userID';
//  const CURRENT_FOLDER_NAME = 'cfName';
  const CURRENT_FOLDER_ID = 'cfID';
  const CURRENT_MB = 'mailBox';
  const CURRENT_LANG = 'lang';
  const CURRENT_MODE = 'mode';

  private $auth_text;

  // Reasons for authentication failure
  const AUTH_NULL = 0;
  const AUTH_SUCCESS = 1;
  const AUTH_NOSERVER = 2;
  const AUTH_SERVER = 3;
  const AUTH_NOSESSION = 4;
  const AUTH_EXPIRED = 5;
  const AUTH_NOUSER = 6;
  const AUTH_OFFLINE = 7;
  const AUTH_MAX = 8;
  // When adding to this list, add also to $auth_text array in constructor.

  function __construct()
  {
    $this->auth_text = array();
    $this->auth_text[SessionHandler::AUTH_NULL]="Unknown authentication problem";
    $this->auth_text[SessionHandler::AUTH_SUCCESS]="Authentication was successful";
    $this->auth_text[SessionHandler::AUTH_NOSERVER]="Server can't be reached";
    $this->auth_text[SessionHandler::AUTH_SERVER]="Server won't let session proceed";
    $this->auth_text[SessionHandler::AUTH_NOSESSION]="There is no session to validate";
    $this->auth_text[SessionHandler::AUTH_EXPIRED]="User has been idle too long";
    $this->auth_text[SessionHandler::AUTH_NOUSER]="There is no server record for this user";
    $this->auth_text[SessionHandler::AUTH_OFFLINE]="User has been out of contact with server for too long";
  }
  function __destruct()
  {
  }

  function ErrorText($reason)
  {
    if( $reason >= 0 && $reason < SessionHandler::AUTH_MAX )
    {
      return $this->auth_text[$reason];
    }
    return $reason;
  }

  function SetSessionVar($name, $value)
  {
    $_SESSION[$name] = $value;
  }

  function GetSessionVar($name, &$var)
  {
    if (isset($_SESSION[$name]))
    {
      $var = $_SESSION[$name];
    }
    else
    {
      $var = null;
    }
  }

  function GetSessionId()
  {
    $id = $_COOKIE['PHPSESSID'];
    return $id;
  }

  function DestroySession()
  {
    $_SESSION = array();
    if (isset($_COOKIE[session_name()]))
    {
      setcookie(session_name(), '', ClientTime()-42000, '/');
    }
    session_destroy();
  }

  function Authenticate( $sessionId, &$user )
  {
    GetEventLog()->WriteInfo( "Authenticate(" . $sessionId . ")" );
    $reason = SessionHandler::AUTH_NULL;
    $user = NULL;
    $userId = "";

    // Check there is a session on the webserver for this user
    if( !isset($_SESSION[ SessionHandler::USER_ID ]) )
    {
      $reason = SessionHandler::AUTH_NOSESSION;  // There is no session for the user
    }
    else
    {
      $userId = $_SESSION[ SessionHandler::USER_ID ];

      // Check user is still allowed to use system
      $mailserver = GetMailserver();
      if( !$mailserver )
      {
        $reason = SessionHandler::AUTH_NOSERVER; // Server can't be reached
      }
      else
      {
        $allowed = $mailserver->IsUserAllowed( $sessionId, $userId );
        if( !$allowed )
        {
          $reason = SessionHandler::AUTH_SERVER;  // Server won't let session proceed
        }
        else
        {
          $user = $mailserver->GetUserById( $sessionId, $userId );
          if( !$user )
          {
            $reason = SessionHandler::AUTH_NOUSER;  // There is no user record available
          }
          else
          {
            // Check user has been active recently
            $idle_time = $mailserver->GetTimeSinceLastAction( $sessionId, $userId );
            $timeout = GetConfiguration()->SessionTimeout;
            GetEventLog()->WriteInfo("Session idle for " . $idle_time . " (" . $timeout .")" );
            if( $idle_time > $timeout )
            {
              $reason = SessionHandler::AUTH_EXPIRED; // Session idle for too long
              $user = NULL;
            }
            else
            {
            	$offline_time = $mailserver->GetTimeSinceLastContact( $sessionId, $userId );
            	$timeout = 60;
            	GetEventLog()->WriteInfo("Session out of contact for " . $offline_time . " (" . $timeout .")" );
	            if( $offline_time > $timeout )
	            {
	              $reason = SessionHandler::AUTH_OFFLINE; // Session out of contact with server for too long
	              $user = NULL;
	            }
	            else
	            {
	            	$reason = SessionHandler::AUTH_SUCCESS;   // Authentication was successful
	            }
            }
          }
        }
      }
    }
    return $reason;
  }
}


class Themes
{

  function ListFiles($dir)
  {
      $dh = opendir($dir);
        $files = Array();
      if ($dh)
      {
          $inner_files = Array();

          while( true == ($file = readdir($dh)) )
          {
              if($file != '.' && $file != '..' && $file[0] != '.')
              {
                  if(is_dir($dir . '/' . $file))
                  {
                      $inner_files = ListFiles($dir . '/' . $file);
                      if(is_array($inner_files))
                        $files = array_merge($files, $inner_files);
                  }
                  else
                  {

                      array_push($files, $this->StripExt($file));
                  }
              }
          }

          closedir($dh);
      }
        return $files;
  }

  // Helper. strips file extension
  function StripExt($name)
  {
    $ext = strrchr($name, '.');
    if($ext != false)
    {
      $name = substr($name, 0, -strlen($ext));
    }
    return $name;
  }

}


function AvayaLink()
{
  $site = "";
  $language = "*";
  // Try to guess the user's country based on their browser's language setting
  $langs = $_SERVER['HTTP_ACCEPT_LANGUAGE'];   // e.g. en-gb,en;q=0.7,en-us;q=0.3
  $lang_array = explode(',', $langs );
  $qual = 0.0;
  foreach( $lang_array as $lang )
  {
    if( preg_match('/([A-Za-z\-]+)(;q=([0-9\.]+))?/', $lang, $matches) )
    {
      if( !isset( $matches[3] ) )
      {
        $matches[3] = '1.0';
      }
      if( ((float)$matches[3]) > $qual )
      {
        $qual = (float)$matches[3];
        $language = strtolower($matches[1]);
      }
    }
  }

  $siteslist = "locale/avayasites.txt";
  if( file_exists( $siteslist ) )
  {
    $handle  = fopen( $siteslist, 'r' );
    if( $handle )
    {
      while( !feof( $handle ) )
      {
        $line = fgets( $handle, 4096 ) ;
        $line = chop($line);
        if( preg_match('/^' . $language . '\s+(.*)$/', $line, $matches) )
        {
          $site = $matches[1];
          break;
        }
        else if( strlen($site) == 0 )
        {
          // Default site
          if( preg_match('/^\*\s+(.*)$/', $line, $matches) )
          {
            $site = $matches[1];
          }
        }
      }
      fclose( $handle );
    }
    else
    {
      GetEventLog()->WriteError( "Avaya websites file \"" . getcwd() . "/" . $siteslist . "\" not loaded." );
    }
    GetEventLog()->WriteInfo( "Avaya website \"" . $site . "\" selected for \"" . $language . "\"." );
  }
  else
  {
    GetEventLog()->WriteError( "Avaya websites file \"" . getcwd() . "/" . $siteslist . "\" not found." );
  }


  if( strlen( $site ) == 0 )
  {
    $site = "http://www.avaya.com/";
  }

  return $site;
}

?>