Code updates for PHP8 compatibility, and json output format to several Non-Agent API
Fixes for input variable filtering git-svn-id: svn://192.168.202.10@3995 3d104415-ff17-0410-8863-d5cf3c621b8a
This commit is contained in:
@@ -803,7 +803,7 @@ else
|
|||||||
|
|
||||||
# update internal process log
|
# update internal process log
|
||||||
$iLog_ct++;
|
$iLog_ct++;
|
||||||
if ($iLog_ct =~ /00$/)
|
if ($iLog_ct =~ /00$|50$/)
|
||||||
{
|
{
|
||||||
$stmtA = "UPDATE vicidial_internal_log SET up_time=NOW(), action='running', stage='Loops: $iLog_ct' WHERE process='$script_name' and server_ip='$server_ip' order by db_time desc limit 1;";
|
$stmtA = "UPDATE vicidial_internal_log SET up_time=NOW(), action='running', stage='Loops: $iLog_ct' WHERE process='$script_name' and server_ip='$server_ip' order by db_time desc limit 1;";
|
||||||
if($DB){print STDERR "|$stmtA|";}
|
if($DB){print STDERR "|$stmtA|";}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
NON-AGENT API DOCUMENT Started: 2008-07-24 Updated: 2025-07-18
|
NON-AGENT API DOCUMENT Started: 2008-07-24 Updated: 2026-05-19
|
||||||
|
|
||||||
This document describes the functions of an API(Application Programming
|
This document describes the functions of an API(Application Programming
|
||||||
Interface) for all functions NOT directly relating to the VICIDIAL Agent screen.
|
Interface) for all functions NOT directly relating to the VICIDIAL Agent screen.
|
||||||
@@ -231,6 +231,10 @@ Changes:
|
|||||||
241004-1518 - Added webform_one-three variables to the update_campaign function
|
241004-1518 - Added webform_one-three variables to the update_campaign function
|
||||||
241113-1600 - Added in_groups as input option for update_user function
|
241113-1600 - Added in_groups as input option for update_user function
|
||||||
250720-1841 - Added hopper_bulk_insert function
|
250720-1841 - Added hopper_bulk_insert function
|
||||||
|
251205-1456 - Added ADAPT_PERCENTMAX dial_method
|
||||||
|
260123-1020 - pause_sec fix in agent_stats_export
|
||||||
|
260506-1525 - small fix for campaign changes
|
||||||
|
260519-1647 - Code updates for PHP8 compatibility, and json output format
|
||||||
|
|
||||||
|
|
||||||
API Functions use the 'function' variable
|
API Functions use the 'function' variable
|
||||||
@@ -398,7 +402,7 @@ campaign_id - 2-8 characters
|
|||||||
ignore_agentdirect - Y or N, default is N. Exclude AGENTDIRECT in-groups from results or not
|
ignore_agentdirect - Y or N, default is N. Exclude AGENTDIRECT in-groups from results or not
|
||||||
|
|
||||||
SETTINGS FIELDS-
|
SETTINGS FIELDS-
|
||||||
stage - the format of the exported data: csv, tab, pipe(default)
|
stage - the format of the exported data: csv, tab, json, pipe(default)
|
||||||
header - include a header(YES) or not(NO). This is optional, default is not to include a header
|
header - include a header(YES) or not(NO). This is optional, default is not to include a header
|
||||||
|
|
||||||
Example URL strings for API calls:
|
Example URL strings for API calls:
|
||||||
@@ -431,7 +435,7 @@ OPTIONAL FIELDS-
|
|||||||
campaign_id - 2-8 characters, for all campaigns, leave blank
|
campaign_id - 2-8 characters, for all campaigns, leave blank
|
||||||
|
|
||||||
SETTINGS FIELDS-
|
SETTINGS FIELDS-
|
||||||
stage - the format of the exported data: csv, tab, pipe(default)
|
stage - the format of the exported data: csv, tab, json, pipe(default)
|
||||||
header - include a header(YES) or not(NO). This is optional, default is not to include a header
|
header - include a header(YES) or not(NO). This is optional, default is not to include a header
|
||||||
|
|
||||||
Example URL strings for API calls:
|
Example URL strings for API calls:
|
||||||
@@ -460,7 +464,7 @@ source - description of what originated the API call (maximum 20 characters)
|
|||||||
campaign_id - 2-8 characters
|
campaign_id - 2-8 characters
|
||||||
|
|
||||||
SETTINGS FIELDS-
|
SETTINGS FIELDS-
|
||||||
stage - the format of the exported data: csv, tab, pipe(default)
|
stage - the format of the exported data: csv, tab, json, pipe(default)
|
||||||
header - include a header(YES) or not(NO). This is optional, default is not to include a header
|
header - include a header(YES) or not(NO). This is optional, default is not to include a header
|
||||||
|
|
||||||
OPTIONAL FIELDS-
|
OPTIONAL FIELDS-
|
||||||
@@ -535,7 +539,7 @@ uniqueid - uniqueid of the call, works best included with another search field
|
|||||||
extension - 3-100 characters, the extension listed in the recording_log
|
extension - 3-100 characters, the extension listed in the recording_log
|
||||||
|
|
||||||
SETTINGS FIELDS-
|
SETTINGS FIELDS-
|
||||||
stage - the format of the exported data: csv, tab, pipe(default)
|
stage - the format of the exported data: csv, tab, json, pipe(default)
|
||||||
header - include a header(YES) or not(NO). This is optional, default is not to include a header
|
header - include a header(YES) or not(NO). This is optional, default is not to include a header
|
||||||
duration - Y or N, default is N. Includes the duration of the recording in the output(in seconds), before the location
|
duration - Y or N, default is N. Includes the duration of the recording in the output(in seconds), before the location
|
||||||
|
|
||||||
@@ -571,7 +575,7 @@ phone_number - 2-20 characters, the DID that you want to pull logs for
|
|||||||
date - date of the calls to pull (must be in YYYY-MM-DD format)
|
date - date of the calls to pull (must be in YYYY-MM-DD format)
|
||||||
|
|
||||||
SETTINGS FIELDS-
|
SETTINGS FIELDS-
|
||||||
stage - the format of the exported data: csv, tab, pipe(default)
|
stage - the format of the exported data: csv, tab, json, pipe(default)
|
||||||
header - include a header(YES) or not(NO). This is optional, default is not to include a header
|
header - include a header(YES) or not(NO). This is optional, default is not to include a header
|
||||||
|
|
||||||
NOTES-
|
NOTES-
|
||||||
@@ -602,7 +606,7 @@ REQUIRED FIELDS-
|
|||||||
phone_number - the phone number(s) that you want to pull logs for. allows more than one, separated by commas
|
phone_number - the phone number(s) that you want to pull logs for. allows more than one, separated by commas
|
||||||
|
|
||||||
SETTINGS FIELDS-
|
SETTINGS FIELDS-
|
||||||
stage - the format of the exported data: csv, tab, pipe(default)
|
stage - the format of the exported data: csv, tab, json, pipe(default)
|
||||||
header - include a header(YES) or not(NO). This is optional, default is not to include a header
|
header - include a header(YES) or not(NO). This is optional, default is not to include a header
|
||||||
detail - (ALL) calls or only (LAST) call. default is (ALL)
|
detail - (ALL) calls or only (LAST) call. default is (ALL)
|
||||||
type - (IN)inbound, (OUT)outbound or (ALL) calls. defauls is (OUT) calls
|
type - (IN)inbound, (OUT)outbound or (ALL) calls. defauls is (OUT) calls
|
||||||
@@ -641,7 +645,7 @@ datetime_end - end date/time of the agent activity to pull (must be in "YYYY-MM
|
|||||||
SETTINGS FIELDS-
|
SETTINGS FIELDS-
|
||||||
agent_user - 2-20 characters, use only for one agent stats <optional>
|
agent_user - 2-20 characters, use only for one agent stats <optional>
|
||||||
campaign_id - 2-8 characters, use only for one campaign stats <optional>
|
campaign_id - 2-8 characters, use only for one campaign stats <optional>
|
||||||
stage - the format of the exported data: csv, tab, pipe(default)
|
stage - the format of the exported data: csv, tab, json, pipe(default)
|
||||||
header - include a header(YES) or not(NO). This is optional, default is not to include a header
|
header - include a header(YES) or not(NO). This is optional, default is not to include a header
|
||||||
time_format - time format('H','HF','M','S') in hours, minutes or seconds: H = 1:23:45, M = 83:45, S = 5023 (default 'HF')
|
time_format - time format('H','HF','M','S') in hours, minutes or seconds: H = 1:23:45, M = 83:45, S = 5023 (default 'HF')
|
||||||
* HF will force hour format even for zero seconds time "0:00:00"
|
* HF will force hour format even for zero seconds time "0:00:00"
|
||||||
@@ -680,7 +684,7 @@ source - description of what originated the API call (maximum 20 characters)
|
|||||||
user_groups - pipe-delimited list of user groups to get status information for "ADMIN|AGENTS"
|
user_groups - pipe-delimited list of user groups to get status information for "ADMIN|AGENTS"
|
||||||
|
|
||||||
SETTINGS FIELDS-
|
SETTINGS FIELDS-
|
||||||
stage - the format of the exported data: csv, tab, pipe(default)
|
stage - the format of the exported data: csv, tab, json, pipe(default)
|
||||||
header - include a header(YES) or not(NO). This is optional, default is not to include a header
|
header - include a header(YES) or not(NO). This is optional, default is not to include a header
|
||||||
|
|
||||||
NOTES-
|
NOTES-
|
||||||
@@ -711,7 +715,7 @@ source - description of what originated the API call (maximum 20 characters)
|
|||||||
in_groups - pipe-delimited list of inbound groups to get status information for "SALESLINE|SUPPORT"
|
in_groups - pipe-delimited list of inbound groups to get status information for "SALESLINE|SUPPORT"
|
||||||
|
|
||||||
SETTINGS FIELDS-
|
SETTINGS FIELDS-
|
||||||
stage - the format of the exported data: csv, tab, pipe(default)
|
stage - the format of the exported data: csv, tab, json, pipe(default)
|
||||||
header - include a header(YES) or not(NO). This is optional, default is not to include a header
|
header - include a header(YES) or not(NO). This is optional, default is not to include a header
|
||||||
|
|
||||||
NOTES-
|
NOTES-
|
||||||
@@ -741,7 +745,7 @@ source - description of what originated the API call (maximum 20 characters)
|
|||||||
agent_user - 2-20 characters, use only for one agent status
|
agent_user - 2-20 characters, use only for one agent status
|
||||||
|
|
||||||
SETTINGS FIELDS-
|
SETTINGS FIELDS-
|
||||||
stage - the format of the exported data: csv, tab, pipe(default)
|
stage - the format of the exported data: csv, tab, json, pipe(default)
|
||||||
header - include a header(YES) or not(NO). This is optional, default is not to include a header
|
header - include a header(YES) or not(NO). This is optional, default is not to include a header
|
||||||
include_ip - include computer_ip field(YES) or not(NO), the last ip address that the agent used to log in to the agent screen
|
include_ip - include computer_ip field(YES) or not(NO), the last ip address that the agent used to log in to the agent screen
|
||||||
|
|
||||||
@@ -775,7 +779,7 @@ source - description of what originated the API call (maximum 20 characters)
|
|||||||
agent_user - 2-20 characters, use only for one user
|
agent_user - 2-20 characters, use only for one user
|
||||||
|
|
||||||
SETTINGS FIELDS-
|
SETTINGS FIELDS-
|
||||||
stage - the format of the exported data: csv, tab, pipe(default)
|
stage - the format of the exported data: csv, tab, json, pipe(default)
|
||||||
header - include a header(YES) or not(NO). This is optional, default is not to include a header
|
header - include a header(YES) or not(NO). This is optional, default is not to include a header
|
||||||
|
|
||||||
Example URL strings for API calls:
|
Example URL strings for API calls:
|
||||||
@@ -803,7 +807,7 @@ source - description of what originated the API call (maximum 20 characters)
|
|||||||
call_id - 16-40 characters
|
call_id - 16-40 characters
|
||||||
|
|
||||||
SETTINGS FIELDS-
|
SETTINGS FIELDS-
|
||||||
stage - the format of the exported data: csv, tab, pipe(default)
|
stage - the format of the exported data: csv, tab, json, pipe(default)
|
||||||
header - include a header(YES) or not(NO). This is optional, default is not to include a header
|
header - include a header(YES) or not(NO). This is optional, default is not to include a header
|
||||||
detail - if set to YES, more call info will be output. Default is NO, only callid and customer talk time will be output
|
detail - if set to YES, more call info will be output. Default is NO, only callid and customer talk time will be output
|
||||||
|
|
||||||
@@ -875,7 +879,7 @@ force_entry_list_id - 3-12 digits, will override the lead's assigned entry_list_
|
|||||||
archived_lead - Y or N, Setting this to Y will query only the vicidial_list_archive leads for the leads details, default is N.
|
archived_lead - Y or N, Setting this to Y will query only the vicidial_list_archive leads for the leads details, default is N.
|
||||||
|
|
||||||
SETTINGS FIELDS-
|
SETTINGS FIELDS-
|
||||||
stage - the format of the exported data: csv, tab, newline, pipe(default)
|
stage - the format of the exported data: csv, tab, newline, json, pipe(default)
|
||||||
header - include a header(YES) or not(NO). This is optional, default is not to include a header
|
header - include a header(YES) or not(NO). This is optional, default is not to include a header
|
||||||
|
|
||||||
Example URL strings for API calls:
|
Example URL strings for API calls:
|
||||||
@@ -992,7 +996,7 @@ source - description of what originated the API call (maximum 20 characters)
|
|||||||
call_id - 16-40 characters
|
call_id - 16-40 characters
|
||||||
|
|
||||||
SETTINGS FIELDS-
|
SETTINGS FIELDS-
|
||||||
stage - the format of the exported data: csv, tab, newline, pipe(default)
|
stage - the format of the exported data: csv, tab, newline, json, pipe(default)
|
||||||
header - include a header(YES) or not(NO). This is optional, default is not to include a header
|
header - include a header(YES) or not(NO). This is optional, default is not to include a header
|
||||||
|
|
||||||
Example URL strings for API calls:
|
Example URL strings for API calls:
|
||||||
@@ -1022,7 +1026,7 @@ source - description of what originated the API call (maximum 20 characters)
|
|||||||
lead_id - 16-40 characters
|
lead_id - 16-40 characters
|
||||||
|
|
||||||
SETTINGS FIELDS-
|
SETTINGS FIELDS-
|
||||||
stage - the format of the exported data: csv, tab, newline, pipe(default)
|
stage - the format of the exported data: csv, tab, newline, json, pipe(default)
|
||||||
header - include a header(YES) or not(NO). This is optional, default is not to include a header
|
header - include a header(YES) or not(NO). This is optional, default is not to include a header
|
||||||
search_location - Where to check for scheduled callback records in the system, can select only one(default is CURRENT):
|
search_location - Where to check for scheduled callback records in the system, can select only one(default is CURRENT):
|
||||||
CURRENT - check for active scheduled callbacks
|
CURRENT - check for active scheduled callbacks
|
||||||
@@ -2202,7 +2206,7 @@ source - description of what originated the API call (maximum 20 characters)
|
|||||||
SETTINGS FIELDS- (optional)
|
SETTINGS FIELDS- (optional)
|
||||||
leads_counts - Y or N, will include the counts of all leads and NEW status leads in the response, default is 'N'
|
leads_counts - Y or N, will include the counts of all leads and NEW status leads in the response, default is 'N'
|
||||||
dialable_count - Y or N, will use the list's campaign settings to provide a count of how many are dialable right now, default is 'N'
|
dialable_count - Y or N, will use the list's campaign settings to provide a count of how many are dialable right now, default is 'N'
|
||||||
stage - the format of the exported data: csv, tab, pipe(default)
|
stage - the format of the exported data: csv, tab, json, pipe(default)
|
||||||
header - include a header(YES) or not(NO). This is optional, default is not to include a header
|
header - include a header(YES) or not(NO). This is optional, default is not to include a header
|
||||||
archived_lead - Y or N, Setting this to Y will query only the vicidial_list_archive leads for the leads count, default is N.
|
archived_lead - Y or N, Setting this to Y will query only the vicidial_list_archive leads for the leads count, default is N.
|
||||||
|
|
||||||
@@ -2239,7 +2243,7 @@ list_id - must be all numbers, 2-14 digits, OR use "---ALL---" for all lists
|
|||||||
source - description of what originated the API call (maximum 20 characters)
|
source - description of what originated the API call (maximum 20 characters)
|
||||||
|
|
||||||
SETTINGS FIELDS- (optional)
|
SETTINGS FIELDS- (optional)
|
||||||
stage - the format of the exported data: csv, tab, pipe(default)
|
stage - the format of the exported data: csv, tab, json, pipe(default)
|
||||||
header - include a header(YES) or not(NO). This is optional, default is not to include a header
|
header - include a header(YES) or not(NO). This is optional, default is not to include a header
|
||||||
custom_order - the order to put the custom fields into: table_order, alpha_up, alpha_down (default is 'table_order')
|
custom_order - the order to put the custom fields into: table_order, alpha_up, alpha_down (default is 'table_order')
|
||||||
|
|
||||||
@@ -2331,7 +2335,7 @@ user_groups - pipe-delimited list of user groups to get status information for
|
|||||||
show_sub_status - show agent sub-status and pause_code, requires log lookup, (YES|NO) default is NO
|
show_sub_status - show agent sub-status and pause_code, requires log lookup, (YES|NO) default is NO
|
||||||
|
|
||||||
SETTINGS FIELDS-
|
SETTINGS FIELDS-
|
||||||
stage - the format of the exported data: csv, tab, pipe(default)
|
stage - the format of the exported data: csv, tab, json, pipe(default)
|
||||||
header - include a header(YES) or not(NO). This is optional, default is not to include a header
|
header - include a header(YES) or not(NO). This is optional, default is not to include a header
|
||||||
|
|
||||||
Example URL strings for API calls:
|
Example URL strings for API calls:
|
||||||
@@ -2552,7 +2556,7 @@ entry_type - One of these: 'campaign'
|
|||||||
url_type - One of these: 'dispo','start','addlead','noagent'
|
url_type - One of these: 'dispo','start','addlead','noagent'
|
||||||
alt_url_id - Digits only, 'NEW' or 'LIST'. Must be a valid alt URL ID for this campaign, or set to 'NEW' to add a new ALT URL
|
alt_url_id - Digits only, 'NEW' or 'LIST'. Must be a valid alt URL ID for this campaign, or set to 'NEW' to add a new ALT URL
|
||||||
NOTE: If only one Alt URL exists for this campaign and type, then this field can be left blank
|
NOTE: If only one Alt URL exists for this campaign and type, then this field can be left blank
|
||||||
NOTE: 'stage'(csv, tab, pipe[default]) and 'header'(YES, NO) options are available for an alt_url_id of 'LIST'
|
NOTE: 'stage'(csv, tab, json, pipe[default]) and 'header'(YES, NO) options are available for an alt_url_id of 'LIST'
|
||||||
|
|
||||||
EDITABLE FIELDS-
|
EDITABLE FIELDS-
|
||||||
active - One of these: 'Y','N', default is 'N'
|
active - One of these: 'Y','N', default is 'N'
|
||||||
@@ -2619,7 +2623,7 @@ source - description of what originated the API call (maximum 20 characters)
|
|||||||
preset_name - name of the preset in the system
|
preset_name - name of the preset in the system
|
||||||
NOTE: If only one preset exists for this campaign, then this field can be left blank
|
NOTE: If only one preset exists for this campaign, then this field can be left blank
|
||||||
action - 'UPDATE', 'NEW', 'DELETE' or 'LIST' (default is 'UPDATE')
|
action - 'UPDATE', 'NEW', 'DELETE' or 'LIST' (default is 'UPDATE')
|
||||||
NOTE: 'stage'(csv, tab, pipe[default]) and 'header'(YES, NO) options are available for an action of 'LIST'
|
NOTE: 'stage'(csv, tab, json, pipe[default]) and 'header'(YES, NO) options are available for an action of 'LIST'
|
||||||
|
|
||||||
EDITABLE FIELDS-
|
EDITABLE FIELDS-
|
||||||
preset_hide_number - One of these: 'Y','N', default is 'N'
|
preset_hide_number - One of these: 'Y','N', default is 'N'
|
||||||
|
|||||||
@@ -4542,6 +4542,9 @@ else
|
|||||||
$survey_fourth_exten = preg_replace('/[^ \,\*\#0-9\p{L}]/u','',$survey_fourth_exten);
|
$survey_fourth_exten = preg_replace('/[^ \,\*\#0-9\p{L}]/u','',$survey_fourth_exten);
|
||||||
$preset_dtmf = preg_replace('/[^ \,\*\#0-9\p{L}]/u','',$preset_dtmf);
|
$preset_dtmf = preg_replace('/[^ \,\*\#0-9\p{L}]/u','',$preset_dtmf);
|
||||||
|
|
||||||
|
### ALPHA-NUMERIC and underscore
|
||||||
|
$qc_statuses_id = preg_replace('/[^_0-9\p{L}]/u','',$qc_statuses_id);
|
||||||
|
|
||||||
### ALPHA-NUMERIC and underscore and dash
|
### ALPHA-NUMERIC and underscore and dash
|
||||||
$agi_output = preg_replace('/[^-_0-9\p{L}]/u','',$agi_output);
|
$agi_output = preg_replace('/[^-_0-9\p{L}]/u','',$agi_output);
|
||||||
$ASTmgrSECRET = preg_replace('/[^-_0-9\p{L}]/u','',$ASTmgrSECRET);
|
$ASTmgrSECRET = preg_replace('/[^-_0-9\p{L}]/u','',$ASTmgrSECRET);
|
||||||
@@ -6338,12 +6341,13 @@ if ($SSscript_remove_js > 0)
|
|||||||
# 260410-1953 - Fix for max_inbound_auto_reenable feature in 4B admin screen
|
# 260410-1953 - Fix for max_inbound_auto_reenable feature in 4B admin screen
|
||||||
# 260416-0909 - Added modify_settings_containers user setting
|
# 260416-0909 - Added modify_settings_containers user setting
|
||||||
# 260516-2350 - Added Internal Process Logs display page
|
# 260516-2350 - Added Internal Process Logs display page
|
||||||
|
# 260521-2044 - Fixes for input variable filtering
|
||||||
#
|
#
|
||||||
|
|
||||||
# make sure you have added a user to the vicidial_users MySQL table with at least user_level 9 to access this page the first time
|
# make sure you have added a user to the vicidial_users MySQL table with at least user_level 9 to access this page the first time
|
||||||
|
|
||||||
$admin_version = '2.14-958a';
|
$admin_version = '2.14-959a';
|
||||||
$build = '260516-2350';
|
$build = '260521-2044';
|
||||||
|
|
||||||
$STARTtime = date("U");
|
$STARTtime = date("U");
|
||||||
$SQLdate = date("Y-m-d H:i:s");
|
$SQLdate = date("Y-m-d H:i:s");
|
||||||
@@ -9108,6 +9112,7 @@ if ($ADD==121)
|
|||||||
$p=0; $DNCadded=0; $DNCnotadded=0; $DNCdeleted=0; $DNCnotdeleted=0;
|
$p=0; $DNCadded=0; $DNCnotadded=0; $DNCdeleted=0; $DNCnotdeleted=0;
|
||||||
while ($p < $PNct)
|
while ($p < $PNct)
|
||||||
{
|
{
|
||||||
|
$PN[$p] = preg_replace('/[^\,\:\+\*\#\.\_0-9\p{L}]/u','',$PN[$p]);
|
||||||
if ( (preg_match('/delete/',$stage)) and ($LOGdelete_from_dnc > 0) )
|
if ( (preg_match('/delete/',$stage)) and ($LOGdelete_from_dnc > 0) )
|
||||||
{
|
{
|
||||||
##### BEGIN DELETE FROM DNC #####
|
##### BEGIN DELETE FROM DNC #####
|
||||||
@@ -9498,6 +9503,7 @@ if ($ADD==171)
|
|||||||
$p=0;
|
$p=0;
|
||||||
while ($p < $PNct)
|
while ($p < $PNct)
|
||||||
{
|
{
|
||||||
|
$PN[$p] = preg_replace('/[^\,\:\+\*\#\.\_0-9\p{L}]/u','',$PN[$p]);
|
||||||
if ( (preg_match('/delete/',$stage)) and ($LOGdelete_from_dnc > 0) )
|
if ( (preg_match('/delete/',$stage)) and ($LOGdelete_from_dnc > 0) )
|
||||||
{
|
{
|
||||||
$stmt="SELECT count(*) from vicidial_filter_phone_numbers where phone_number='$PN[$p]' and filter_phone_group_id='$filter_phone_group_id';";
|
$stmt="SELECT count(*) from vicidial_filter_phone_numbers where phone_number='$PN[$p]' and filter_phone_group_id='$filter_phone_group_id';";
|
||||||
@@ -9617,6 +9623,7 @@ if ($ADD==3211)
|
|||||||
{
|
{
|
||||||
if (strlen($PN[$p]) > 0)
|
if (strlen($PN[$p]) > 0)
|
||||||
{
|
{
|
||||||
|
$PN[$p] = preg_replace('/[^\,\:\+\*\#\.\_0-9\p{L}]/u','',$PN[$p]);
|
||||||
$ac_found=0;
|
$ac_found=0;
|
||||||
$vaf=0;
|
$vaf=0;
|
||||||
while ($vaf_ct > $vaf)
|
while ($vaf_ct > $vaf)
|
||||||
@@ -14951,6 +14958,7 @@ if ($ADD==231111111)
|
|||||||
$shift_weekdays_ct = count($shift_weekdays);
|
$shift_weekdays_ct = count($shift_weekdays);
|
||||||
while ($p <= $shift_weekdays_ct)
|
while ($p <= $shift_weekdays_ct)
|
||||||
{
|
{
|
||||||
|
$shift_weekdays[$p] = preg_replace('/[^0-9]/','',$shift_weekdays[$p]);
|
||||||
$SHIFT_weekdays .= "$shift_weekdays[$p]";
|
$SHIFT_weekdays .= "$shift_weekdays[$p]";
|
||||||
$p++;
|
$p++;
|
||||||
}
|
}
|
||||||
@@ -18362,6 +18370,7 @@ if ($ADD==48)
|
|||||||
$qc_statuses_ct = count($qc_statuses);
|
$qc_statuses_ct = count($qc_statuses);
|
||||||
while ($p < $qc_statuses_ct)
|
while ($p < $qc_statuses_ct)
|
||||||
{
|
{
|
||||||
|
$qc_statuses[$p] = preg_replace('/[^-_0-9\p{L}]/u','',$qc_statuses[$p]);
|
||||||
$QC_statuses .= " $qc_statuses[$p]";
|
$QC_statuses .= " $qc_statuses[$p]";
|
||||||
$p++;
|
$p++;
|
||||||
}
|
}
|
||||||
@@ -19025,6 +19034,7 @@ if ($ADD==4111 || $ADD==4811 || $ADD==4911)
|
|||||||
$qc_statuses_ct = count($qc_statuses);
|
$qc_statuses_ct = count($qc_statuses);
|
||||||
while ($p < $qc_statuses_ct)
|
while ($p < $qc_statuses_ct)
|
||||||
{
|
{
|
||||||
|
$qc_statuses[$p] = preg_replace('/[^-_0-9\p{L}]/u','',$qc_statuses[$p]);
|
||||||
$QC_statuses .= " $qc_statuses[$p]";
|
$QC_statuses .= " $qc_statuses[$p]";
|
||||||
$p++;
|
$p++;
|
||||||
}
|
}
|
||||||
@@ -19033,6 +19043,7 @@ if ($ADD==4111 || $ADD==4811 || $ADD==4911)
|
|||||||
$qc_lists_ct = count($qc_lists);
|
$qc_lists_ct = count($qc_lists);
|
||||||
while ($p < $qc_lists_ct)
|
while ($p < $qc_lists_ct)
|
||||||
{
|
{
|
||||||
|
$qc_lists[$p] = preg_replace('/[^-_0-9\p{L}]/u','',$qc_lists[$p]);
|
||||||
$QC_lists .= " $qc_lists[$p]";
|
$QC_lists .= " $qc_lists[$p]";
|
||||||
$p++;
|
$p++;
|
||||||
}
|
}
|
||||||
@@ -20143,6 +20154,7 @@ if ($ADD==431111111)
|
|||||||
$shift_weekdays_ct = count($shift_weekdays);
|
$shift_weekdays_ct = count($shift_weekdays);
|
||||||
while ($p <= $shift_weekdays_ct)
|
while ($p <= $shift_weekdays_ct)
|
||||||
{
|
{
|
||||||
|
$shift_weekdays[$p] = preg_replace('/[^0-9]/','',$shift_weekdays[$p]);
|
||||||
$SHIFT_weekdays .= "$shift_weekdays[$p]";
|
$SHIFT_weekdays .= "$shift_weekdays[$p]";
|
||||||
$p++;
|
$p++;
|
||||||
}
|
}
|
||||||
@@ -21276,6 +21288,7 @@ if ($ADD==494111111111)
|
|||||||
$report_weekdays_ct = count($report_weekdays);
|
$report_weekdays_ct = count($report_weekdays);
|
||||||
while ($p <= $report_weekdays_ct)
|
while ($p <= $report_weekdays_ct)
|
||||||
{
|
{
|
||||||
|
$report_weekdays[$p] = preg_replace('/[^0-9]/','',$report_weekdays[$p]);
|
||||||
$REPORT_weekdays .= "$report_weekdays[$p]";
|
$REPORT_weekdays .= "$report_weekdays[$p]";
|
||||||
$p++;
|
$p++;
|
||||||
}
|
}
|
||||||
@@ -34066,6 +34079,7 @@ if ($ADD==431)
|
|||||||
$dl_weekdays_ct = count($dl_weekdays);
|
$dl_weekdays_ct = count($dl_weekdays);
|
||||||
while ($p <= $dl_weekdays_ct)
|
while ($p <= $dl_weekdays_ct)
|
||||||
{
|
{
|
||||||
|
$dl_weekdays[$p] = preg_replace('/[^0-9]/','',$dl_weekdays[$p]);
|
||||||
$DL_weekdays .= "$dl_weekdays[$p]";
|
$DL_weekdays .= "$dl_weekdays[$p]";
|
||||||
$p++;
|
$p++;
|
||||||
}
|
}
|
||||||
@@ -34075,6 +34089,7 @@ if ($ADD==431)
|
|||||||
$p=0;
|
$p=0;
|
||||||
while ($p < $group_ct)
|
while ($p < $group_ct)
|
||||||
{
|
{
|
||||||
|
$groups[$p] = preg_replace('/[^-_0-9\p{L}]/u','',$groups[$p]);
|
||||||
$groups_value .= " $groups[$p]";
|
$groups_value .= " $groups[$p]";
|
||||||
$p++;
|
$p++;
|
||||||
}
|
}
|
||||||
@@ -44283,6 +44298,7 @@ if ($ADD==395111111111)
|
|||||||
$p=0; $ip_added=0; $ip_removed=0;
|
$p=0; $ip_added=0; $ip_removed=0;
|
||||||
while ($p < $PNct)
|
while ($p < $PNct)
|
||||||
{
|
{
|
||||||
|
$PN[$p] = preg_replace('/[^\,\:\+\*\#\.\_0-9\p{L}]/u','',$PN[$p]);
|
||||||
if (strlen($PN[$p]) > 0)
|
if (strlen($PN[$p]) > 0)
|
||||||
{
|
{
|
||||||
$PN[$p] = preg_replace("/\r|\n|\t/",'',$PN[$p]);
|
$PN[$p] = preg_replace("/\r|\n|\t/",'',$PN[$p]);
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
#
|
#
|
||||||
# functions for administrative scripts and reports
|
# functions for administrative scripts and reports
|
||||||
#
|
#
|
||||||
# Copyright (C) 2024 Matt Florell <vicidial@gmail.com> LICENSE: AGPLv2
|
# Copyright (C) 2026 Matt Florell <vicidial@gmail.com> LICENSE: AGPLv2
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# CHANGES:
|
# CHANGES:
|
||||||
@@ -44,9 +44,10 @@
|
|||||||
# 240401-1459 - Added check for vicidial_pending_ar entries in user_authorization
|
# 240401-1459 - Added check for vicidial_pending_ar entries in user_authorization
|
||||||
# 240801-1130 - Code updates for PHP8 compatibility
|
# 240801-1130 - Code updates for PHP8 compatibility
|
||||||
# 240805-2103 - Added PHP_error_reporting_OVERRIDE options
|
# 240805-2103 - Added PHP_error_reporting_OVERRIDE options
|
||||||
|
# 260521-1644 - Code updates for PHP8 compatibility, added ConvertToJSON function
|
||||||
#
|
#
|
||||||
|
|
||||||
$PHP_error_reporting_OVERRIDE=0;
|
$PHP_error_reporting_OVERRIDE=0; $php_err_suppression_value=0;
|
||||||
if (file_exists('options.php'))
|
if (file_exists('options.php'))
|
||||||
{
|
{
|
||||||
require('options.php');
|
require('options.php');
|
||||||
@@ -65,7 +66,7 @@ if ($PHP_error_reporting_OVERRIDE > 0)
|
|||||||
##### BEGIN validate user login credentials, check for failed lock out #####
|
##### BEGIN validate user login credentials, check for failed lock out #####
|
||||||
function user_authorization($user,$pass,$user_option,$user_update,$api_call)
|
function user_authorization($user,$pass,$user_option,$user_update,$api_call)
|
||||||
{
|
{
|
||||||
global $link,$php_script;
|
global $link,$php_script,$DB;
|
||||||
# require("dbconnect_mysqli.php");
|
# require("dbconnect_mysqli.php");
|
||||||
|
|
||||||
#############################################
|
#############################################
|
||||||
@@ -103,6 +104,7 @@ function user_authorization($user,$pass,$user_option,$user_update,$api_call)
|
|||||||
$pass = preg_replace("/\||`|&|\'|\"|\\\\|;| /","",$pass);
|
$pass = preg_replace("/\||`|&|\'|\"|\\\\|;| /","",$pass);
|
||||||
|
|
||||||
$passSQL = "pass='$pass'";
|
$passSQL = "pass='$pass'";
|
||||||
|
$login_problem=0;
|
||||||
|
|
||||||
if ($SSpass_hash_enabled > 0)
|
if ($SSpass_hash_enabled > 0)
|
||||||
{
|
{
|
||||||
@@ -401,6 +403,7 @@ function array_group_count($array, $sort = false)
|
|||||||
##### BEGIN bar chart using max stats data #####
|
##### BEGIN bar chart using max stats data #####
|
||||||
function horizontal_bar_chart($campaign_id,$days_graph,$title,$link,$metric,$metric_name,$more_link,$END_DATE,$download_link,$chart_title)
|
function horizontal_bar_chart($campaign_id,$days_graph,$title,$link,$metric,$metric_name,$more_link,$END_DATE,$download_link,$chart_title)
|
||||||
{
|
{
|
||||||
|
global $PHP_SELF;
|
||||||
$stats_start_time = time();
|
$stats_start_time = time();
|
||||||
if ($END_DATE)
|
if ($END_DATE)
|
||||||
{
|
{
|
||||||
@@ -501,7 +504,7 @@ function horizontal_bar_chart($campaign_id,$days_graph,$title,$link,$metric,$met
|
|||||||
|
|
||||||
|
|
||||||
##### BEGIN download max stats data #####
|
##### BEGIN download max stats data #####
|
||||||
function download_max_system_stats($campaign_id,$days_graph,$title,$metric,$metric_name,$END_DATE)
|
function download_max_system_stats($campaign_id,$days_graph,$title="",$metric,$metric_name,$END_DATE)
|
||||||
{
|
{
|
||||||
global $CSV_text, $link;
|
global $CSV_text, $link;
|
||||||
$stats_start_time = time();
|
$stats_start_time = time();
|
||||||
@@ -516,6 +519,7 @@ function download_max_system_stats($campaign_id,$days_graph,$title,$metric,$metr
|
|||||||
$Btotal_calls[0]=0;
|
$Btotal_calls[0]=0;
|
||||||
$link_text='';
|
$link_text='';
|
||||||
$i=0;
|
$i=0;
|
||||||
|
$max_count=0;
|
||||||
|
|
||||||
### get stats for last X days
|
### get stats for last X days
|
||||||
$stmt="SELECT stats_date,$metric from vicidial_daily_max_stats where campaign_id='$campaign_id' and stats_flag='OPEN' and stats_date<='$Bstats_date[0]';";
|
$stmt="SELECT stats_date,$metric from vicidial_daily_max_stats where campaign_id='$campaign_id' and stats_flag='OPEN' and stats_date<='$Bstats_date[0]';";
|
||||||
@@ -576,7 +580,7 @@ function download_max_system_stats($campaign_id,$days_graph,$title,$metric,$metr
|
|||||||
$i=0;
|
$i=0;
|
||||||
while($i < $days_graph)
|
while($i < $days_graph)
|
||||||
{
|
{
|
||||||
$bar_width = intval($max_multi * $Btotal_calls[$i]);
|
# $bar_width = intval($max_multi * $Btotal_calls[$i]);
|
||||||
if ($Btotal_calls[$i] < 1) {$Btotal_calls[$i] = "-none-";}
|
if ($Btotal_calls[$i] < 1) {$Btotal_calls[$i] = "-none-";}
|
||||||
$CSV_text.="\"$Bstats_date[$i]\",\"$Btotal_calls[$i]\"\n";
|
$CSV_text.="\"$Bstats_date[$i]\",\"$Btotal_calls[$i]\"\n";
|
||||||
$i++;
|
$i++;
|
||||||
@@ -592,7 +596,7 @@ function download_max_system_stats($campaign_id,$days_graph,$title,$metric,$metr
|
|||||||
|
|
||||||
function lookup_gmt($phone_code,$USarea,$state,$LOCAL_GMT_OFF_STD,$Shour,$Smin,$Ssec,$Smon,$Smday,$Syear,$postalgmt,$postal_code,$owner,$USprefix)
|
function lookup_gmt($phone_code,$USarea,$state,$LOCAL_GMT_OFF_STD,$Shour,$Smin,$Ssec,$Smon,$Smday,$Syear,$postalgmt,$postal_code,$owner,$USprefix)
|
||||||
{
|
{
|
||||||
global $link;
|
global $link, $DB, $DBX, $tz_method;
|
||||||
|
|
||||||
$postalgmt_found=0;
|
$postalgmt_found=0;
|
||||||
if ( (preg_match("/POSTAL/i",$postalgmt)) && (strlen($postal_code)>4) )
|
if ( (preg_match("/POSTAL/i",$postalgmt)) && (strlen($postal_code)>4) )
|
||||||
@@ -1393,9 +1397,11 @@ function lookup_gmt($phone_code,$USarea,$state,$LOCAL_GMT_OFF_STD,$Shour,$Smin,$
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function mysql_to_mysqli($stmt, $link)
|
function mysql_to_mysqli($stmt, $link, $debug=0)
|
||||||
{
|
{
|
||||||
|
if ($debug) {print $stmt."\n";}
|
||||||
$rslt=mysqli_query($link, $stmt);
|
$rslt=mysqli_query($link, $stmt);
|
||||||
|
if ($debug) {print " - ".mysqli_num_rows($rslt)."<BR>\n";}
|
||||||
return $rslt;
|
return $rslt;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1632,7 +1638,7 @@ if (isset($camp_lists))
|
|||||||
$g++;
|
$g++;
|
||||||
}
|
}
|
||||||
|
|
||||||
$stmt="SELECT call_time_id,call_time_name,call_time_comments,ct_default_start,ct_default_stop,ct_sunday_start,ct_sunday_stop,ct_monday_start,ct_monday_stop,ct_tuesday_start,ct_tuesday_stop,ct_wednesday_start,ct_wednesday_stop,ct_thursday_start,ct_thursday_stop,ct_friday_start,ct_friday_stop,ct_saturday_start,ct_saturday_stop,ct_state_call_times FROM vicidial_call_times where call_time_id='$local_call_time';";
|
$stmt="SELECT call_time_id,call_time_name,call_time_comments,ct_default_start,ct_default_stop,ct_sunday_start,ct_sunday_stop,ct_monday_start,ct_monday_stop,ct_tuesday_start,ct_tuesday_stop,ct_wednesday_start,ct_wednesday_stop,ct_thursday_start,ct_thursday_stop,ct_friday_start,ct_friday_stop,ct_saturday_start,ct_saturday_stop,ct_state_call_times,ct_holidays FROM vicidial_call_times where call_time_id='$local_call_time';";
|
||||||
if ($DB) {$dialable_output .= "$stmt\n";}
|
if ($DB) {$dialable_output .= "$stmt\n";}
|
||||||
$rslt=mysql_to_mysqli($stmt, $link);
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
$rowx=mysqli_fetch_row($rslt);
|
$rowx=mysqli_fetch_row($rslt);
|
||||||
@@ -1697,6 +1703,7 @@ if (isset($camp_lists))
|
|||||||
$ct_state_gmt_SQL = '';
|
$ct_state_gmt_SQL = '';
|
||||||
$ct_srs=0;
|
$ct_srs=0;
|
||||||
$b=0;
|
$b=0;
|
||||||
|
$state_rules=array();
|
||||||
if (strlen($Gct_state_call_times)>2)
|
if (strlen($Gct_state_call_times)>2)
|
||||||
{
|
{
|
||||||
$state_rules = explode('|',$Gct_state_call_times);
|
$state_rules = explode('|',$Gct_state_call_times);
|
||||||
@@ -1704,7 +1711,7 @@ if (isset($camp_lists))
|
|||||||
}
|
}
|
||||||
while($ct_srs >= $b)
|
while($ct_srs >= $b)
|
||||||
{
|
{
|
||||||
if (strlen($state_rules[$b])>1)
|
if (isset($state_rules[$b]) && strlen($state_rules[$b])>1)
|
||||||
{
|
{
|
||||||
$stmt="SELECT state_call_time_id,state_call_time_state,state_call_time_name,state_call_time_comments,sct_default_start,sct_default_stop,sct_sunday_start,sct_sunday_stop,sct_monday_start,sct_monday_stop,sct_tuesday_start,sct_tuesday_stop,sct_wednesday_start,sct_wednesday_stop,sct_thursday_start,sct_thursday_stop,sct_friday_start,sct_friday_stop,sct_saturday_start,sct_saturday_stop from vicidial_state_call_times where state_call_time_id='$state_rules[$b]';";
|
$stmt="SELECT state_call_time_id,state_call_time_state,state_call_time_name,state_call_time_comments,sct_default_start,sct_default_stop,sct_sunday_start,sct_sunday_stop,sct_monday_start,sct_monday_stop,sct_tuesday_start,sct_tuesday_stop,sct_wednesday_start,sct_wednesday_stop,sct_thursday_start,sct_thursday_stop,sct_friday_start,sct_friday_stop,sct_saturday_start,sct_saturday_stop from vicidial_state_call_times where state_call_time_id='$state_rules[$b]';";
|
||||||
$rslt=mysql_to_mysqli($stmt, $link);
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
@@ -1997,8 +2004,8 @@ if (isset($camp_lists))
|
|||||||
$o=0;
|
$o=0;
|
||||||
while ($Ds_to_print > $o)
|
while ($Ds_to_print > $o)
|
||||||
{
|
{
|
||||||
$o++;
|
|
||||||
$Dsql .= "'$Dstatuses[$o]',";
|
$Dsql .= "'$Dstatuses[$o]',";
|
||||||
|
$o++;
|
||||||
}
|
}
|
||||||
$Dsql = preg_replace("/,$/","",$Dsql);
|
$Dsql = preg_replace("/,$/","",$Dsql);
|
||||||
if (strlen($Dsql) < 2) {$Dsql = "''";}
|
if (strlen($Dsql) < 2) {$Dsql = "''";}
|
||||||
@@ -2046,6 +2053,8 @@ if (isset($camp_lists))
|
|||||||
if ($DB) {$dialable_output .= "$camplists_ct|$stmt\n";}
|
if ($DB) {$dialable_output .= "$camplists_ct|$stmt\n";}
|
||||||
$k=0;
|
$k=0;
|
||||||
$camp_lists='';
|
$camp_lists='';
|
||||||
|
$list_id_sql='';
|
||||||
|
$LCTlist_id_sql='';
|
||||||
while ($camplists_ct > $k)
|
while ($camplists_ct > $k)
|
||||||
{
|
{
|
||||||
$rowA = mysqli_fetch_row($rslt_list);
|
$rowA = mysqli_fetch_row($rslt_list);
|
||||||
@@ -2167,6 +2176,7 @@ if (isset($camp_lists))
|
|||||||
$ct_state_gmt_SQL = '';
|
$ct_state_gmt_SQL = '';
|
||||||
$ct_srs=0;
|
$ct_srs=0;
|
||||||
$b=0;
|
$b=0;
|
||||||
|
$state_rules=array();
|
||||||
if (strlen($Gct_state_call_times)>2)
|
if (strlen($Gct_state_call_times)>2)
|
||||||
{
|
{
|
||||||
$state_rules = explode('|',$Gct_state_call_times);
|
$state_rules = explode('|',$Gct_state_call_times);
|
||||||
@@ -2174,7 +2184,7 @@ if (isset($camp_lists))
|
|||||||
}
|
}
|
||||||
while($ct_srs >= $b)
|
while($ct_srs >= $b)
|
||||||
{
|
{
|
||||||
if (strlen($state_rules[$b])>1)
|
if (isset($state_rules[$b]) && strlen($state_rules[$b])>1)
|
||||||
{
|
{
|
||||||
$stmt = "SELECT state_call_time_id,state_call_time_state,state_call_time_name,state_call_time_comments,sct_default_start,sct_default_stop,sct_sunday_start,sct_sunday_stop,sct_monday_start,sct_monday_stop,sct_tuesday_start,sct_tuesday_stop,sct_wednesday_start,sct_wednesday_stop,sct_thursday_start,sct_thursday_stop,sct_friday_start,sct_friday_stop,sct_saturday_start,sct_saturday_stop,ct_holidays from vicidial_state_call_times where state_call_time_id='$state_rules[$b]';";
|
$stmt = "SELECT state_call_time_id,state_call_time_state,state_call_time_name,state_call_time_comments,sct_default_start,sct_default_stop,sct_sunday_start,sct_sunday_stop,sct_monday_start,sct_monday_stop,sct_tuesday_start,sct_tuesday_stop,sct_wednesday_start,sct_wednesday_stop,sct_thursday_start,sct_thursday_stop,sct_friday_start,sct_friday_stop,sct_saturday_start,sct_saturday_stop,ct_holidays from vicidial_state_call_times where state_call_time_id='$state_rules[$b]';";
|
||||||
$rslt=mysql_to_mysqli($stmt, $link);
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
@@ -2565,4 +2575,49 @@ if ($only_return < 1)
|
|||||||
|
|
||||||
##### END calculate what gmt_offset_now values are within the allowed local_call_time setting ###
|
##### END calculate what gmt_offset_now values are within the allowed local_call_time setting ###
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function ConvertToJSON($result,$result_reason,$header="",$data="",$key="")
|
||||||
|
{
|
||||||
|
$json_output="{\n\"result\": \"$result\",\n\"result_reason\": \"$result_reason\",\n";
|
||||||
|
$data=trim($data);
|
||||||
|
if (strlen($data)>0)
|
||||||
|
{
|
||||||
|
$json_output.="\n\"data\": [\n";
|
||||||
|
$row_array=explode("\n", $data);
|
||||||
|
|
||||||
|
if ($header=="YES")
|
||||||
|
{
|
||||||
|
$key_array=explode("|", $row_array[0]);
|
||||||
|
$i=1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$key_array=array();
|
||||||
|
$i=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ($i<count($row_array))
|
||||||
|
{
|
||||||
|
$json_output.="{";
|
||||||
|
|
||||||
|
$data_array=explode("|", $row_array[$i]);
|
||||||
|
for ($j=0; $j<count($data_array); $j++)
|
||||||
|
{
|
||||||
|
if (!isset($key_array[$j])) {$key_array[$j]="$j";}
|
||||||
|
|
||||||
|
$json_output.="\"".$key_array[$j]."\": \"".$data_array[$j]."\", ";
|
||||||
|
}
|
||||||
|
$json_output=preg_replace('/, $/', '', $json_output);
|
||||||
|
$json_output.="},\n";
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
|
$json_output=preg_replace('/,\n$/', '', $json_output);
|
||||||
|
$json_output.="\n]\n";
|
||||||
|
}
|
||||||
|
$json_output=preg_replace('/,\n$/', '', $json_output);
|
||||||
|
$json_output.="}";
|
||||||
|
|
||||||
|
return $json_output."\n";
|
||||||
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user