From 55203592b6bd6011ecff74a8ed0e1391d627460c Mon Sep 17 00:00:00 2001 From: tbradsha <32492176+tbradsha@users.noreply.github.com> Date: Wed, 26 Nov 2025 10:23:50 -0700 Subject: [PATCH 1/5] json_encode audit of CRM code --- .../plugins/crm/admin/dashboard/main.page.php | 5 +- .../first-use-dashboard-woo.block.php | 2 +- .../partials/first-use-dashboard.block.php | 2 +- .../crm/admin/settings/custom-fields.page.php | 4 +- .../crm/admin/settings/mail-delivery.ajax.php | 2 +- .../plugins/crm/admin/settings/tax.page.php | 2 +- .../plugins/crm/admin/support/main.page.php | 6 +- .../crm/includes/ZeroBSCRM.AdminStyling.php | 2 +- .../crm/includes/ZeroBSCRM.DAL3.Helpers.php | 12 - .../plugins/crm/includes/ZeroBSCRM.DAL3.php | 4 +- .../crm/includes/ZeroBSCRM.Edit.Segment.php | 185 +++++------ .../crm/includes/ZeroBSCRM.GeneralFuncs.php | 2 +- .../includes/ZeroBSCRM.InternalAutomator.php | 16 +- .../crm/includes/ZeroBSCRM.List.Tasks.php | 3 +- .../crm/includes/ZeroBSCRM.List.Views.php | 2 +- .../plugins/crm/includes/ZeroBSCRM.List.php | 23 +- .../plugins/crm/includes/ZeroBSCRM.Mail.php | 294 +++++++++--------- .../includes/ZeroBSCRM.MetaBoxes3.Logs.php | 14 +- .../ZeroBSCRM.MetaBoxes3.QuoteTemplates.php | 2 +- .../includes/ZeroBSCRM.MetaBoxes3.Tags.php | 6 +- .../crm/includes/ZeroBSCRM.Migrations.php | 2 +- .../includes/ZeroBSCRM.PerformanceTesting.php | 2 +- .../crm/includes/ZeroBSCRM.ScreenOptions.php | 7 +- .../crm/includes/ZeroBSCRM.ScriptsStyles.php | 16 +- .../crm/includes/ZeroBSCRM.TagManager.php | 2 +- .../crm/includes/ZeroBSCRM.WYSIWYGButtons.php | 4 +- .../automations/admin/admin-page-init.php | 2 +- .../mailpoet/admin/mailpoet-hub/main.page.php | 5 +- .../woo-sync/admin/woo-sync-hub/main.page.php | 5 +- .../class-woo-sync-background-sync-job.php | 8 +- .../workflow/class-workflow-repository.php | 4 +- 31 files changed, 328 insertions(+), 317 deletions(-) diff --git a/projects/plugins/crm/admin/dashboard/main.page.php b/projects/plugins/crm/admin/dashboard/main.page.php index b62482fb4224e..0757ec7e00413 100644 --- a/projects/plugins/crm/admin/dashboard/main.page.php +++ b/projects/plugins/crm/admin/dashboard/main.page.php @@ -407,12 +407,13 @@ function jpcrm_render_dashboard_page() { } } - $jpcrm_dash_data = 'const jpcrm_funnel_data = ' . wp_json_encode( $funnel_data ) . ';'; + $jpcrm_dash_data = 'const jpcrm_funnel_data = ' . wp_json_encode( $funnel_data, JSON_UNESCAPED_SLASHES | JSON_HEX_TAG | JSON_HEX_AMP ) . ';'; $jpcrm_dash_data .= 'const jpcrm_revenue_chart_data = ' . wp_json_encode( array( 'labels' => $labels, 'data' => $chartdata, - ) + ), + JSON_UNESCAPED_SLASHES | JSON_HEX_TAG | JSON_HEX_AMP ); wp_add_inline_script( 'jpcrm-dash', $jpcrm_dash_data, 'before' ); } diff --git a/projects/plugins/crm/admin/dashboard/partials/first-use-dashboard-woo.block.php b/projects/plugins/crm/admin/dashboard/partials/first-use-dashboard-woo.block.php index 99fe18b10a25d..99ec70c5fe7f3 100644 --- a/projects/plugins/crm/admin/dashboard/partials/first-use-dashboard-woo.block.php +++ b/projects/plugins/crm/admin/dashboard/partials/first-use-dashboard-woo.block.php @@ -101,7 +101,7 @@ - + - + ; - var wpzbscrmAcceptableTypes = ; + var wpzbscrmCustomFields = ; + var wpzbscrmAcceptableTypes = ; var wpzbscrm_settings_page = 'customfields'; // this fires init js in admin.settings.min.js var wpzbscrm_settings_lang = { diff --git a/projects/plugins/crm/admin/settings/mail-delivery.ajax.php b/projects/plugins/crm/admin/settings/mail-delivery.ajax.php index 1cb740aafa3c9..03e7629e3cd64 100644 --- a/projects/plugins/crm/admin/settings/mail-delivery.ajax.php +++ b/projects/plugins/crm/admin/settings/mail-delivery.ajax.php @@ -899,5 +899,5 @@ function zeroBSCRM_AJAX_mailDelivery_setMailDeliveryAsDefault() { // fini - lazy nocheck $res['success'] = 1; - echo wp_json_encode( $res ); + echo wp_json_encode( $res, JSON_UNESCAPED_SLASHES ); } diff --git a/projects/plugins/crm/admin/settings/tax.page.php b/projects/plugins/crm/admin/settings/tax.page.php index 669ed8650ccfa..4ee5968320beb 100644 --- a/projects/plugins/crm/admin/settings/tax.page.php +++ b/projects/plugins/crm/admin/settings/tax.page.php @@ -220,7 +220,7 @@ '; + echo ''; echo ''; $zbsadmincolors = $_wp_admin_css_colors[ $current_color ]->colors; ?> diff --git a/projects/plugins/crm/includes/ZeroBSCRM.DAL3.Helpers.php b/projects/plugins/crm/includes/ZeroBSCRM.DAL3.Helpers.php index ca243b490ac6c..7986ab5371d27 100644 --- a/projects/plugins/crm/includes/ZeroBSCRM.DAL3.Helpers.php +++ b/projects/plugins/crm/includes/ZeroBSCRM.DAL3.Helpers.php @@ -1574,18 +1574,6 @@ function zeroBSCRM_mergeCustomers($dominantID=-1,$slaveID=-1){ $slaveLogs = zeroBSCRM_getContactLogs($slaveID,true,10000,0); // id created name meta if (is_array($slaveLogs) && count($slaveLogs) > 0){ - /* in fact, just save as json encode :D - rough but quicker - // brutal str builder. - $logStr = ''; - - foreach ($slaveLogs as $log){ - - if (!empty($logStr)) $logStr .= "\r\n"; - - - } */ - - //update_post_meta($dominantID, 'zbs_merged_customer_log_bk_'.time(), json_encode($slaveLogs)); // no $change here, as this is kinda secret, kthx $zbs->DAL->updateMeta(ZBS_TYPE_CONTACT,$dominantID,'merged_customer_log_bk_'.time(),$slaveLogs); diff --git a/projects/plugins/crm/includes/ZeroBSCRM.DAL3.php b/projects/plugins/crm/includes/ZeroBSCRM.DAL3.php index e0f186e2da8ba..6f8abc6f66abb 100644 --- a/projects/plugins/crm/includes/ZeroBSCRM.DAL3.php +++ b/projects/plugins/crm/includes/ZeroBSCRM.DAL3.php @@ -2189,7 +2189,7 @@ public function addUpdateSetting($args=array()){ // WH note: it was necessary to add JSON_UNESCAPED_SLASHES to properly save down without issue // combined with a more complex zeroBSCRM_stripSlashes recurrsive // https://stackoverflow.com/questions/7282755/how-to-remove-backslash-on-json-encode-function - $data['val'] = json_encode($data['val'],JSON_UNESCAPED_SLASHES); + $data['val'] = wp_json_encode( $data['val'], JSON_UNESCAPED_SLASHES ); // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UndefinedVariable } @@ -2801,7 +2801,7 @@ public function addUpdateMeta($args=array()){ #} Var up any val (json_encode) if (in_array(gettype($data['val']),array("object","array"))){ - $data['val'] = json_encode($data['val']); + $data['val'] = wp_json_encode( $data['val'], JSON_UNESCAPED_SLASHES ); // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UndefinedVariable } diff --git a/projects/plugins/crm/includes/ZeroBSCRM.Edit.Segment.php b/projects/plugins/crm/includes/ZeroBSCRM.Edit.Segment.php index 7b3e9d982bb36..7dd7b53931f6e 100644 --- a/projects/plugins/crm/includes/ZeroBSCRM.Edit.Segment.php +++ b/projects/plugins/crm/includes/ZeroBSCRM.Edit.Segment.php @@ -163,100 +163,101 @@ function zeroBSCRM_html_addEditSegment($potentialID = -1) - - - - external_sources as $external_source_key => $external_source_info ) { + $external_source_array[] = array( + 'key' => $external_source_key, + 'name' => $external_source_info[0], + ); + } + + // sort by name + usort( + $external_source_array, + function ( $a, $b ) { + return strcmp( $a['key'], $b['key'] ); + } + ); + + // phpcs:disable WordPress.WP.I18n.TextDomainMismatch -- this is intentionally using the `mailpoet` text domain + $jpcrm_mailpoet_status_list = array( + array( + 'key' => 'subscribed', + 'name' => __( 'Subscribed', 'mailpoet' ), + ), + array( + 'key' => 'unconfirmed', + 'name' => __( 'Unconfirmed', 'mailpoet' ), + ), + array( + 'key' => 'unsubscribed', + 'name' => __( 'Unsubscribed', 'mailpoet' ), + ), + array( + 'key' => 'inactive', + 'name' => __( 'Inactive', 'mailpoet' ), + ), + array( + 'key' => 'bounced', + 'name' => __( 'Bounced', 'mailpoet' ), + ), + ); + // phpcs:enable WordPress.WP.I18n.TextDomainMismatch + ?> + + + + $fullcalendar_locale, 'events' => $calendar_events, 'firstDay' => (int) get_option( 'start_of_week', 0 ), - ) + ), + JSON_UNESCAPED_SLASHES | JSON_HEX_TAG | JSON_HEX_AMP ); ?> diff --git a/projects/plugins/crm/includes/ZeroBSCRM.List.Views.php b/projects/plugins/crm/includes/ZeroBSCRM.List.Views.php index 6bbb8fb483423..e6d1b338bcf58 100644 --- a/projects/plugins/crm/includes/ZeroBSCRM.List.Views.php +++ b/projects/plugins/crm/includes/ZeroBSCRM.List.Views.php @@ -29,7 +29,7 @@ function zeroBSCRM_render_customerslist_page() { // phpcs:ignore WordPress.Namin // extra_js: $status_array = $zbs->settings->get( 'customisedfields' )['customers']['status']; $statuses = is_array( $status_array ) && isset( $status_array[1] ) ? explode( ',', $status_array[1] ) : array(); - $extra_js = 'var zbsStatusesForBulkActions = ' . wp_json_encode( $statuses ) . ';'; + $extra_js = 'var zbsStatusesForBulkActions = ' . wp_json_encode( $statuses, JSON_UNESCAPED_SLASHES | JSON_HEX_TAG | JSON_HEX_AMP ) . ';'; // phpcs:ignore Squiz.PHP.CommentedOutCode.Found // Messages: diff --git a/projects/plugins/crm/includes/ZeroBSCRM.List.php b/projects/plugins/crm/includes/ZeroBSCRM.List.php index aeaa6e76a8519..1887ea14a4f04 100644 --- a/projects/plugins/crm/includes/ZeroBSCRM.List.php +++ b/projects/plugins/crm/includes/ZeroBSCRM.List.php @@ -400,9 +400,10 @@ public function drawListView(){ - // expose log types (For columns) - var zbsLogTypes = ; + // expose log types (For columns) + var zbsLogTypes = ; - // General options for listview - var zbsListViewSettings = ; + // General options for listview + var zbsListViewSettings = ; - // Vars for zbs list view drawer - var zbsListViewParams = ; + // Vars for zbs list view drawer + var zbsListViewParams = ; var zbsSortables = [ - var zbsListViewLangLabels = ; + var zbsListViewLangLabels = ; var zbsTagsForBulkActions = ; @@ -631,7 +632,7 @@ public function drawListView(){ // phpcs:disable WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase global $zbsCustomerFields; if ( is_array( $zbsCustomerFields['status'][3] ) ) { - echo wp_json_encode( $zbsCustomerFields['status'][3] ); + echo wp_json_encode( $zbsCustomerFields['status'][3], JSON_UNESCAPED_SLASHES | JSON_HEX_TAG | JSON_HEX_AMP ); } else { echo '[]'; } @@ -644,9 +645,9 @@ public function drawListView(){ // hardcoded customer perms atm $possible_owners = zeroBS_getPossibleOwners( array( 'zerobs_admin', 'zerobs_customermgr' ), true ); if ( ! is_array( $possible_owners ) ) { - echo wp_json_encode( array() ); + echo wp_json_encode( array(), JSON_UNESCAPED_SLASHES | JSON_HEX_TAG | JSON_HEX_AMP ); } else { - echo wp_json_encode( $possible_owners ); + echo wp_json_encode( $possible_owners, JSON_UNESCAPED_SLASHES | JSON_HEX_TAG | JSON_HEX_AMP ); } ?> diff --git a/projects/plugins/crm/includes/ZeroBSCRM.Mail.php b/projects/plugins/crm/includes/ZeroBSCRM.Mail.php index 4ab4a910970fd..6fea8a869858a 100644 --- a/projects/plugins/crm/includes/ZeroBSCRM.Mail.php +++ b/projects/plugins/crm/includes/ZeroBSCRM.Mail.php @@ -964,7 +964,7 @@ function zeroBSCRM_mailDelivery_checkSMTPDetails($sendFromName='',$sendFromEmail #} add to debug list + log tried $emailDebugs[] = $emailDebug; - $emailSettingsTried[] = json_encode($smtpSettings); + $emailSettingsTried[] = wp_json_encode( $smtpSettings, JSON_UNESCAPED_SLASHES ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase #} Analysis of send @@ -1063,57 +1063,58 @@ function zeroBSCRM_mailDelivery_checkSMTPDetails($sendFromName='',$sendFromEmail if (!empty($replacementPort)) $smtpSettings['port'] = $replacementPort; if (!empty($replacementSecurityMode)) $smtpSettings['security'] = $replacementSecurityMode; # tls, ssl, none - #} If not already tried, try that! - if (!in_array(json_encode($smtpSettings),$emailSettingsTried)){ - - // Re-test - $emailDebug = zeroBSCRM_mailDelivery_sendViaSMTP( - - #} SMTP Settings - $smtpSettings['host'],$smtpSettings['port'],$smtpSettings['user'],$smtpSettings['pass'], - #'tls', #tls ssl - switched for option: - $smtpSettings['security'], - #} FROM - $sendFromEmail,$sendFromName, - #} To - $emTo,'', - #} Deets - $emSubject,$emTextBody,$emHTMLBody, - #} Following returns debug - true,true - ); - - #} add to debug list + save tried settings - $emailDebugs[] = $emailDebug; - $emailSettingsTried[] = json_encode($smtpSettings); - - #} Analysis of send - THIS ISN'T DRY! - #success: or error: - if ( str_starts_with( $emailDebug, 'error:' ) ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase - - $emailWasSent = false; - $emailSentMsg = __('Your SMTP details do not allow mail to be sent. (A test email could not be successfully sent)',"zero-bs-crm"); - - #} various: - if ($emailDebug == 'error:SMTP connect() failed.'){ - $emailSentMsg .= " - ".__('This error suggests that your Port & Security settings are not correct, or that you have the wrong value for SMTP Host.',"zero-bs-crm"); - } - - } elseif ( str_starts_with( $emailDebug, 'success:' ) ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase - - $emailWasSent = true; - $emailSentMsg .= __("Success! Your SMTP details are correct. (A test email was successfully sent)","zero-bs-crm"); - - } - - $testCount++; - - } // if not already tested - - } // if any to test - - } + // If not already tried, try that! + // phpcs:disable WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase + if ( ! in_array( wp_json_encode( $smtpSettings, JSON_UNESCAPED_SLASHES ), $emailSettingsTried, true ) ) { + + // Re-test + $emailDebug = zeroBSCRM_mailDelivery_sendViaSMTP( + // SMTP Settings + $smtpSettings['host'], + $smtpSettings['port'], + $smtpSettings['user'], + $smtpSettings['pass'], + $smtpSettings['security'], + // FROM + $sendFromEmail, + $sendFromName, + // To + $emTo, + '', + // Deets + $emSubject, + $emTextBody, + $emHTMLBody, + // Following returns debug + true, + true + ); + + // add to debug list + save tried settings + $emailDebugs[] = $emailDebug; + $emailSettingsTried[] = wp_json_encode( $smtpSettings, JSON_UNESCAPED_SLASHES ); + + // Analysis of send - THIS ISN'T DRY! + // success: or error: + if ( str_starts_with( $emailDebug, 'error:' ) ) { + + $emailWasSent = false; + $emailSentMsg = __( 'Your SMTP details do not allow mail to be sent. (A test email could not be successfully sent)', 'zero-bs-crm' ); + + // various: + if ( $emailDebug === 'error:SMTP connect() failed.' ) { + $emailSentMsg .= ' + ' . __( 'This error suggests that your Port & Security settings are not correct, or that you have the wrong value for SMTP Host.', 'zero-bs-crm' ); + } + } elseif ( str_starts_with( $emailDebug, 'success:' ) ) { + $emailWasSent = true; + $emailSentMsg .= __( 'Success! Your SMTP details are correct. (A test email was successfully sent)', 'zero-bs-crm' ); + } + ++$testCount; + } // if not already tested + // phpcs:enable WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase + } // if any to test + } #} =============================================== #} ==== 3) If no success, switch security models, (ssl/tls->tls/ssl->none) @@ -1152,54 +1153,57 @@ function zeroBSCRM_mailDelivery_checkSMTPDetails($sendFromName='',$sendFromEmail } - #} If not already tried, try that! - if (!in_array(json_encode($smtpSettings),$emailSettingsTried)){ - - // Re-test - $emailDebug = zeroBSCRM_mailDelivery_sendViaSMTP( - #} SMTP Settings - $smtpSettings['host'],$smtpSettings['port'],$smtpSettings['user'],$smtpSettings['pass'], - #'tls', #tls ssl - switched for option: - $smtpSettings['security'], - #} FROM - $sendFromEmail,$sendFromName, - #} To - $emTo,'', - #} Deets - $emSubject,$emTextBody,$emHTMLBody, - #} Following returns debug - true,true - ); - - #} add to debug list + save tried settings - $emailDebugs[] = $emailDebug; - $emailSettingsTried[] = json_encode($smtpSettings); - - #} Analysis of send - THIS ISN'T DRY - #success: or error: - if ( str_starts_with( $emailDebug, 'error:' ) ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase - - $emailWasSent = false; - $emailSentMsg = __('Your SMTP details do not allow mail to be sent. (A test email could not be successfully sent)',"zero-bs-crm"); - - #} various: - if ($emailDebug == 'error:SMTP connect() failed.'){ - $emailSentMsg .= " - ".__('This error suggests that your Port & Security settings are not correct, or that you have the wrong value for SMTP Host.',"zero-bs-crm"); - } - - } elseif ( str_starts_with( $emailDebug, 'success:' ) ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase - - $emailWasSent = true; - $emailSentMsg .= __("Success! Your SMTP details are correct. (A test email was successfully sent)","zero-bs-crm"); - - } - - $testCount++; - - } // if not already tested - + // If not already tried, try that! + // phpcs:disable WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase + if ( ! in_array( wp_json_encode( $smtpSettings, JSON_UNESCAPED_SLASHES ), $emailSettingsTried, true ) ) { + + // Re-test + $emailDebug = zeroBSCRM_mailDelivery_sendViaSMTP( + // SMTP Settings + $smtpSettings['host'], + $smtpSettings['port'], + $smtpSettings['user'], + $smtpSettings['pass'], + $smtpSettings['security'], + // FROM + $sendFromEmail, + $sendFromName, + // To + $emTo, + '', + // Deets + $emSubject, + $emTextBody, + $emHTMLBody, + // Following returns debug + true, + true + ); + + // add to debug list + save tried settings + $emailDebugs[] = $emailDebug; + $emailSettingsTried[] = wp_json_encode( $smtpSettings, JSON_UNESCAPED_SLASHES ); + + // Analysis of send - THIS ISN'T DRY + // success: or error: + if ( str_starts_with( $emailDebug, 'error:' ) ) { + + $emailWasSent = false; + $emailSentMsg = __( 'Your SMTP details do not allow mail to be sent. (A test email could not be successfully sent)', 'zero-bs-crm' ); + + // various: + if ( $emailDebug === 'error:SMTP connect() failed.' ) { + $emailSentMsg .= ' + ' . __( 'This error suggests that your Port & Security settings are not correct, or that you have the wrong value for SMTP Host.', 'zero-bs-crm' ); + } + } elseif ( str_starts_with( $emailDebug, 'success:' ) ) { + $emailWasSent = true; + $emailSentMsg .= __( 'Success! Your SMTP details are correct. (A test email was successfully sent)', 'zero-bs-crm' ); } + ++$testCount; + } // if not already tested + // phpcs:enable WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase + } #} =============================================== #} ==== 4) If no success, and is 587, try without TLS @@ -1218,51 +1222,57 @@ function zeroBSCRM_mailDelivery_checkSMTPDetails($sendFromName='',$sendFromEmail } - #} If not already tried, try that! - if (!in_array(json_encode($smtpSettings),$emailSettingsTried)){ - - // Re-test - $emailDebug = zeroBSCRM_mailDelivery_sendViaSMTP( - #} SMTP Settings - $smtpSettings['host'],$smtpSettings['port'],$smtpSettings['user'],$smtpSettings['pass'], - #'tls', #tls ssl - switched for option: - $smtpSettings['security'], - #} FROM - $sendFromEmail,$sendFromName, - #} To - $emTo,'', - #} Deets - $emSubject,$emTextBody,$emHTMLBody, - #} Following returns debug - true,true - ); - - #} add to debug list + save tried settings - $emailDebugs[] = $emailDebug; - $emailSettingsTried[] = json_encode($smtpSettings); - - #} Analysis of send - THIS ISN'T DRY - #success: or error: - if ( str_starts_with( $emailDebug, 'error:' ) ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase - - $emailWasSent = false; - $emailSentMsg = __('Your SMTP details do not allow mail to be sent. (A test email could not be successfully sent)',"zero-bs-crm"); - - #} various: - if ($emailDebug == 'error:SMTP connect() failed.'){ - $emailSentMsg .= " - ".__('This error suggests that your Port & Security settings are not correct, or that you have the wrong value for SMTP Host.',"zero-bs-crm"); - } - - } elseif ( str_starts_with( $emailDebug, 'success:' ) ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase - - $emailWasSent = true; - $emailSentMsg .= __("Success! Your SMTP details are correct. (A test email was successfully sent)","zero-bs-crm"); - - } + // If not already tried, try that! + // phpcs:disable WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase + if ( ! in_array( wp_json_encode( $smtpSettings, JSON_UNESCAPED_SLASHES ), $emailSettingsTried, true ) ) { + + // Re-test + $emailDebug = zeroBSCRM_mailDelivery_sendViaSMTP( + // SMTP Settings + $smtpSettings['host'], + $smtpSettings['port'], + $smtpSettings['user'], + $smtpSettings['pass'], + $smtpSettings['security'], + // FROM + $sendFromEmail, + $sendFromName, + // To + $emTo, + '', + // Deets + $emSubject, + $emTextBody, + $emHTMLBody, + // Following returns debug + true, + true + ); + + // add to debug list + save tried settings + $emailDebugs[] = $emailDebug; + $emailSettingsTried[] = wp_json_encode( $smtpSettings, JSON_UNESCAPED_SLASHES ); + + // Analysis of send - THIS ISN'T DRY + // success: or error: + if ( str_starts_with( $emailDebug, 'error:' ) ) { + + $emailWasSent = false; + $emailSentMsg = __( 'Your SMTP details do not allow mail to be sent. (A test email could not be successfully sent)', 'zero-bs-crm' ); + + // various: + if ( $emailDebug === 'error:SMTP connect() failed.' ) { + $emailSentMsg .= ' + ' . __( 'This error suggests that your Port & Security settings are not correct, or that you have the wrong value for SMTP Host.', 'zero-bs-crm' ); + } + } elseif ( str_starts_with( $emailDebug, 'success:' ) ) { + $emailWasSent = true; + $emailSentMsg .= __( 'Success! Your SMTP details are correct. (A test email was successfully sent)', 'zero-bs-crm' ); + } - ++$testCount; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase + ++$testCount; } // if not already tested + // phpcs:enable WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase } #} Return diff --git a/projects/plugins/crm/includes/ZeroBSCRM.MetaBoxes3.Logs.php b/projects/plugins/crm/includes/ZeroBSCRM.MetaBoxes3.Logs.php index 4c392b333913a..d6764e1494c21 100644 --- a/projects/plugins/crm/includes/ZeroBSCRM.MetaBoxes3.Logs.php +++ b/projects/plugins/crm/includes/ZeroBSCRM.MetaBoxes3.Logs.php @@ -333,7 +333,7 @@ public function html( $obj, $metabox ) { '; + echo ''; // for mvp v3.0 we now just hard-type these, as there a lesser obj rarely used. $fields = array( diff --git a/projects/plugins/crm/includes/ZeroBSCRM.MetaBoxes3.Tags.php b/projects/plugins/crm/includes/ZeroBSCRM.MetaBoxes3.Tags.php index 838b0842f3b0c..bf28ca6fe6806 100644 --- a/projects/plugins/crm/includes/ZeroBSCRM.MetaBoxes3.Tags.php +++ b/projects/plugins/crm/includes/ZeroBSCRM.MetaBoxes3.Tags.php @@ -150,11 +150,11 @@ public function html( $obj, $metabox ) { - + update( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching $ZBSCRM_t['meta'], // phpcs:ignore WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase array( - 'zbsm_val' => wp_json_encode( $new_file_array ), + 'zbsm_val' => wp_json_encode( $new_file_array, JSON_UNESCAPED_SLASHES ), 'zbsm_lastupdated' => time(), ), array( 'ID' => $meta_row->ID ), diff --git a/projects/plugins/crm/includes/ZeroBSCRM.PerformanceTesting.php b/projects/plugins/crm/includes/ZeroBSCRM.PerformanceTesting.php index 8d28adb2d6978..252a02829acb5 100644 --- a/projects/plugins/crm/includes/ZeroBSCRM.PerformanceTesting.php +++ b/projects/plugins/crm/includes/ZeroBSCRM.PerformanceTesting.php @@ -121,7 +121,7 @@ function zeroBSCRM_performanceTest_debugOut(){ echo '

'.$sTime.$sTimeExtra.' seconds

'; $retArr = $v; $retArr['took'] = $sTime; - $scriptVer .= 'console.log("'.$k.': '.$sTime.$sTimeExtra.'",'.json_encode($retArr).');'; + $scriptVer .= 'console.log("' . $k . ': ' . $sTime . $sTimeExtra . '",' . wp_json_encode( $retArr, JSON_UNESCAPED_SLASHES | JSON_HEX_TAG | JSON_HEX_AMP ) . ');'; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase } echo ''; diff --git a/projects/plugins/crm/includes/ZeroBSCRM.ScreenOptions.php b/projects/plugins/crm/includes/ZeroBSCRM.ScreenOptions.php index ee9128de58367..bdfbf858b8ca5 100644 --- a/projects/plugins/crm/includes/ZeroBSCRM.ScreenOptions.php +++ b/projects/plugins/crm/includes/ZeroBSCRM.ScreenOptions.php @@ -213,7 +213,12 @@ function zeroBS_outputScreenOptions(){ $screenOpts = $zbs->global_screen_options(); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase - ?> + + ; + var zbsCRMJS_currentTags = ; jQuery(function($){ console.log("======= TAG MANAGER VIEW UI ========="); diff --git a/projects/plugins/crm/includes/ZeroBSCRM.WYSIWYGButtons.php b/projects/plugins/crm/includes/ZeroBSCRM.WYSIWYGButtons.php index bf37aaf8232d1..e57ad17537339 100644 --- a/projects/plugins/crm/includes/ZeroBSCRM.WYSIWYGButtons.php +++ b/projects/plugins/crm/includes/ZeroBSCRM.WYSIWYGButtons.php @@ -66,7 +66,9 @@ function zeroBSCRM_exposeFormListJS(){ } } - ?> + + + + + + debug( 'Company import failed: ' . json_encode( $crm_object_data['company'] ) . '' ); + $this->debug( 'Company import failed: ' . wp_json_encode( $crm_object_data['company'], JSON_UNESCAPED_SLASHES | JSON_HEX_TAG | JSON_HEX_AMP ) . '' ); } @@ -901,7 +901,7 @@ public function import_crm_object_data( $crm_object_data ) { } else { // failed to add contact? - $this->debug( 'Contact import failed, or there was no contact to import. Contact Data: ' . json_encode( $crm_object_data['contact'] ) . '' ); + $this->debug( 'Contact import failed, or there was no contact to import. Contact Data: ' . wp_json_encode( $crm_object_data['contact'], JSON_UNESCAPED_SLASHES | JSON_HEX_TAG | JSON_HEX_AMP ) . '' ); } @@ -941,7 +941,7 @@ public function import_crm_object_data( $crm_object_data ) { } else { - $this->debug( 'invoice import failed: ' . json_encode( $crm_object_data['invoice'] ) . '' ); + $this->debug( 'invoice import failed: ' . wp_json_encode( $crm_object_data['invoice'], JSON_UNESCAPED_SLASHES | JSON_HEX_TAG | JSON_HEX_AMP ) . '' ); } @@ -991,7 +991,7 @@ public function import_crm_object_data( $crm_object_data ) { } else { - $this->debug( 'Transaction import failed: ' . json_encode( $crm_object_data['transaction'] ) . '' ); + $this->debug( 'Transaction import failed: ' . wp_json_encode( $crm_object_data['transaction'], JSON_UNESCAPED_SLASHES | JSON_HEX_TAG | JSON_HEX_AMP ) . '' ); } diff --git a/projects/plugins/crm/src/automation/workflow/class-workflow-repository.php b/projects/plugins/crm/src/automation/workflow/class-workflow-repository.php index d1dde68ff65a9..53cb76f8c54d9 100644 --- a/projects/plugins/crm/src/automation/workflow/class-workflow-repository.php +++ b/projects/plugins/crm/src/automation/workflow/class-workflow-repository.php @@ -180,8 +180,8 @@ public function persist( Automation_Workflow $workflow ): void { protected function prepare_data_to_persist( Automation_Workflow $workflow ): array { $data = $workflow->to_array(); - $data['triggers'] = wp_json_encode( $data['triggers'] ); - $data['steps'] = wp_json_encode( $data['steps'] ); + $data['triggers'] = wp_json_encode( $data['triggers'], JSON_UNESCAPED_SLASHES ); + $data['steps'] = wp_json_encode( $data['steps'], JSON_UNESCAPED_SLASHES ); return $data; } From 2ef3f975afe1b6cad3f4b23bcdc4119a716edbc9 Mon Sep 17 00:00:00 2001 From: tbradsha <32492176+tbradsha@users.noreply.github.com> Date: Wed, 26 Nov 2025 10:26:20 -0700 Subject: [PATCH 2/5] Add changelog --- .../crm/changelog/fix-crm-audit_json_encode_flags_part_deux | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 projects/plugins/crm/changelog/fix-crm-audit_json_encode_flags_part_deux diff --git a/projects/plugins/crm/changelog/fix-crm-audit_json_encode_flags_part_deux b/projects/plugins/crm/changelog/fix-crm-audit_json_encode_flags_part_deux new file mode 100644 index 0000000000000..7d5053df2fc27 --- /dev/null +++ b/projects/plugins/crm/changelog/fix-crm-audit_json_encode_flags_part_deux @@ -0,0 +1,4 @@ +Significance: patch +Type: fixed + +Ensure proper flags are used with `json_escape()`. From ae9ca1be09dd3036429890e6ac74fd245bb29cd2 Mon Sep 17 00:00:00 2001 From: tbradsha <32492176+tbradsha@users.noreply.github.com> Date: Wed, 26 Nov 2025 11:27:50 -0700 Subject: [PATCH 3/5] Fix typo --- .../crm/changelog/fix-crm-audit_json_encode_flags_part_deux | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/plugins/crm/changelog/fix-crm-audit_json_encode_flags_part_deux b/projects/plugins/crm/changelog/fix-crm-audit_json_encode_flags_part_deux index 7d5053df2fc27..f140a52a9274c 100644 --- a/projects/plugins/crm/changelog/fix-crm-audit_json_encode_flags_part_deux +++ b/projects/plugins/crm/changelog/fix-crm-audit_json_encode_flags_part_deux @@ -1,4 +1,4 @@ Significance: patch Type: fixed -Ensure proper flags are used with `json_escape()`. +Ensure proper flags are used with `json_encode()`. From 53caab66b9d6d0af799be965869792f17cbd8377 Mon Sep 17 00:00:00 2001 From: tbradsha <32492176+tbradsha@users.noreply.github.com> Date: Wed, 26 Nov 2025 13:39:35 -0700 Subject: [PATCH 4/5] Apply tweaks from code review Co-authored-by: Brad Jorsch --- projects/plugins/crm/admin/support/main.page.php | 2 +- projects/plugins/crm/includes/ZeroBSCRM.Edit.Segment.php | 2 +- projects/plugins/crm/includes/ZeroBSCRM.ScreenOptions.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/projects/plugins/crm/admin/support/main.page.php b/projects/plugins/crm/admin/support/main.page.php index 644e853fa0205..c5ba90631296b 100644 --- a/projects/plugins/crm/admin/support/main.page.php +++ b/projects/plugins/crm/admin/support/main.page.php @@ -207,7 +207,7 @@
Site URL:
License:
- Site data:
+ Site data:
diff --git a/projects/plugins/crm/includes/ZeroBSCRM.Edit.Segment.php b/projects/plugins/crm/includes/ZeroBSCRM.Edit.Segment.php index 7dd7b53931f6e..0e79de459df49 100644 --- a/projects/plugins/crm/includes/ZeroBSCRM.Edit.Segment.php +++ b/projects/plugins/crm/includes/ZeroBSCRM.Edit.Segment.php @@ -218,7 +218,7 @@ function ( $a, $b ) { var zbsSegmentStemURL = ''; var jpcrm_contact_stem_URL = ''; var zbsSegmentListURL = 'slugs['segments'] ); ?>'; - var zbsSegmentSEC = ''; + var zbsSegmentSEC = ; var zbsSegmentLang = { generalerrortitle: '', generalerror: '', diff --git a/projects/plugins/crm/includes/ZeroBSCRM.ScreenOptions.php b/projects/plugins/crm/includes/ZeroBSCRM.ScreenOptions.php index bdfbf858b8ca5..b7f545fe39810 100644 --- a/projects/plugins/crm/includes/ZeroBSCRM.ScreenOptions.php +++ b/projects/plugins/crm/includes/ZeroBSCRM.ScreenOptions.php @@ -215,7 +215,7 @@ function zeroBS_outputScreenOptions(){ ?> Date: Wed, 26 Nov 2025 13:50:36 -0700 Subject: [PATCH 5/5] Downgrade Phan baseline --- projects/plugins/crm/.phan/baseline.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/plugins/crm/.phan/baseline.php b/projects/plugins/crm/.phan/baseline.php index a4104157706b6..7158fdfd6beba 100644 --- a/projects/plugins/crm/.phan/baseline.php +++ b/projects/plugins/crm/.phan/baseline.php @@ -181,7 +181,7 @@ 'includes/ZeroBSCRM.DAL3.Obj.Segments.php' => ['PhanEmptyForeach', 'PhanPluginNeverReturnMethod', 'PhanPluginUnreachableCode', 'PhanRedundantCondition', 'PhanTypeArraySuspiciousNullable', 'PhanTypeMismatchDefault', 'PhanTypeMismatchReturn', 'PhanTypeMismatchReturnProbablyReal', 'PhanUndeclaredMethod', 'PhanUndeclaredVariable', 'PhanUnextractableAnnotationElementName'], 'includes/ZeroBSCRM.DAL3.Obj.Transactions.php' => ['PhanCommentParamWithoutRealParam', 'PhanEmptyForeach', 'PhanImpossibleTypeComparison', 'PhanNoopBinaryOperator', 'PhanPluginDuplicateConditionalNullCoalescing', 'PhanPluginDuplicateExpressionAssignmentOperation', 'PhanPluginRedundantAssignment', 'PhanPluginUnreachableCode', 'PhanPossiblyUndeclaredVariable', 'PhanRedundantCondition', 'PhanSuspiciousValueComparison', 'PhanSuspiciousWeakTypeComparison', 'PhanTypeArraySuspicious', 'PhanTypeArraySuspiciousNull', 'PhanTypeArraySuspiciousNullable', 'PhanTypeComparisonFromArray', 'PhanTypeComparisonToArray', 'PhanTypeConversionFromArray', 'PhanTypeExpectedObjectPropAccess', 'PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentInternalReal', 'PhanTypeMismatchArgumentNullable', 'PhanTypeMismatchArgumentNullableInternal', 'PhanTypeMismatchArgumentProbablyReal', 'PhanTypeMismatchDefault', 'PhanTypeMismatchDimFetchNullable', 'PhanTypeMismatchForeach', 'PhanTypeMismatchReturn', 'PhanTypeMismatchReturnNullable', 'PhanTypeMismatchReturnProbablyReal', 'PhanTypePossiblyInvalidDimOffset', 'PhanUndeclaredVariable', 'PhanUndeclaredVariableDim', 'PhanUnextractableAnnotationElementName'], 'includes/ZeroBSCRM.DAL3.ObjectLayer.php' => ['PhanCommentParamWithoutRealParam', 'PhanEmptyForeach', 'PhanPluginDuplicateConditionalNullCoalescing', 'PhanPluginDuplicateExpressionAssignmentOperation', 'PhanPossiblyUndeclaredVariable', 'PhanRedundantCondition', 'PhanTypeArraySuspicious', 'PhanTypeExpectedObjectPropAccess', 'PhanTypeMismatchArgumentInternal', 'PhanTypeMismatchArgumentInternalProbablyReal', 'PhanTypeMismatchDefault', 'PhanTypeMismatchForeach', 'PhanTypeMismatchReturn', 'PhanTypeMismatchReturnNullable', 'PhanTypeMismatchReturnProbablyReal', 'PhanUndeclaredFunction', 'PhanUnextractableAnnotationElementName'], - 'includes/ZeroBSCRM.DAL3.php' => ['PhanAccessMethodPrivate', 'PhanCommentParamWithoutRealParam', 'PhanPluginDuplicateConditionalNullCoalescing', 'PhanPluginDuplicateExpressionAssignmentOperation', 'PhanPluginRedundantAssignment', 'PhanPluginUnreachableCode', 'PhanPossiblyUndeclaredVariable', 'PhanRedundantCondition', 'PhanSuspiciousValueComparison', 'PhanSuspiciousWeakTypeComparison', 'PhanSuspiciousWeakTypeComparisonInLoop', 'PhanTypeArraySuspiciousNull', 'PhanTypeArraySuspiciousNullable', 'PhanTypeComparisonFromArray', 'PhanTypeExpectedObjectPropAccess', 'PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentInternal', 'PhanTypeMismatchArgumentInternalReal', 'PhanTypeMismatchArgumentProbablyReal', 'PhanTypeMismatchDefault', 'PhanTypeMismatchForeach', 'PhanTypeMismatchReturn', 'PhanTypeMismatchReturnProbablyReal', 'PhanUndeclaredMethod', 'PhanUndeclaredTypeParameter', 'PhanUndeclaredTypeReturnType', 'PhanUndeclaredVariable', 'PhanUnextractableAnnotationElementName', 'PhanUnextractableAnnotationSuffix'], + 'includes/ZeroBSCRM.DAL3.php' => ['PhanAccessMethodPrivate', 'PhanCommentParamWithoutRealParam', 'PhanPluginDuplicateConditionalNullCoalescing', 'PhanPluginDuplicateExpressionAssignmentOperation', 'PhanPluginRedundantAssignment', 'PhanPluginUnreachableCode', 'PhanPossiblyUndeclaredVariable', 'PhanRedundantCondition', 'PhanSuspiciousValueComparison', 'PhanSuspiciousWeakTypeComparison', 'PhanSuspiciousWeakTypeComparisonInLoop', 'PhanTypeArraySuspiciousNull', 'PhanTypeArraySuspiciousNullable', 'PhanTypeComparisonFromArray', 'PhanTypeExpectedObjectPropAccess', 'PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentInternal', 'PhanTypeMismatchArgumentInternalReal', 'PhanTypeMismatchArgumentProbablyReal', 'PhanTypeMismatchDefault', 'PhanTypeMismatchForeach', 'PhanTypeMismatchReturn', 'PhanTypeMismatchReturnProbablyReal', 'PhanTypePossiblyInvalidDimOffset', 'PhanUndeclaredMethod', 'PhanUndeclaredTypeParameter', 'PhanUndeclaredTypeReturnType', 'PhanUndeclaredVariable', 'PhanUnextractableAnnotationElementName', 'PhanUnextractableAnnotationSuffix'], 'includes/ZeroBSCRM.DataIOValidation.php' => ['PhanTypeMismatchArgument'], 'includes/ZeroBSCRM.Database.php' => ['PhanRedundantCondition', 'PhanSuspiciousValueComparison'], 'includes/ZeroBSCRM.Delete.php' => ['PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentInternal'],