<?
/**
 * VoiceOne Webservices Interface
 *
 * @package voiceone_webservices
 * @subpackage  sounds
 */ 
//******************************************************************************
//********************             SOUNDS             **************************
//******************************************************************************
/**
 * Initialize table cw_sounds_files with audio file in asterisk/sounds.
 *
 * @param null
 * @return array $ret xsd:int number of error during insert operations
 * @see getSoundDesc
 * @see getLanguages
 * @see getCatidByCatname
 * @see putTempSound
 * @see deleteTempSound
 * @see modifySound
 */
function soundsInit($reload=0) {
  global $db, $voTools, $voiceoneWSDocumentRoot;
  // if reload==true set presence falg to 0
  if($reload==1){
    $qry="UPDATE `cw_sounds_file` SET `present`=0";
    $res=$db->Execute($qry);
    if($res===false) return 0;
  }
  // get categories
  $qry="SELECT * FROM `cw_sounds_category`";
  $res=$db->Execute($qry);
  while($arr=$res->FetchRow()){
   $categories[]=$arr;
   $catArr[]=$arr["tag"];
  }
  // create filesList.txt
  $topath = $voiceoneWSDocumentRoot."/sandbox";
  exec("sudo $voTools soundsInit $topath",$output,$retScript);
  // read  filesList.txt
  exec("sudo $voTools getSoundsDir",$output,$retScript);
  if(count($output)<1) return 0;
  $soundspath=$output[0];
  $file_list = $topath."/sounds/filesList.txt";
  if(is_file($file_list)) {
    $lines = file($file_list);
    // process files list
    $error=0;
    $forget=false;
    foreach($lines as $line){
      // Folder
      if(substr($line,0,1)=='/'){
        $div=array();
        $forget=false;
        $lang="default";
        $line=substr($line,0,-2);
        $folder=str_replace($soundspath, "", $line);
        //find language as first folder
        if(strlen($folder)>1) $firstfolder=substr($folder,1);
        if(strpos($firstfolder,"/")!==false) $firstfolder=substr($firstfolder,0,strpos($firstfolder,"/"));
        if(((strlen($firstfolder)==2)||(strlen($firstfolder)==5))&&(!in_array($firstfolder,$catArr))){ 
          $lang=$firstfolder;
        }
        // find category's folder in "sounds/"
        //$tmp=ereg(".*/(.*)", $folder, $div); //DEPRECATED IN PHP 5.3
        //$lastfolder=$div[1];                 //
        if($folder!=''){
          $lastfolder=basename($folder);
          if(substr($folder,1)==$lang) $lastfolder='';
        }else $lastfolder='';
        //skip some voiceone folders
        if(strstr($folder,"voiceone")!==false){
          if(!in_array($lastfolder,array('custom','IVR','tmp'))) $forget=true;
        }
        continue;
      }
      // Skip Directory
      else if((substr($line,0,1)=='d')&&($forget===false)) continue;
      // File
      else if((substr($line,0,1)=='-')&&($forget===false)){
        $line=substr($line,0,-1);
        //$tmp=ereg(".* (.*)", $line, $div1); //DEPRECATED IN PHP 5.3
        //$name_complete=$div1[1];            //
        $tmp=preg_match("/^.*(\s)(.*)$/i", trim($line), $div1);
        $name_complete=$div1[2];
        // check file extension
        if(substr($name_complete, -4)!=".gsm") continue; 
        // extract category and filename
        if($lastfolder==""){ // folder "~/lang/": extract catecory from filename
          if(strstr($name_complete, "-")===false){
            $filename=$name_complete;
            $category="general";
          }else{
            $name_arr=explode("-",$name_complete);
            $i=0;
            if(is_array($name_arr)){
              foreach($name_arr as $piece){
                if($i==0) $category=$piece;
                else if($i==1) $filename=$piece;
                else $filename.="-".$piece;
                $i++;
              }
            }
          }
          // extract category_id
          $category_id="";
          foreach($categories as $cat){
            if($cat["tag"]=="general") $cat_general_id=$cat["id"];
            if($category==$cat["tag"]) $category_id=$cat["id"];
          }
          if($category_id=="") {
            $category_id=$cat_general_id;
            $filename=$category."-".$filename;
          }
        }
        else{ // folder "~/$lang/xxx": category is the folder name -> xxx
          $filename=$name_complete;
          $category=$lastfolder;
          // extract category_id
          $category_id="";
          foreach($categories as $cat){
            if($cat["tag"]=="general") $cat_general_id=$cat["id"];
            if($category==$cat["tag"]) $category_id=$cat["id"];
          }
          if($category_id=="") $category_id=$cat_general_id;
        }
        // check cw_sounds_files if it is a preload file 
        $filename=substr($filename, 0, -4);
        $filename=str_replace("-","_",$filename);
        $ret=getSoundDesc($filename, $category_id, $lang);
        if(is_array($ret)){
          if(count($ret)==1){
            $qry="UPDATE `cw_sounds_file` SET `present`=1 , `filepath` = '".string2sql($soundspath.$folder."/".$name_complete)."' , `lastmodified` = '0000-00-00 00:00:00'  WHERE `id`=".$ret[0]["id"];
            $res=$db->Execute($qry);
            if($res===false) $error++;
            continue;  
          }
        }
        // insert data in cw_sounds_files
        $qry="INSERT INTO `cw_sounds_file` ( `id` , `name` , `category` , `language` , `filepath` , `present` , `text` , `lastmodified` ) ";
        $qry.="VALUES (NULL , '".string2sql($filename)."', '".string2sql($category_id)."', '".string2sql($lang)."', '".string2sql($soundspath.$folder."/".$name_complete)."', '1', '', '0000-00-00 00:00:00');";
        $res=$db->Execute($qry);
        if($res===false) $error++;
      }
    } 
  }
  if($error!=0) return 0;
  // delete not present file
  $qry="DELETE FROM `cw_sounds_file` WHERE `present`=0 ";
  $res=$db->Execute($qry);
  if($res===false) return 0;
  else return 1;
}
/**
 * Return sounds
 *
 */
function getSound($id){
  global $db;
  if(($id!=0)and($id!="")) $condition="WHERE id=$id"; else $condition="";
  // retrieve audio file
  $qry="SELECT * FROM cw_sounds_file $condition";
  $res=$db->Execute($qry);
  while($arr=$res->FetchRow()) {
    $ret[]=$arr;
  }
  return $ret;
}
/**
 * Return name, category and filepath of the audio file with name==$filename and 
 * language==$lang (if $filename=="" function will return all file, if $lang=="" 
 * language will be setted to "default", if $cat_id==0 function will return all category
 *
 * @param string $filename the name of the file
 * @param int $cat_id the id of the file's category
 * @param string $lang the language of the file
 * @return array $ret tns:soundsFileArray with file's properties
 * @see soundsInit
 * @see getLanguages
 * @see getCatidByCatname
 * @see putTempSound
 * @see deleteTempSound
 * @see modifySound
 */
function getSoundDesc($filename, $cat_id, $language) {
  global $db;
  $ret=array(); 
  // check language
  if($language=="") $language="default";
  // retrieve audio files
  $qry="SELECT file.id, file.name , file.category, cat.tag, cat.description , file.filepath, file.text, file.lastmodified ";  
  $qry.="FROM cw_sounds_file file INNER JOIN cw_sounds_category cat ON file.category=cat.id ";
  $qry.="WHERE file.language LIKE '".string2sql($language)."' ";
  if($cat_id!=0) $qry.="AND file.category = ".string2sql($cat_id)." ";
  if($filename!="") $qry.="AND file.name LIKE '".string2sql($filename)."' ";  
  $qry.="ORDER BY cat.description ASC , file.name ASC";
  $res=$db->Execute($qry);
  $i=0;
  while($arr=$res->FetchRow()) {
    $ret[$i]["id"]=$arr["id"];
    $ret[$i]["name"]=$arr["name"];
    $ret[$i]["cat_id"]=$arr["category"];
    $ret[$i]["cat_tag"]=$arr["tag"];
    $ret[$i]["category"]=$arr["description"];
    $ret[$i]["filepath"]=$arr["filepath"];
    $ret[$i]["text"]=$arr["text"];
    $ret[$i]["lastmodified"]=$arr["lastmodified"];
    $i++;
  }
  return $ret;
}
/**
 * Return arrey of languages
 *
 * @param null
 * @return array $ret tns:stringArray with languages list
 * @see soundsInit
 * @see getSoundDesc
 * @see getCatidByCatname
 * @see putTempSound
 * @see deleteTempSound
 * @see modifySound
 */
function getLanguages(){
  global $db;
  $ret=array();
  // retrieve languages
  $qry="SELECT DISTINCT language FROM cw_sounds_file WHERE language<>'default'";
  $res=$db->Execute($qry);
  while($arr=$res->FetchRow()) $ret[]=$arr["language"];
  return $ret;
}
/**
 * Return category id
 *
 * @param string $tag the tag name of the category
 * @return int $ret the category id (0 for error)
 * @see soundsInit
 * @see getSoundDesc
 * @see getLanguages
 * @see putTempSound
 * @see deleteTempSound
 * @see modifySound
 */
function getCatidByTagname($tag){
  global $db;
  // retrieve cat_id
  $qry="SELECT id FROM cw_sounds_category WHERE tag='".string2sql($tag)."'";
  $res=$db->Execute($qry);
  $count=0;
  while($arr=$res->FetchRow()){
    $ret=$arr["id"];
    $count++;
  }
  if($count==1) return $ret;
  else return 0; 
}
/**
 * Put a tmp file in cw_sounds_file
 *
 * @param string $filename the name of the file
 * @return int $ret 1 if ok, 0 if not
 * @see soundsInit
 * @see getSoundDesc
 * @see getLanguages
 * @see getCatidByCatname
 * @see deleteTempSound
 * @see modifySound
 */
function putTempSound($filename) {
  global $db, $voTools;
  // check parameters
  if($filename=="") return 0;
  // insert audio files
  exec("sudo $voTools getSoundsDir",$output,$retScript);
  if(count($output)!=1) return 0;
  $soundspath=$output[0];
  $tmp_path=$soundspath."/voiceone/tmp/".$filename.".gsm";
  $tmp_id=getCatidByTagname("tmp");
  $date=date("Y-m-d H:i:s");
  $qry="INSERT INTO `cw_sounds_file` ( `id` , `name` , `category` , `language` , `filepath` , `present` , `text` , `lastmodified` ) ";
  $qry.="VALUES (NULL , '".string2sql($filename)."', '".string2sql($tmp_id)."', 'default', '".string2sql($tmp_path)."', '1', '', '".$date."');";
  $res=$db->Execute($qry);
  if($res===false) return 0;
  else return 1;
}
/**
 * Delete a tmp file in cw_sounds_file
 *
 * @param string $filename the name of the file
 * @return int $ret 1 if ok, 0 if not
 * @see soundsInit
 * @see getSoundDesc
 * @see getLanguages
 * @see getCatidByCatname
 * @see putTempSound
 * @see modifySound
 */
function deleteTempSound($filename) {
  global $db;
  // check parameters
  if($filename=="") return 0;
  // delete audio files
  $tmp_id=getCatidByTagname("tmp");
  $qry="DELETE FROM `cw_sounds_file` WHERE `name`='".string2sql($filename)."' AND `category`=".string2sql($tmp_id)." AND `language`='default'";
  $res=$db->Execute($qry);
  if($res===false) return 0;
  else return 1;
}
/**
 * Modify sound file in cw_sounds_file
 *
 * @param string $filename the name of the file
 * @param int $cat_id the id of the file's category
 * @param string $lang the language of the file
 * @param string $newcontent new audio message  
 * @param string $newtext new message text
 * @return int $ret 1 if ok, 0 if not
 * @see soundsInit
 * @see getSoundDesc
 * @see getLanguages
 * @see getCatidByCatname
 * @see putTempSound
 * @see deleteTempSound
 */
function modifySound($filename, $cat_id, $language, $newcontent, $modtext, $newtext) {
  global $db, $voTools;
  // check parameters
  if(($filename=="")||($cat_id==0)||($language=="")||(($newcontent=="")&&($newtext=="")&&($modtext==0))) return 0;
  // change audio content
  if($newcontent!=""){
    // extract frompath
    $tmp_id=getCatidByTagname("tmp");
    $newfile=getSoundDesc($newcontent, $tmp_id, "default"); 
    if((is_array($newfile))&&(count($newfile)==1)){
      $frompath=addslashes($newfile[0]["filepath"]);
    }else return 0;
    // extract topath
    $oldfile=getSoundDesc($filename, $cat_id, $language);
    if((is_array($oldfile))&&(count($oldfile)==1)){
      $topath=addslashes($oldfile[0]["filepath"]);
    }else return 0;
    // copy audio content from $frompath to $topath
    exec("sudo $voTools soundsCopy $frompath $topath",$output,$retScript); 
  }
  // change text field
  $newdate=date("Y-m-d H:i:s");
  if($modtext==1){
    $qry="UPDATE `cw_sounds_file` SET `text`='".string2sql($newtext)."' , `lastmodified`='".$newdate."' WHERE `name`='".string2sql($filename)."' AND `category`=".string2sql($cat_id)." AND `language`='".string2sql($language)."'";
    $res=$db->Execute($qry);
    if($res===false) return 0;
    else return 1;
  }
  //return
  return 1;
}
/**
 * Create a new empty file in "custom" or "IVR" category
 *
 * @param string $filename the name of the file
 * @param int $cat_id the id of the file's category
 * @param string $lang the language of the file
 * @return int $ret 1 if ok, 0 if not
 * @see soundsInit
 * @see getSoundDesc
 * @see getLanguages
 * @see getCatidByCatname
 * @see putTempSound
 * @see deleteTempSound
 * @see modifySound
 */
function createEmptyFile($filename, $cat_id, $language) {
  global $db, $voTools;
  // check parameters
  if(($filename=="")||($cat_id==0)||($language=="")) return 0;
  // check filename
  $files=getSoundDesc("", $cat_id, $language);
  foreach($files as $file){
    if($file["name"]==$filename) return 0;
  }
  // retrive category tag
  $qry="SELECT tag FROM cw_sounds_category WHERE id='".string2sql($cat_id)."'";
  $res=$db->Execute($qry);
  $count=0;
  while($arr=$res->FetchRow()){
    $cat_tag=$arr["tag"];
    $count++;
  }
  if($count!=1) return 0;
  // define file path
  $lang_folder="";
  if(strlen($language)==2) $lang_folder="/".$language;
  exec("sudo $voTools getSoundsDir",$output,$retScript);
  if(count($output)!=1) return 0;
  $soundspath=$output[0];
  if($cat_tag=="custom"){
    $folder_path=$soundspath.$lang_folder."/voiceone/custom/";
    $file_path=$folder_path.$filename.".gsm";
    $link_path=$soundspath."/en/voiceone/custom/".$filename.".gsm"; 
  }else if($cat_tag=="IVR"){
    $folder_path=$soundspath.$lang_folder."/voiceone/IVR/";
    $file_path=$folder_path.$filename.".gsm";
    $link_path=$soundspath."/en/voiceone/IVR/".$filename.".gsm";
  }else return 0;
  // write empty file
  exec("sudo $voTools soundsCreateEmptyFile $folder_path $filename",$output,$retScript);
  // insert audio file in db
  $qry="INSERT INTO `cw_sounds_file` ( `id` , `name` , `category` , `language` , `filepath` , `present` , `text` , `lastmodified` ) ";
  $qry.="VALUES (NULL , '".string2sql($filename)."', '".string2sql($cat_id)."', '".string2sql($language)."', '".string2sql($file_path)."', '1', '', '0000-00-00 00:00:00');";
  $res=$db->Execute($qry);
  if($res===false) return 0;
  // if new sound is not present in default language, write link to new sounds in default language
  if(trim($lang_folder)!=''){
    //check default language
    $def_files=getSoundDesc($filename, $cat_id, "en");
    if((!is_array($def_files))||(count($def_files)<1)){
      exec("sudo $voTools soundsCreateLinkFile $folder_path $file_path $link_path",$output,$retScript);
      $qry="INSERT INTO `cw_sounds_file` ( `id` , `name` , `category` , `language` , `filepath` , `present` , `text` , `lastmodified` ) ";
      $qry.="VALUES (NULL , '".string2sql($filename)."', '".string2sql($cat_id)."', '".string2sql('en')."', '".string2sql($link_path)."', '1', '', '0000-00-00 00:00:00');";
      $res=$db->Execute($qry);
      if($res===false) return 0;
    }
  }
  //return
  return 1;
}
/**
 * Delete a file in cw_sounds_file
 *
 * @param string $filename the name of the file
 * @param int $cat_id the id of the file's category
 * @param string $lang the language of the file
 * @return int $ret 1 if ok, 0 if not
 * @see soundsInit
 * @see getSoundDesc
 * @see getLanguages
 * @see getCatidByCatname
 * @see putTempSound
 * @see modifySound
 */
function deleteFile($filename, $cat_id, $language) {
  global $db, $voTools;
  // check parameters
  if(($filename=="")||($cat_id==0)||($language=="")) return 0;
  // check category tag
  $qry="SELECT tag FROM cw_sounds_category WHERE id='".string2sql($cat_id)."'";
  $res=$db->Execute($qry);
  $count=0;
  while($arr=$res->FetchRow()){
    $cat_tag=$arr["tag"];
    $count++;
  }
  if(($count!=1)||(($cat_tag!="custom")&&($cat_tag!="IVR"))) return 0;
  // retrieve file path
  $files=getSoundDesc($filename, $cat_id, $language);
  if(count($files)!=1) return 0;
  $file_path=$files[0]["filepath"];
  // delete audio file from db
  $qry="DELETE FROM `cw_sounds_file` WHERE `name`='".string2sql($filename)."' AND `category`=".string2sql($cat_id)." AND `language`='".string2sql($language)."'";
  $res=$db->Execute($qry);
  if($res===false) return 0;
  // delete file from FS
  exec("sudo $voTools soundsClear $file_path",$output,$retScript);
  return 1;
}
/**
 * Return arrey of categories
 *
 * @param null
 * @return array $ret tns:stringArray with category list
 * @see soundsInit
 * @see getSoundDesc
 * @see getCatidByCatname
 * @see putTempSound
 * @see deleteTempSound
 * @see modifySound
 */
function getCategories() {
  global $db;
  // retrieve languages
  $qry="SELECT * FROM cw_sounds_category";
  $res=$db->Execute($qry);
  $i=0;
  while($arr=$res->FetchRow()){
    $ret[$i]["id"]=$arr["id"];
    $ret[$i]["tag"]=$arr["tag"];
    $ret[$i]["description"]=$arr["description"];
    $i++;
  }
  return $ret;
}
//============================================================================//
//======================== PLAY - RECORD - UPLOAD ============================//
//============================================================================//
/**
 * Check if a audio file is in voiceone_ws's sandbox. If not, it copies it in sandbox 
 *
 * @param int $cat_id file category id
 * @param string $filename name to check
 * @param string $lang file language
 * @return int $ret 1 if message is present, 0 if not
 * @see recordNewMessage
 * @see deleteRecordedMessage
 * @see uploadMessage
 */
function mvSoundsFileToSandbox($cat_id, $filename, $language) {
  global $db, $voTools, $voiceoneWSDocumentRoot;
  // clean sandbox/sounds
  $topath=$voiceoneWSDocumentRoot."/sandbox/sounds";
  $audioList=glob($topath."/*.wav");
  foreach($audioList as $file){
    exec("sudo $voTools soundsClear $file",$output,$retScript);
  } 
  // find filepath
  $res=getSoundDesc($filename, $cat_id, $language);
  if(is_array($res)){
    if(count($res)==1){
      $frompath=addslashes($res[0]["filepath"]);
      $filemoved=$topath."/".addslashes($filename).".wav";
    } else return 0;
  } else return 0; 
  // move file
  exec("sudo $voTools soundsMoveToSandbox $frompath $topath $filemoved",$output,$retScript); 
  // verify and return
  if(file_exists($topath."/".$filename.".wav"))  return 1;
  else return 0;
}
/**
 * Record a new message with floAPI and put it in ~/sounds/voiceone/tmp
 *
 * @param string $clientId user id
 * @param string $filename message name 
 * @return int $ret 1 if ok, 0 if not
 * @see mvSoundsFileToSandbox
 * @see deleteRecordedMessage
 * @see uploadMessage
 */
function recordNewMessage($clientId, $filename) {
  global $voTools,$floapi,$API_user,$API_pass,$API_host;
  $ret=getApplicationByName("audiorecorder");
  $AUDIO_RECORDER_APPLICATION=$ret[0]["id"];
  //retrieve some information from db
  $channelArr=getChannel(getChannelFromEntity($clientId));
  $channelName=$channelArr[0]["name"];
  $clientArr=getClient($clientId,0);
  $client=$clientArr[0];
  $ruleId=$client["rule"];
  $ruleArr=getRule($ruleId);
  $ruleName=$ruleArr[0]["name"];
  $applicationArr=getApplication($AUDIO_RECORDER_APPLICATION);
  $application=$applicationArr[0];
  $appExtension=$application["extension"];
  //originate the call and save audio message in var/lib/asterisk/sounds/voiceone/voicemail
  $entry=array('Channel'=>$channelName,'Exten'=>$appExtension,'Context'=>$ruleName,'Priority'=>1,'Callerid'=>"Sounds Audio Recorder <$filename>");
  $floapi = new floAPI($API_user, $API_pass, $API_host);
  if ($floapi->socket!="") {
    $ret=$floapi->request("Originate", $entry);
    $floapi->close();
  }
  else return 0;
  return 1;
}
/**
 * Delete message in ~/sounds/voiceone/tmp
 *
 * @param string $filename message name 
 * @return int $ret 1 if ok, 0 if not
 * @see mvSoundsFileToSandbox
 * @see recordNewMessage
 * @see uploadMessage
 */
function deleteRecordedMessage($filename) {
  global $voTools;
  // build filepath
  exec("sudo $voTools getSoundsDir",$output,$retScript);
  if(count($output)!=1) return 0;
  $soundspath=$output[0];
  $filepath=$soundspath."/voiceone/tmp/".$filename.".gsm";
  // delete
  exec("sudo $voTools soundsClear $filepath",$output,$retScript);
  return 1;
}
/**
 * Upload an audio file to asterisk/sounds/voiceone/tmp folder.
 *
 * @param string $file_name the name of the audio file
 * @param base64Binary $file_content audio file's binary stream
 * @return array $ret xsd:int 1 if ok, 0 if not
 * @see mvSoundsFileToSandbox
 * @see recordNewMessage
 * @see deleteRecordedMessage
 */
function uploadMessage($file_name, $file_content) {
  global $voTools, $voiceoneWSDocumentRoot;
  $filepath=$voiceoneWSDocumentRoot."/sandbox/";
  $file_ext=substr($file_name, -4);
  $file_temp_name = "tempFile".$file_ext;
  $file_name=substr($file_name, 0, -4).".gsm";
  // if web service is emulated the file_content have to be decoded
  if($soapWrapper===true){
    $file_content=base64_decode($file_content);
  }
  // open file, if file doesn't exist crete it 
  $filehandle = fopen($filepath.$file_temp_name, 'w');
  // write temp file
  if(fwrite($filehandle, $file_content)>0){
    if(fclose($filehandle)===true) {
      // move file to moh folder
      $frompath=$filepath.$file_temp_name;
      exec("sudo $voTools soundsMoveToSounds $frompath $file_name",$output,$retScript);
      if(@unlink($filepath.$file_temp_name)===false) return 0;
      else return 1;
    }
    else return 0;
  }
  else {
    fclose($filehandle);
    return 0;
  }
}
?>