From d2ff71ed6b1a039618f65d885a725024c39fb7f3 Mon Sep 17 00:00:00 2001 From: FusionPBX Date: Fri, 9 Jan 2026 20:27:27 -0700 Subject: [PATCH] Update XML handling --- app/dialplans/dialplan_xml.php | 142 +++++++++++++++++++++++---------- 1 file changed, 98 insertions(+), 44 deletions(-) diff --git a/app/dialplans/dialplan_xml.php b/app/dialplans/dialplan_xml.php index 94772393e9..b2f466b4ad 100644 --- a/app/dialplans/dialplan_xml.php +++ b/app/dialplans/dialplan_xml.php @@ -17,7 +17,7 @@ The Initial Developer of the Original Code is Mark J Crane - Portions created by the Initial Developer are Copyright (C) 2008-2024 + Portions created by the Initial Developer are Copyright (C) 2008-2026 the Initial Developer. All Rights Reserved. Contributor(s): @@ -35,6 +35,10 @@ exit; } +//get and the domain_uuid from the PHP session + $domain_uuid = $_SESSION['domain_uuid']; + $domain_name = $_SESSION['domain_name']; + //get the uuids if (!empty($_REQUEST['id']) && is_uuid($_REQUEST['id'])) { $dialplan_uuid = $_REQUEST['id']; @@ -45,7 +49,7 @@ $dialplan_xml = $_REQUEST['dialplan_xml'] ?? ''; //process the HTTP POST - if (count($_POST) > 0 && empty($_POST["persistformvar"])) { + if (!empty($_POST) && !empty($dialplan_uuid) && !empty($_REQUEST['app_uuid']) && !empty($_REQUEST['app_uuid'])) { //validate the token $token = new token; @@ -55,7 +59,7 @@ exit; } - //get the dialplan xml + //get the dialplan XML if (is_uuid($dialplan_uuid)) { $sql = "select * from v_dialplans "; $sql .= "where dialplan_uuid = :dialplan_uuid "; @@ -68,7 +72,7 @@ unset($sql, $parameters, $row); } - //validate the xml + //sanitize the xml $dialplan_valid = true; if (preg_match("/.*([\"\'])system([\"\']).*>/i", $dialplan_xml)) { $dialplan_valid = false; @@ -101,15 +105,15 @@ $dialplan_valid = false; } - //disable xml entities and load the xml object to test if the xml is valid - if (PHP_VERSION_ID < 80000) { libxml_disable_entity_loader(true); } - preg_match_all('/^\s*(?:[\S\s])+<\/extension>\s*$/mU', $dialplan_xml, $matches); - foreach($matches as $match) { - $xml = simplexml_load_string($match[0], 'SimpleXMLElement', LIBXML_NOCDATA); - if (!$xml) { - //$errors = libxml_get_errors(); - $dialplan_valid = false; - break; + //disable XML entities and load the XML object to test if the XML is valid + if ($dialplan_valid) { + preg_match_all('/^\s*(?:[\S\s])+<\/extension>\s*$/mU', $dialplan_xml, $matches); + foreach($matches as $match) { + if (valid_xml($xml)) { + //$errors = libxml_get_errors(); + $dialplan_valid = false; + break; + } } } @@ -117,7 +121,6 @@ if ($dialplan_valid) { //build the dialplan array $x = 0; - //$array['dialplans'][$x]["domain_uuid"] = $_SESSION['domain_uuid']; $array['dialplans'][$x]["dialplan_uuid"] = $dialplan_uuid; $array['dialplans'][$x]["dialplan_xml"] = $dialplan_xml; @@ -146,14 +149,20 @@ } -//get the dialplan xml +//get a specific dialplan using the dialplan_uuid if (is_uuid($dialplan_uuid)) { - $sql = "select * from v_dialplans "; + $sql = "select domain_uuid, app_uuid, dialplan_name, "; + $sql .= "dialplan_number, dialplan_order, dialplan_continue, "; + $sql .= "dialplan_xml, dialplan_enabled, dialplan_description "; + $sql .= "from v_dialplans "; $sql .= "where dialplan_uuid = :dialplan_uuid "; + $sql .= "and (domain_uuid = :domain_uuid or domain_uuid is null) "; $parameters['dialplan_uuid'] = $dialplan_uuid; + $parameters['domain_uuid'] = $domain_uuid; $row = $database->select($sql, $parameters, 'row'); if (is_array($row) && @sizeof($row) != 0) { $domain_uuid = $row["domain_uuid"]; + $app_uuid = $row["app_uuid"]; $dialplan_name = $row["dialplan_name"]; $dialplan_number = $row["dialplan_number"]; $dialplan_order = $row["dialplan_order"]; @@ -166,6 +175,41 @@ unset($sql, $parameters, $row); } +//get all dialplans for a specific domain with global dialplans + if (empty($dialplan_uuid) && is_uuid($domain_uuid)) { + $sql = "select dialplan_xml from v_dialplans "; + $sql .= "where (domain_uuid = :domain_uuid or domain_uuid is null) "; + $sql .= "and dialplan_enabled = true "; + $sql .= "order by dialplan_order asc, lower(dialplan_name) asc "; + $parameters['domain_uuid'] = $domain_uuid; + $dialplans = $database->select($sql, $parameters, 'all'); + } + +//get all dialplans for a specific domain + if (empty($dialplan_uuid)) { + $dialplan_xml = "\n"; + $dialplan_xml .= "\n"; + $dialplan_xml .= "
\n"; + $dialplan_xml .= " \n"; + if (!empty($dialplans)) { + foreach($dialplans as $row) { + foreach (explode("\n", mb_convert_encoding($row["dialplan_xml"], 'UTF-8')) as $line) { + $dialplan_xml .= "\t\t\t".$line."\n"; + } + } + } + unset($sql, $parameters, $row); + $dialplan_xml .= " \n"; + $dialplan_xml .= "
\n"; + $dialplan_xml .= "
\n"; + } + +//validate the XML + //list($xml_valid, $xml_errors) = xml::valid($dialplan_xml); + +//convert the line to UTF-8 + //$dialplan_xml = mb_convert_encoding($dialplan_xml, 'UTF-8'); + //add multi-lingual support $language = new text; $text = $language->get(); @@ -177,6 +221,14 @@ $setting_indenting = $settings->get('editor', 'indent_guides', 'false'); $setting_numbering = $settings->get('editor', 'line_numbers', 'true'); +//set the button back link + if (is_array($dialplan_uuid)) { + $button_back_link = 'dialplan_edit.php?id='.urlencode($dialplan_uuid).(!empty($app_uuid) && is_uuid($app_uuid) ? "&app_uuid=".urlencode($app_uuid) : null); + } + else { + $button_back_link = 'dialplans.php'; + } + //create token $object = new token; $token = $object->create($_SERVER['PHP_SELF']); @@ -213,14 +265,14 @@ echo " editor.focus();\n"; echo " }\n"; - //copy the value from the editor on submit + //Copy the value from the editor on submit echo " function set_value() {\n"; - echo " $('#dialplan_xml').val(editor.session.getValue());\n"; + echo " document.getElementById('dialplan_xml').value = editor.session.getValue();\n"; echo " }\n"; //load editor value from hidden textarea echo " function load_value() {\n"; - echo " editor.session.setValue($('#dialplan_xml').val());"; + echo " editor.session.setValue(document.getElementById('dialplan_xml').value);"; echo " }\n"; echo "\n"; @@ -241,8 +293,10 @@ echo "
\n"; echo "
".$text['title-dialplan_edit']." XML
\n"; echo "
\n"; - echo button::create(['type'=>'button','label'=>$text['button-back'],'icon'=>$settings->get('theme', 'button_icon_back'),'id'=>'btn_back','link'=>'dialplan_edit.php?id='.urlencode($dialplan_uuid).(!empty($app_uuid) && is_uuid($app_uuid) ? "&app_uuid=".urlencode($app_uuid) : null)]); - echo button::create(['type'=>'button','label'=>$text['button-save'],'icon'=>$settings->get('theme', 'button_icon_save'),'id'=>'btn_save','style'=>'margin-left: 15px;','onclick'=>"set_value(); $('#frm').submit();"]); + echo button::create(['type'=>'button','label'=>$text['button-back'],'icon'=>$settings->get('theme', 'button_icon_back'),'id'=>'btn_back','link'=>$button_back_link]); + if (is_uuid($dialplan_uuid)) { + echo button::create(['type'=>'button','label'=>$text['button-save'],'icon'=>$settings->get('theme', 'button_icon_save'),'id'=>'btn_save','style'=>'margin-left: 15px;','onclick'=>"set_value(); $('#frm').submit();"]); + } echo "
\n"; echo "
\n"; echo "
\n"; @@ -337,36 +391,36 @@ echo "\n"; //show the footer require_once "resources/footer.php"; -?> \ No newline at end of file +?>