Portions created by the Initial Developer are Copyright (C) 2008-2019 the Initial Developer. All Rights Reserved. Contributor(s): Mark J Crane */ //define the directory class if (!class_exists('extension')) { class extension { /** * declare public variables */ public $domain_uuid; public $domain_name; public $extension_uuid; public $extension; public $voicemail_id; public $number_alias; public $password; public $provisioning_list; public $voicemail_password; public $accountcode; public $effective_caller_id_name; public $effective_caller_id_number; public $outbound_caller_id_name; public $outbound_caller_id_number; public $emergency_caller_id_name; public $emergency_caller_id_number; public $directory_full_name; public $directory_visible; public $directory_exten_visible; public $limit_max; public $limit_destination; public $voicemail_enabled; public $voicemail_mail_to; public $voicemail_file; public $voicemail_local_after_email; public $user_context; public $toll_allow; public $call_timeout; public $call_group; public $hold_music; public $auth_acl; public $cidr; public $sip_force_contact; public $sip_force_expires; public $nibble_account; public $mwi_account; public $sip_bypass_media; public $absolute_codec_string; public $dial_string; public $enabled; public $description; public $delete_voicemail; /** * declare private variables */ private $app_name; private $app_uuid; private $permission_prefix; private $list_page; private $table; private $uuid_prefix; private $toggle_field; private $toggle_values; /** * called when the object is created */ public function __construct() { //assign private variables $this->app_name = 'extensions'; $this->app_uuid = 'e68d9689-2769-e013-28fa-6214bf47fca3'; $this->permission_prefix = 'extension_'; $this->list_page = 'extensions.php'; $this->table = 'extensions'; $this->uuid_prefix = 'extension_'; $this->toggle_field = 'enabled'; $this->toggle_values = ['true','false']; } public function exists($domain_uuid, $extension) { $sql = "select count(*) from v_extensions "; $sql .= "where domain_uuid = :domain_uuid "; $sql .= "and ( "; $sql .= "extension = :extension "; $sql .= "or number_alias = :extension "; $sql .= ") "; $sql .= "and enabled = 'true' "; $parameters['domain_uuid'] = $domain_uuid; $parameters['extension'] = $extension; $database = new database; return $database->select($sql, $parameters, 'column') != 0 ? true : false; unset($sql, $parameters); } public function get_domain_uuid() { return $this->domain_uuid; } public function set_domain_uuid($domain_uuid){ $this->domain_uuid = $domain_uuid; } public function voicemail() { //determine the voicemail_id if (is_numeric($this->number_alias)) { $this->voicemail_id = $this->number_alias; } else { $this->voicemail_id = $this->extension; } //insert or update the voicemail settings $sql = "select voicemail_uuid from v_voicemails "; $sql .= "where domain_uuid = :domain_uuid "; $sql .= "and voicemail_id = :voicemail_id "; $parameters['domain_uuid'] = $this->domain_uuid; $parameters['voicemail_id'] = $this->voicemail_id; $database = new database; $voicemail_uuid = $database->select($sql, $parameters, 'column'); unset($sql, $parameters); if (is_uuid($voicemail_uuid)) { //build update array $array['voicemails'][0]['voicemail_uuid'] = $voicemail_uuid; //grant temporary permissions $p = new permissions; $p->add('voicemail_edit', 'temp'); } else { //build insert array $array['voicemails'][0]['voicemail_uuid'] = uuid(); $array['voicemails'][0]['domain_uuid'] = $this->domain_uuid; //grant temporary permissions $p = new permissions; $p->add('voicemail_add', 'temp'); } if (is_array($array) && @sizeof($array) != 0) { //include common array fields $array['voicemails'][0]['voicemail_id'] = $this->voicemail_id; $array['voicemails'][0]['voicemail_password'] = $this->voicemail_password; $array['voicemails'][0]['voicemail_mail_to'] = $this->voicemail_mail_to; $array['voicemails'][0]['voicemail_file'] = $this->voicemail_file; $array['voicemails'][0]['voicemail_local_after_email'] = $this->voicemail_local_after_email; $array['voicemails'][0]['voicemail_enabled'] = $this->voicemail_enabled; $array['voicemails'][0]['voicemail_description'] = $this->description; //execute insert/update $database = new database; $database->app_name = 'extensions'; $database->app_uuid = 'e68d9689-2769-e013-28fa-6214bf47fca3'; $database->save($array); unset($array); //revoke temporary permissions $p->delete('voicemail_edit', 'temp'); $p->delete('voicemail_add', 'temp'); } unset($voicemail_uuid); } public function xml() { if (isset($_SESSION['switch']['extensions']['dir'])) { //declare global variables global $config, $domain_uuid; //get the domain_name $domain_name = $_SESSION['domains'][$domain_uuid]['domain_name']; $user_context = $domain_name; //delete all old extensions to prepare for new ones $dialplan_list = glob($_SESSION['switch']['extensions']['dir']."/".$user_context."/v_*.xml"); foreach($dialplan_list as $name => $value) { unlink($value); } //write the xml files $sql = "select * from v_extensions as e, v_voicemails as v "; $sql .= "where e.domain_uuid = :domain_uuid "; $sql .= "and coalesce(nullif(e.number_alias,''),e.extension) = cast(v.voicemail_id as varchar) "; $sql .= "order by e.call_group asc "; $parameters['domain_uuid'] = $domain_uuid; $database = new database; $rows = $database->select($sql, $parameters, 'all'); unset($sql, $parameters); $extension_xml_condensed = false; if (is_array($rows) && @sizeof($rows) != 0) { foreach ($rows as $row) { $call_group = $row['call_group']; $call_group = str_replace(";", ",", $call_group); $tmp_array = explode(",", $call_group); foreach ($tmp_array as &$tmp_call_group) { $tmp_call_group = trim($tmp_call_group); if (!empty($tmp_call_group)) { if (empty($call_group_array[$tmp_call_group])) { $call_group_array[$tmp_call_group] = $row['extension']; } else { $call_group_array[$tmp_call_group] = $call_group_array[$tmp_call_group].','.$row['extension']; } } } $call_timeout = $row['call_timeout']; $user_context = $row['user_context']; $password = $row['password']; $voicemail_password = $row['voicemail_password']; //$voicemail_password = str_replace("#", "", $voicemail_password); //preserves leading zeros //echo "enabled: ".$row['enabled']; if ($row['enabled'] != "false") { $extension_uuid = $row['extension_uuid']; //remove invalid characters from the file names $extension = $row['extension']; $extension = str_replace(" ", "_", $extension); $extension = preg_replace("/[\*\:\\/\<\>\|\'\"\?]/", "", $extension); $dial_string = $row['dial_string']; if (empty($dial_string)) { if (!empty($_SESSION['domain']['dial_string']['text'])) { $dial_string = $_SESSION['domain']['dial_string']['text']; } else { $dial_string = "{sip_invite_domain=\${domain_name},leg_timeout=".$call_timeout.",presence_id=\${dialed_user}@\${dialed_domain}}\${sofia_contact(\${dialed_user}@\${dialed_domain})}"; } } //set the password hashes $a1_hash = md5($extension.":".$domain_name.":".$password); $vm_a1_hash = md5($extension.":".$domain_name.":".$voicemail_password); $xml .= "\n"; $cidr = ''; if (!empty($row['cidr'])) { $cidr = " cidr=\"" . $row['cidr'] . "\""; } $number_alias = ''; if (!empty($row['number_alias'])) { $number_alias = " number-alias=\"".$row['number_alias']."\""; } $xml .= " \n"; $xml .= " \n"; //$xml .= " \n"; $xml .= " \n"; $xml .= " \n"; $xml .= " \n"; //voicemail settings //$xml .= " \n"; $xml .= " \n"; switch ($row['voicemail_enabled']) { case "true": $xml .= " \n"; break; case "false": $xml .= " \n"; break; default: $xml .= " \n"; } if (!empty($row['voicemail_mail_to'])) { $xml .= " \n"; switch ($row['voicemail_file']) { case "attach": $xml .= " \n"; break; default: $xml .= " \n"; } switch ($row['voicemail_local_after_email']) { case "true": $xml .= " \n"; break; case "false": $xml .= " \n"; break; default: $xml .= " \n"; } $xml .= " \n"; } if (!empty($row['mwi_account'])) { $xml .= " \n"; } if (!empty($row['auth_acl'])) { $xml .= " \n"; } if (!empty($row['directory_exten_visible'])) { $xml .= " \n"; } $xml .= " \n"; $xml .= " \n"; $xml .= " \n"; $xml .= " \n"; $xml .= " \n"; $xml .= " \n"; if (!empty($row['call_group'])) { $xml .= " \n"; } if (!empty($row['user_record'])) { $xml .= " \n"; } if (!empty($row['hold_music'])) { $xml .= " \n"; } $xml .= " \n"; if (!empty($row['call_timeout'])) { $xml .= " \n"; } if (!empty($switch_account_code)) { $xml .= " \n"; } else { $xml .= " \n"; } $xml .= " \n"; if (!empty($row['effective_caller_id_name'])) { $xml .= " \n"; } if (!empty($row['effective_caller_id_number'])) { $xml .= " \n"; } if (!empty($row['outbound_caller_id_name'])) { $xml .= " \n"; } if (!empty($row['outbound_caller_id_number'])) { $xml .= " \n"; } if (!empty($row['emergency_caller_id_name'])) { $xml .= " \n"; } if (!empty($row['emergency_caller_id_number'])) { $xml .= " \n"; } if (!empty($row['directory_full_name'])) { $xml .= " \n"; } if (!empty($row['directory_visible'])) { $xml .= " \n"; } if (!empty($row['limit_max'])) { $xml .= " \n"; } else { $xml .= " \n"; } if (!empty($row['limit_destination'])) { $xml .= " \n"; } if (!empty($row['sip_force_contact'])) { $xml .= " \n"; } if (!empty($row['sip_force_expires'])) { $xml .= " \n"; } if (!empty($row['nibble_account'])) { $xml .= " \n"; } switch ($row['sip_bypass_media']) { case "bypass-media": $xml .= " \n"; break; case "bypass-media-after-bridge": $xml .= " \n"; break; case "proxy-media": $xml .= " \n"; break; } if (!empty($row['absolute_codec_string'])) { $xml .= " \n"; } if (!empty($row['forward_all_enabled'])) { $xml .= " \n"; } if (!empty($row['forward_all_destination'])) { $xml .= " \n"; } if (!empty($row['forward_busy_enabled'])) { $xml .= " \n"; } if (!empty($row['forward_busy_destination'])) { $xml .= " \n"; } if (!empty($row['forward_no_answer_enabled'])) { $xml .= " \n"; } if (!empty($row['forward_no_answer_destination'])) { $xml .= " \n"; } if (!empty($row['forward_user_not_registered_enabled'])) { $xml .= " \n"; } if (!empty($row['forward_user_not_registered_destination'])) { $xml .= " \n"; } if (!empty($row['do_not_disturb'])) { $xml .= " \n"; } $xml .= " \n"; $xml .= " \n"; if (!is_readable($_SESSION['switch']['extensions']['dir']."/".$row['user_context'])) { mkdir($_SESSION['switch']['extensions']['dir']."/".$row['user_context'], 0770, false); } if (!empty($extension)) { $fout = fopen($_SESSION['switch']['extensions']['dir']."/".$row['user_context']."/v_".$extension.".xml","w"); } $xml .= "\n"; fwrite($fout, $xml); unset($xml); fclose($fout); } } } unset($rows, $row); //prepare extension $extension_dir = realpath($_SESSION['switch']['extensions']['dir']); $user_context = str_replace(" ", "_", $user_context); $user_context = preg_replace("/[\*\:\\/\<\>\|\'\"\?]/", "", $user_context); //define the group members $xml = "\n"; $xml .= "\n"; $xml .= "\n"; $xml .= " \n"; if ($user_context == "default") { $xml .= " \n"; } else { $xml .= " \n"; } $xml .= " \n"; //$xml .= " \n"; $xml .= " \n"; $xml .= "\n"; $xml .= " \n"; $xml .= " \n"; $xml .= " \n"; $xml .= " \n"; $xml .= " \n"; $xml .= " \n"; $xml .= " \n"; $xml .= "\n"; $xml .= " \n"; $xml .= " \n"; $xml .= " \n"; $xml .= " \n"; $xml .= " \n"; $xml .= " \n"; $xml .= "\n"; $previous_call_group = ""; foreach ($call_group_array as $key => $value) { $call_group = trim($key); $extension_list = trim($value); if (!empty($call_group)) { if ($previous_call_group != $call_group) { $xml .= " \n"; $xml .= " \n"; $xml .= " \n"; $extension_array = explode(",", $extension_list); foreach ($extension_array as &$tmp_extension) { $xml .= " \n"; } $xml .= " \n"; $xml .= " \n"; $xml .= "\n"; } $previous_call_group = $call_group; } unset($call_group); } $xml .= " \n"; $xml .= "\n"; $xml .= " \n"; $xml .= ""; //write the xml file if (is_readable($extension_dir) && !empty($extension_dir)) { $fout = fopen($extension_dir."/".$user_context.".xml","w"); fwrite($fout, $xml); unset($xml); fclose($fout); } //apply settings $_SESSION["reload_xml"] = true; } } /** * delete records */ public function delete($records) { if (permission_exists($this->permission_prefix.'delete')) { //add multi-lingual support $language = new text; $text = $language->get(); //validate the token $token = new token; if (!$token->validate($_SERVER['PHP_SELF'])) { message::add($text['message-invalid_token'],'negative'); header('Location: '.$this->list_page); exit; } //delete multiple records if (is_array($records) && @sizeof($records) != 0) { //build the delete array $y = @sizeof($records) + 1; foreach ($records as $x => $record) { if ($record['checked'] == 'true' && is_uuid($record['uuid'])) { //get the extension details $sql = "select extension, number_alias, user_context, follow_me_uuid from v_extensions "; $sql .= "where domain_uuid = :domain_uuid "; $sql .= "and extension_uuid = :extension_uuid "; $parameters['domain_uuid'] = $_SESSION['domain_uuid']; $parameters['extension_uuid'] = $record['uuid']; $database = new database; $row = $database->select($sql, $parameters, 'row'); if (is_array($row) && @sizeof($row) != 0) { //for use below and to clear cache (bottom) $extensions[$x] = $row; //build delete array $array[$this->table][$x][$this->uuid_prefix.'uuid'] = $record['uuid']; $array['extension_users'][$x]['extension_uuid'] = $record['uuid']; //include follow me destinations, if exists if (is_uuid($extensions[$x]['follow_me_uuid'])) { $array['follow_me'][$x]['follow_me_uuid'] = $extensions[$x]['follow_me_uuid']; $array['follow_me_destinations'][$x]['follow_me_uuid'] = $extensions[$x]['follow_me_uuid']; } //include ring group destinations, if exists if (file_exists($_SERVER["PROJECT_ROOT"]."/app/ring_groups/app_config.php")) { $array['ring_group_destinations'][$x]['destination_number'] = $extensions[$x]['extension']; $array['ring_group_destinations'][$x]['domain_uuid'] = $_SESSION['domain_uuid']; if (is_numeric($extensions[$x]['number_alias'])) { $array['ring_group_destinations'][$y]['destination_number'] = $extensions[$x]['number_alias']; $array['ring_group_destinations'][$y]['domain_uuid'] = $_SESSION['domain_uuid']; } $y++; } //create array of voicemail ids if ($this->delete_voicemail && permission_exists('voicemail_delete')) { if (is_numeric($extensions[$x]['extension'])) { $voicemail_ids[] = $extensions[$x]['extension']; } if (is_numeric($extensions[$x]['number_alias'])) { $voicemail_ids[] = $extensions[$x]['number_alias']; } } } unset($sql, $parameters, $row); } } //delete the checked rows if (is_array($array) && @sizeof($array) != 0) { //delete extension voicemail boxes if ( $this->delete_voicemail && permission_exists('voicemail_delete') && is_array($voicemail_ids) && @sizeof($voicemail_ids) != 0 ) { //retrieve voicemail uuids $sql = "select voicemail_uuid as uuid from v_voicemails "; $sql .= "where domain_uuid = :domain_uuid "; $sql .= "and voicemail_id in ('".implode("','", $voicemail_ids)."') "; $parameters['domain_uuid'] = $_SESSION['domain_uuid']; $database = new database; $rows = $database->select($sql, $parameters, 'all'); if (is_array($rows) && @sizeof($rows) != 0) { foreach ($rows as $r => $row) { $voicemails[$r]['checked'] = 'true'; $voicemails[$r]['uuid'] = $row['uuid']; } } //delete voicemail boxes if (is_array($voicemails) && @sizeof($voicemails) != 0) { $obj = new voicemail; $obj->voicemail_delete($voicemails); } } //grant temporary permissions $p = new permissions; $p->add('extension_user_delete', 'temp'); $p->add('follow_me_delete', 'temp'); $p->add('follow_me_destination_delete', 'temp'); $p->add('ring_group_destination_delete', 'temp'); //execute delete $database = new database; $database->app_name = $this->app_name; $database->app_uuid = $this->app_uuid; $database->delete($array); unset($array); //revoke temporary permissions $p->delete('extension_user_delete', 'temp'); $p->delete('follow_me_delete', 'temp'); $p->delete('follow_me_destination_delete', 'temp'); $p->delete('ring_group_destination_delete', 'temp'); //clear the cache foreach ($extensions as $x => $extension) { $cache = new cache; $cache->delete("directory:".$extension['extension']."@".$extension['user_context']); if (permission_exists('number_alias') && !empty($extension['number_alias'])) { $cache->delete("directory:".$extension['number_alias']."@".$extension['user_context']); } } unset($extensions); //synchronize configuration if (is_writable($_SESSION['switch']['extensions']['dir'])) { $this->xml(); } //clear the destinations session array if (isset($_SESSION['destinations']['array'])) { unset($_SESSION['destinations']['array']); } //set message message::add($text['message-delete']); } unset($records); } } } /** * toggle records */ public function toggle($records) { if (permission_exists($this->permission_prefix.'enabled')) { //add multi-lingual support $language = new text; $text = $language->get(); //validate the token $token = new token; if (!$token->validate($_SERVER['PHP_SELF'])) { message::add($text['message-invalid_token'],'negative'); header('Location: '.$this->list_page); exit; } //toggle the checked records if (is_array($records) && @sizeof($records) != 0) { //get current toggle state foreach($records as $x => $record) { if ($record['checked'] == 'true' && is_uuid($record['uuid'])) { $uuids[] = "'".$record['uuid']."'"; } } if (is_array($uuids) && @sizeof($uuids) != 0) { $sql = "select ".$this->uuid_prefix."uuid as uuid, ".$this->toggle_field." as toggle, extension, number_alias, user_context from v_".$this->table." "; $sql .= "where domain_uuid = :domain_uuid "; $sql .= "and ".$this->uuid_prefix."uuid in (".implode(', ', $uuids).") "; $parameters['domain_uuid'] = $_SESSION['domain_uuid']; $database = new database; $rows = $database->select($sql, $parameters, 'all'); if (is_array($rows) && @sizeof($rows) != 0) { foreach ($rows as $row) { //for use below and to clear cache (bottom) $extensions[$row['uuid']]['state'] = $row['toggle']; $extensions[$row['uuid']]['extension'] = $row['extension']; $extensions[$row['uuid']]['number_alias'] = $row['number_alias']; $extensions[$row['uuid']]['user_context'] = $row['user_context']; } } unset($sql, $parameters, $rows, $row); } //build update array $x = 0; foreach($extensions as $uuid => $extension) { $array[$this->table][$x][$this->uuid_prefix.'uuid'] = $uuid; $array[$this->table][$x][$this->toggle_field] = $extension['state'] == $this->toggle_values[0] ? $this->toggle_values[1] : $this->toggle_values[0]; $x++; } //save the changes if (is_array($array) && @sizeof($array) != 0) { //grant temporary permissions $p = new permissions; $p->add('extension_edit', 'temp'); //save the array $database = new database; $database->app_name = $this->app_name; $database->app_uuid = $this->app_uuid; $database->save($array); unset($array); //revoke temporary permissions $p->delete('extension_edit', 'temp'); //synchronize configuration if (is_writable($_SESSION['switch']['extensions']['dir'])) { $this->xml(); } //write the provision files if (!empty($_SESSION['provision']['path']['text'])) { if (is_dir($_SERVER["DOCUMENT_ROOT"].PROJECT_PATH.'/app/provision')) { $prov = new provision; $prov->domain_uuid = $_SESSION['domain_uuid']; $response = $prov->write(); } } //clear the cache foreach ($extensions as $uuid => $extension) { $cache = new cache; $cache->delete("directory:".$extension['extension']."@".$extension['user_context']); if (permission_exists('number_alias') && !empty($extension['number_alias'])) { $cache->delete("directory:".$extension['number_alias']."@".$extension['user_context']); } } unset($extensions); //clear the destinations session array if (isset($_SESSION['destinations']['array'])) { unset($_SESSION['destinations']['array']); } //set message message::add($text['message-toggle']); } unset($records); } } } } } ?>