From e08b82c160fd71e0c230aac5f19d68ac05ebb989 Mon Sep 17 00:00:00 2001 From: FusionPBX Date: Mon, 12 Feb 2024 10:26:33 -0700 Subject: [PATCH] Bug fix for app/emergency logs --- app/emergency/app_config.php | 97 +++---- app/emergency/app_languages.php | 133 +++++++++ app/emergency/emergency.php | 32 ++- .../resources/scripts/app/emergency/index.lua | 263 ++++++++---------- 4 files changed, 318 insertions(+), 207 deletions(-) create mode 100644 app/emergency/app_languages.php diff --git a/app/emergency/app_config.php b/app/emergency/app_config.php index 53f7f09e0a..3ede60ab78 100644 --- a/app/emergency/app_config.php +++ b/app/emergency/app_config.php @@ -19,78 +19,67 @@ $apps[$x]['description']['pt-pt'] = ''; $apps[$x]['description']['pt-br'] = ''; - //permission details - $y=0; - $apps[$x]['permissions'][$y]['name'] = "emergency_logs_view"; - $apps[$x]['permissions'][$y]['groups'][] = "superadmin"; - $apps[$x]['permissions'][$y]['menu']['uuid'] = "23a6fc8a-77f1-11ee-88b0-005056a27559"; + //permission details + $y=0; + $apps[$x]['permissions'][$y]['name'] = "emergency_logs_view"; + $apps[$x]['permissions'][$y]['groups'][] = "superadmin"; + $apps[$x]['permissions'][$y]['menu']['uuid'] = "23a6fc8a-77f1-11ee-88b0-005056a27559"; $y++; - $apps[$x]['permissions'][$y]['name'] = "emergency_logs_view_all"; - $apps[$x]['permissions'][$y]['groups'][] = "superadmin"; + $apps[$x]['permissions'][$y]['name'] = "emergency_logs_view_all"; + $apps[$x]['permissions'][$y]['groups'][] = "superadmin"; $y++; //schema details $z=0; $apps[$x]['db'][$y]['table']['name'] = "v_emergency_logs"; $apps[$x]['db'][$y]['table']['parent'] = ""; - $apps[$x]['db'][$y]['fields'][$z]['name'] = 'log_uuid'; + $apps[$x]['db'][$y]['fields'][$z]['name'] = 'emergency_log_uuid'; $apps[$x]['db'][$y]['fields'][$z]['type']['pgsql'] = 'uuid'; $apps[$x]['db'][$y]['fields'][$z]['key']['type'] = 'primary'; $apps[$x]['db'][$y]['fields'][$z]['description'] = ''; $z++; - $apps[$x]['db'][$y]['fields'][$z]['name'] = 'domain_uuid'; - $apps[$x]['db'][$y]['fields'][$z]['type']['pgsql'] = 'uuid'; - $apps[$x]['db'][$y]['fields'][$z]['type']['sqlite'] = 'text'; - $apps[$x]['db'][$y]['fields'][$z]['type']['mysql'] = 'char(36)'; - $apps[$x]['db'][$y]['fields'][$z]['key']['type'] = 'foreign'; - $apps[$x]['db'][$y]['fields'][$z]['key']['reference']['table'] = 'v_domains'; - $apps[$x]['db'][$y]['fields'][$z]['key']['reference']['field'] = 'domain_uuid'; - $z++; - $apps[$x]['db'][$y]['fields'][$z]['name'] = 'date'; - $apps[$x]['db'][$y]['fields'][$z]['type']['pgsql'] = 'text'; - $apps[$x]['db'][$y]['fields'][$z]['type']['sqlite'] = "text"; - $apps[$x]['db'][$y]['fields'][$z]['type']['mysql'] = "text"; - $apps[$x]['db'][$y]['fields'][$z]['description'] = ''; - $z++; - $apps[$x]['db'][$y]['fields'][$z]['name'] = 'time'; - $apps[$x]['db'][$y]['fields'][$z]['type']['pgsql'] = 'text'; - $apps[$x]['db'][$y]['fields'][$z]['type']['sqlite'] = "text"; - $apps[$x]['db'][$y]['fields'][$z]['type']['mysql'] = "text"; - $apps[$x]['db'][$y]['fields'][$z]['description'] = ''; + $apps[$x]['db'][$y]['fields'][$z]['name'] = 'domain_uuid'; + $apps[$x]['db'][$y]['fields'][$z]['type']['pgsql'] = 'uuid'; + $apps[$x]['db'][$y]['fields'][$z]['type']['sqlite'] = 'text'; + $apps[$x]['db'][$y]['fields'][$z]['type']['mysql'] = 'char(36)'; + $apps[$x]['db'][$y]['fields'][$z]['key']['type'] = 'foreign'; + $apps[$x]['db'][$y]['fields'][$z]['key']['reference']['table'] = 'v_domains'; + $apps[$x]['db'][$y]['fields'][$z]['key']['reference']['field'] = 'domain_uuid'; $z++; $apps[$x]['db'][$y]['fields'][$z]['name'] = 'extension'; $apps[$x]['db'][$y]['fields'][$z]['type']['pgsql'] = 'numeric'; $apps[$x]['db'][$y]['fields'][$z]['type']['sqlite'] = "text"; - $apps[$x]['db'][$y]['fields'][$z]['type']['mysql'] = "char(36)"; + $apps[$x]['db'][$y]['fields'][$z]['type']['mysql'] = "char(36)"; $apps[$x]['db'][$y]['fields'][$z]['description'] = ''; $z++; $apps[$x]['db'][$y]['fields'][$z]['name'] = 'event'; $apps[$x]['db'][$y]['fields'][$z]['type']['pgsql'] = "text"; - $apps[$x]['db'][$y]['fields'][$z]['type']['sqlite'] = "text"; - $apps[$x]['db'][$y]['fields'][$z]['type']['mysql'] = "text"; + $apps[$x]['db'][$y]['fields'][$z]['type']['sqlite'] = "text"; + $apps[$x]['db'][$y]['fields'][$z]['type']['mysql'] = "text"; $apps[$x]['db'][$y]['fields'][$z]['description'] = ''; $z++; - $apps[$x]['db'][$y]['fields'][$z]['name'] = "insert_date"; - $apps[$x]['db'][$y]['fields'][$z]['type']['pgsql'] = 'timestamptz'; - $apps[$x]['db'][$y]['fields'][$z]['type']['sqlite'] = 'date'; - $apps[$x]['db'][$y]['fields'][$z]['type']['mysql'] = 'date'; - $apps[$x]['db'][$y]['fields'][$z]['description']['en-us'] = ""; - $z++; - $apps[$x]['db'][$y]['fields'][$z]['name'] = "insert_user"; - $apps[$x]['db'][$y]['fields'][$z]['type']['pgsql'] = "uuid"; - $apps[$x]['db'][$y]['fields'][$z]['type']['sqlite'] = "text"; - $apps[$x]['db'][$y]['fields'][$z]['type']['mysql'] = "char(36)"; - $apps[$x]['db'][$y]['fields'][$z]['description']['en-us'] = ""; - $z++; - $apps[$x]['db'][$y]['fields'][$z]['name'] = "update_date"; - $apps[$x]['db'][$y]['fields'][$z]['type']['pgsql'] = 'timestamptz'; - $apps[$x]['db'][$y]['fields'][$z]['type']['sqlite'] = 'date'; - $apps[$x]['db'][$y]['fields'][$z]['type']['mysql'] = 'date'; - $apps[$x]['db'][$y]['fields'][$z]['description']['en-us'] = ""; - $z++; - $apps[$x]['db'][$y]['fields'][$z]['name'] = "update_user"; - $apps[$x]['db'][$y]['fields'][$z]['type']['pgsql'] = "uuid"; - $apps[$x]['db'][$y]['fields'][$z]['type']['sqlite'] = "text"; - $apps[$x]['db'][$y]['fields'][$z]['type']['mysql'] = "char(36)"; - $apps[$x]['db'][$y]['fields'][$z]['description']['en-us'] = ""; -?> + $apps[$x]['db'][$y]['fields'][$z]['name'] = "insert_date"; + $apps[$x]['db'][$y]['fields'][$z]['type']['pgsql'] = 'timestamptz'; + $apps[$x]['db'][$y]['fields'][$z]['type']['sqlite'] = 'date'; + $apps[$x]['db'][$y]['fields'][$z]['type']['mysql'] = 'date'; + $apps[$x]['db'][$y]['fields'][$z]['description']['en-us'] = ""; + $z++; + $apps[$x]['db'][$y]['fields'][$z]['name'] = "insert_user"; + $apps[$x]['db'][$y]['fields'][$z]['type']['pgsql'] = "uuid"; + $apps[$x]['db'][$y]['fields'][$z]['type']['sqlite'] = "text"; + $apps[$x]['db'][$y]['fields'][$z]['type']['mysql'] = "char(36)"; + $apps[$x]['db'][$y]['fields'][$z]['description']['en-us'] = ""; + $z++; + $apps[$x]['db'][$y]['fields'][$z]['name'] = "update_date"; + $apps[$x]['db'][$y]['fields'][$z]['type']['pgsql'] = 'timestamptz'; + $apps[$x]['db'][$y]['fields'][$z]['type']['sqlite'] = 'date'; + $apps[$x]['db'][$y]['fields'][$z]['type']['mysql'] = 'date'; + $apps[$x]['db'][$y]['fields'][$z]['description']['en-us'] = ""; + $z++; + $apps[$x]['db'][$y]['fields'][$z]['name'] = "update_user"; + $apps[$x]['db'][$y]['fields'][$z]['type']['pgsql'] = "uuid"; + $apps[$x]['db'][$y]['fields'][$z]['type']['sqlite'] = "text"; + $apps[$x]['db'][$y]['fields'][$z]['type']['mysql'] = "char(36)"; + $apps[$x]['db'][$y]['fields'][$z]['description']['en-us'] = ""; + +?> \ No newline at end of file diff --git a/app/emergency/app_languages.php b/app/emergency/app_languages.php new file mode 100644 index 0000000000..c2139f8baf --- /dev/null +++ b/app/emergency/app_languages.php @@ -0,0 +1,133 @@ + \ No newline at end of file diff --git a/app/emergency/emergency.php b/app/emergency/emergency.php index 03dbaaa698..849f22d46c 100644 --- a/app/emergency/emergency.php +++ b/app/emergency/emergency.php @@ -78,9 +78,8 @@ if (!empty($_GET["show"])) { $show = $_GET["show"]; } - //get the count -$sql = "select count(log_uuid) "; +$sql = "select count(emergency_log_uuid) "; $sql .= "from v_emergency_logs "; if ($show == 'all') { $sql .= "where true "; @@ -117,7 +116,13 @@ else { } //get the list -$sql = "select * "; +$sql = "select emergency_log_uuid, "; +$sql .= "domain_uuid, "; +$sql .= "extension, "; +$sql .= "event, "; +$sql .= "to_char(timezone(:time_zone, insert_date), 'DD Mon YYYY') as date_formatted, "; +$sql .= "to_char(timezone(:time_zone, insert_date), 'HH12:MI:SS am') as time_formatted, "; +$sql .= "insert_date "; $sql .= "from v_emergency_logs "; if ($show == 'all') { $sql .= "where true "; @@ -132,8 +137,9 @@ if (!empty($search)) { $sql .= ") "; $parameters['search'] = '%'.$search.'%'; } +$sql .= "order by insert_date desc "; $sql .= limit_offset($rows_per_page, $offset); - +$parameters['time_zone'] = $time_zone; $database = new database; $emergency_logs = $database->select($sql, $parameters ?? null, 'all'); unset($sql, $parameters); @@ -143,12 +149,12 @@ $object = new token; $token = $object->create($_SERVER['PHP_SELF']); //additional includes -$document['title'] = 'Emergency Logs'; +$document['title'] = $text['title-emergency_logs']; require_once "resources/header.php"; //show the content echo "
\n"; -echo "
Emergency Logs (".$num_rows.")
\n"; +echo "
".$text['title-emergency_logs']." (".$num_rows.")
\n"; echo "
\n"; if ($emergency_logs) { echo button::create(['type'=>'button','label'=>$text['button-delete'],'icon'=>$_SESSION['theme']['button_icon_delete'],'id'=>'btn_delete','name'=>'btn_delete','style'=>'display:none;','onclick'=>"modal_open('modal-delete','btn_delete');"]); @@ -181,18 +187,18 @@ echo "

\n"; echo "\n"; echo "\n"; -echo "\n"; -echo "\n"; -echo "\n"; -echo "\n"; +echo "\n"; +echo "\n"; +echo "\n"; +echo "\n"; echo "\n"; if (!empty($emergency_logs) && is_array($emergency_logs) && @sizeof($emergency_logs) != 0) { $x = 0; foreach ($emergency_logs as $row) { echo "\n"; - echo " \n"; - echo " \n"; + echo " \n"; + echo " \n"; echo " \n"; echo " \n"; echo "\n"; @@ -210,4 +216,4 @@ echo "\n"; //include the footer require_once "resources/footer.php"; -?> +?> \ No newline at end of file diff --git a/app/switch/resources/scripts/app/emergency/index.lua b/app/switch/resources/scripts/app/emergency/index.lua index fd1a694ede..ad91d47543 100644 --- a/app/switch/resources/scripts/app/emergency/index.lua +++ b/app/switch/resources/scripts/app/emergency/index.lua @@ -36,25 +36,25 @@ --convert_ext (optional) to replace the file's extension --Example - --luarun emergency.lua to@domain.com from@domain.com 'headers' 'subject' 'body' +--luarun emergency.lua to@domain.com from@domain.com 'headers' 'subject' 'body' --load libraries - local send_mail = require 'resources.functions.send_mail' - local Database = require "resources.functions.database" - local Settings = require "resources.functions.lazy_settings" - local Utils = require "resources.functions.channel_utils"; +local send_mail = require 'resources.functions.send_mail' +local Database = require "resources.functions.database" +local Settings = require "resources.functions.lazy_settings" +local Utils = require "resources.functions.channel_utils"; --define a function to send email - local db = dbh or Database.new('system') - local settings = Settings.new(db, domain_name, domain_uuid) - local email_queue_enabled = settings:get('email_queue', 'enabled', 'boolean') or "false"; +local db = dbh or Database.new('system') +local settings = Settings.new(db, domain_name, domain_uuid) +local email_queue_enabled = settings:get('email_queue', 'enabled', 'boolean') or "false"; --get the argv values - script_name = argv[0]; - delete = argv[1]; +script_name = argv[0]; +delete = argv[1]; --prepare the api object - api = freeswitch.API(); +api = freeswitch.API(); --get sessions info if (session and session:ready()) then @@ -71,17 +71,17 @@ else headers = {} end -function escapeCSV(s) +function escape_csv(s) if string.find(s, '[,"]') then s = '"' .. string.gsub(s, '"', '""') .. '"' end return s end -function toCSV(tt) +function to_csv(tt) local s = "" for _,p in ipairs(tt) do - s = s .. "," .. escapeCSV(p) + s = s .. "," .. escape_csv(p) end return string.sub(s, 2) end @@ -100,9 +100,9 @@ local sql = "SELECT * FROM v_email_templates "; body = row.template_body; language = row.template_language; end); - if (debug["sql"]) then - freeswitch.consoleLog("info", "[emergency] SQL: " .. sql .. "\n"); - end + if (debug["sql"]) then + freeswitch.consoleLog("info", "[emergency] SQL: " .. sql .. "\n"); + end --freeswitch.consoleLog("info", "[template] SQL: " .. sql .. "body: " .. body .. "\n"); --get email from @@ -110,11 +110,9 @@ local sql = "SELECT * FROM v_default_settings "; sql = sql .. "WHERE default_setting_category = 'email' "; sql = sql .. "AND (default_setting_subcategory = 'smtp_from' "; sql = sql .. "OR default_setting_subcategory = 'smtp_from_name') "; - - if (debug["sql"]) then - freeswitch.consoleLog("notice", "[emergency] SQL: " .. sql .. "\n"); - end - + if (debug["sql"]) then + freeswitch.consoleLog("notice", "[emergency] SQL: " .. sql .. "\n"); + end dbh:query(sql, function(row) if (row.default_setting_subcategory == "smtp_from") then from = row.default_setting_value; @@ -122,85 +120,94 @@ local sql = "SELECT * FROM v_default_settings "; if (row.default_setting_subcategory == "smtp_from_name") then from_name = row.default_setting_value; end - end); - - - --- get vars -domain_uuid = session:getVariable("domain_uuid"); -call_date = session:getVariable("call_date"); -caller_id_name = session:getVariable("caller_id_name"); -caller_id_number = session:getVariable("caller_id_number"); -sip_from_user = session:getVariable("sip_from_user"); -emergency_caller_id_name = session:getVariable("emergency_caller_id_name"); -emergency_caller_id_number = session:getVariable("emergency_caller_id_number"); -call_duration = session:getVariable("call_duration"); - ---domain level check - result = {} -local sql = "SELECT count(domain_setting_value) "; - sql = sql .. "AS total "; - sql = sql .. "FROM v_domain_settings "; - sql = sql .. "WHERE domain_uuid = :domain_uuid "; - sql = sql .. "AND domain_setting_subcategory = :emergency_email_address "; - sql = sql .. "AND domain_setting_enabled = :status "; - - local params = {domain_uuid = domain_uuid, emergency_email_address = 'emergency_email_address', status = 't'} - - dbh:query(sql, params, function(result) - total = result.total; - --no emergency emails found under domain, using default - if (total == 0 or total == nil) then - to = {} - local sql = "SELECT default_setting_value "; - sql = sql .. "FROM v_default_settings "; - sql = sql .. "WHERE default_setting_category = :category "; - sql = sql .. "AND default_setting_subcategory = :emergency_email_address "; - sql = sql .. "AND default_setting_enabled = :status "; - sql = sql .. "LIMIT 5 "; - local params = {category = 'dialplan', emergency_email_address = 'emergency_email_address', status = 't'} - dbh:query(sql, params, function(result) - for key,row in pairs(result) do - table.insert(to, row); - freeswitch.consoleLog("info", "[emergency] Inserted into table from default settings " .. row .. "\n"); - end - --add some details - if (debug["sql"]) then - freeswitch.consoleLog("notice", "[emergency] SQL: " .. sql .. " result " .. result .. "\n"); - end - end); - --domain level emails max 5 - else if (tonumber(total) <= 5) then - to = {} - local sql = "SELECT domain_setting_value "; - sql = sql .. "FROM v_domain_settings "; - sql = sql .. "WHERE domain_uuid = :domain_uuid "; - sql = sql .. "AND domain_setting_subcategory = :emergency_email_address "; - sql = sql .. "AND domain_setting_enabled = :status "; - local params = {domain_uuid = domain_uuid, emergency_email_address = 'emergency_email_address', status = 't'} - dbh:query(sql, params, function(result) - for key,row in pairs(result) do - table.insert(to, row); - freeswitch.consoleLog("info", "[template] Inserted into table " .. row .. "\n"); - end - end); - end - end - end); -dbh:release() - -if (#to > 0) then - --set event +--get variables +if (session and session:ready()) then + domain_uuid = session:getVariable("domain_uuid"); + caller_id_name = session:getVariable("caller_id_name"); + caller_id_number = session:getVariable("caller_id_number"); + sip_from_user = session:getVariable("sip_from_user"); + emergency_caller_id_name = session:getVariable("emergency_caller_id_name"); + emergency_caller_id_number = session:getVariable("emergency_caller_id_number"); + call_duration = session:getVariable("call_duration"); destination_number = session:getVariable("destination_number"); - if (tonumber(destination_number) == 933) then - event = '933 Emergency Address Validation Service'; - else if (tonumber(destination_number) == 911) then - event = '911 Emergency Call'; - end +end + +--domain level check +result = {} +local sql = "SELECT count(domain_setting_value) "; +sql = sql .. "AS total "; +sql = sql .. "FROM v_domain_settings "; +sql = sql .. "WHERE domain_uuid = :domain_uuid "; +sql = sql .. "AND domain_setting_subcategory = :emergency_email_address "; +sql = sql .. "AND domain_setting_enabled = :status "; + +local params = {domain_uuid = domain_uuid, emergency_email_address = 'emergency_email_address', status = 't'} + +dbh:query(sql, params, function(result) + total = result.total; + --no emergency emails found under domain, using default + if (total == 0 or total == nil) then + to = {} + local sql = "SELECT default_setting_value "; + sql = sql .. "FROM v_default_settings "; + sql = sql .. "WHERE default_setting_category = :category "; + sql = sql .. "AND default_setting_subcategory = :emergency_email_address "; + sql = sql .. "AND default_setting_enabled = :status "; + sql = sql .. "LIMIT 5 "; + local params = {category = 'dialplan', emergency_email_address = 'emergency_email_address', status = 't'} + dbh:query(sql, params, function(result) + for key,row in pairs(result) do + table.insert(to, row); + freeswitch.consoleLog("info", "[emergency] Inserted into table from default settings " .. row .. "\n"); + end + --add some details + if (debug["sql"]) then + freeswitch.consoleLog("notice", "[emergency] SQL: " .. sql .. " result " .. result .. "\n"); + end + end); + --domain level emails max 5 + else if (tonumber(total) <= 5) then + to = {} + local sql = "SELECT domain_setting_value "; + sql = sql .. "FROM v_domain_settings "; + sql = sql .. "WHERE domain_uuid = :domain_uuid "; + sql = sql .. "AND domain_setting_subcategory = :emergency_email_address "; + sql = sql .. "AND domain_setting_enabled = :status "; + local params = {domain_uuid = domain_uuid, emergency_email_address = 'emergency_email_address', status = 't'} + dbh:query(sql, params, function(result) + for key,row in pairs(result) do + table.insert(to, row); + freeswitch.consoleLog("info", "[template] Inserted into table " .. row .. "\n"); + end + end); + end end +end); + +--set event +if (tonumber(destination_number) == 933) then + event = '933 Emergency Address Validation Service'; +else if (tonumber(destination_number) == 911) then + event = '911 Emergency Call'; + end +end + +--connect to the database +local dbh = Database.new('system'); + +--set the call date +sql = "SELECT now() as call_date "; +if (debug["sql"]) then + freeswitch.consoleLog("NOTICE", "[event] "..sql.."\n"); +end +local t = dbh:first_row(sql); +call_date = t.call_date; + +--send the email +if (#to > 0) then --prepare the body if (body ~= nil) then body = body:gsub("${caller_id_name}", caller_id_name); @@ -225,54 +232,30 @@ if (#to > 0) then end end --- Insert into Emergency Logs -emergency_logs_uuid = api:executeString("create_uuid"); -domain_uuid = session:getVariable("domain_uuid"); - --- Set time and date -local delimiter = " "; -local y = 0; -local tab = {} - -while true do - local endindex = call_date:find(delimiter,y); - if not endindex then - break - end - table.insert(tab,call_date:sub(y,endindex-1)) - y = endindex + 1; -end - -table.insert(tab,call_date:sub(y)); -local time = tab[2] .. " " .. tab[3]; - -freeswitch.consoleLog("info", "[emergency] Getting Date " .. tab[1] .. " Time " .. tab[2] .. " Format " .. tab[3] .. "\n"); - --connect to the database local dbh = Database.new('system'); +--insert into emergency logs local sql = "INSERT INTO v_emergency_logs ( "; - sql = sql .. " log_uuid, "; - sql = sql .. " domain_uuid, "; - sql = sql .. " date, "; - sql = sql .. " time, "; - sql = sql .. " extension, "; - sql = sql .. " event "; - sql = sql .. ") "; - sql = sql .. "VALUES ( "; - sql = sql .. " :emergency_logs_uuid, "; - sql = sql .. " :domain_uuid, "; - sql = sql .. " :date, "; - sql = sql .. " :time, "; - sql = sql .. " :extension, "; - sql = sql .. " :event "; - sql = sql .. ") "; +sql = sql .. " emergency_log_uuid, "; +sql = sql .. " domain_uuid, "; +sql = sql .. " insert_date, "; +sql = sql .. " extension, "; +sql = sql .. " event "; +sql = sql .. ") "; +sql = sql .. "VALUES ( "; +sql = sql .. " :emergency_log_uuid, "; +sql = sql .. " :domain_uuid, "; +sql = sql .. " now(), "; +sql = sql .. " :extension, "; +sql = sql .. " :event "; +sql = sql .. ") "; - local params = {emergency_logs_uuid = emergency_logs_uuid,domain_uuid = domain_uuid, date = tab[1], time = time, extension = caller_id_number, event = event} +local params = {emergency_log_uuid = call_uuid, domain_uuid = domain_uuid, extension = caller_id_number, event = event} - if (debug["sql"]) then - freeswitch.consoleLog("info", "[emergency] SQL: " .. sql .. "\n"); - end +if (debug["sql"]) then + freeswitch.consoleLog("info", "[emergency] SQL: " .. sql .. "\n"); +end - dbh:query(sql, params); - dbh:release(); +dbh:query(sql, params); +dbh:release(); \ No newline at end of file
TimeDateExtensionEvent".$text['label-emergency_time']."".$text['label-emergency_date']."".$text['label-emergency_extension']."".$text['label-emergency_event']."
".escape($row['time'])."".escape($row['date'])."".escape($row['time_formatted'])."".escape($row['date_formatted'])."".escape($row['extension'])."".escape($row['event'])."