Files
LiveCartaWP/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/admin/class-cmatic-admin-panel.php

212 lines
6.6 KiB
PHP

<?php
/**
* CF7 admin panel integration.
*
* @package contact-form-7-mailchimp-extension
* @author renzo.johnson@gmail.com
* @copyright 2014-2026 https://renzojohnson.com
* @license GPL-3.0+
*/
defined( 'ABSPATH' ) || exit;
final class Cmatic_Admin_Panel {
private const PANEL_KEY = 'Chimpmatic';
public static function init(): void {
add_filter( 'wpcf7_editor_panels', array( __CLASS__, 'register_panel' ) );
add_action( 'wpcf7_after_save', array( __CLASS__, 'save_settings' ) );
add_action( 'wpcf7_admin_misc_pub_section', array( __CLASS__, 'render_sidebar_info' ) );
add_action( 'wpcf7_admin_footer', array( __CLASS__, 'render_footer_banner' ), 10, 1 );
}
public static function register_panel( array $panels ): array {
if ( defined( 'CMATIC_VERSION' ) ) {
return $panels;
}
$post_id = isset( $_GET['post'] ) ? absint( $_GET['post'] ) : 0; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
if ( ! current_user_can( 'wpcf7_edit_contact_form', $post_id ) ) {
return $panels;
}
$panels[ self::PANEL_KEY ] = array(
'title' => __( 'Chimpmatic', 'chimpmatic-lite' ),
'callback' => array( __CLASS__, 'render_panel' ),
);
return $panels;
}
public static function render_panel( $contact_form ): void {
$form_id = $contact_form->id() ?? 0;
$cf7_mch = get_option( 'cf7_mch_' . $form_id, array() );
$cf7_mch = is_array( $cf7_mch ) ? $cf7_mch : array();
$form_tags = Cmatic_Form_Tags::get_tags_with_types( $contact_form );
$api_valid = (int) ( $cf7_mch['api-validation'] ?? 0 );
$list_data = isset( $cf7_mch['lisdata'] ) && is_array( $cf7_mch['lisdata'] ) ? $cf7_mch['lisdata'] : null;
// Render container.
if ( class_exists( 'Cmatic_Data_Container' ) ) {
Cmatic_Data_Container::render_open( $form_id, (string) $api_valid );
} else {
echo '<div class="cmatic-inner">';
}
// Header.
if ( class_exists( 'Cmatic_Header' ) ) {
$api_status = ( 1 === $api_valid ) ? 'connected' : ( ( 0 === $api_valid ) ? 'disconnected' : null );
Cmatic_Header::output( array( 'api_status' => $api_status ) );
}
echo '<div class="cmatic-content">';
// API Panel.
Cmatic_Api_Panel::render( $cf7_mch, (string) $api_valid );
// Audiences.
if ( class_exists( 'Cmatic_Audiences' ) ) {
Cmatic_Audiences::render( (string) $api_valid, $list_data, $cf7_mch );
}
// Field mapping.
Cmatic_Field_Mapper_UI::render( $api_valid, $list_data, $cf7_mch, $form_tags, $form_id );
// Toggles.
Cmatic_Panel_Toggles::cmatic_render();
// Contact Lookup.
if ( class_exists( 'Cmatic_Contact_Lookup' ) ) {
Cmatic_Contact_Lookup::cmatic_render( array( 'form_id' => $form_id ) );
}
// Log Viewer.
Cmatic_Log_Viewer::render();
// Advanced Settings.
echo '<div id="cme-container" class="mce-custom-fields vc-advanced-settings">';
Cmatic_Advanced_Settings::render();
echo '</div>';
// Welcome banner.
echo '<div class="vc-hidden-start dev-cta mce-cta welcome-panel">';
echo '<div class="welcome-panel-content">';
echo Cmatic_Banners::get_welcome(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo '</div></div>';
echo '</div>'; // .cmatic-content
if ( class_exists( 'Cmatic_Data_Container' ) ) {
Cmatic_Data_Container::render_close();
} else {
echo '</div>';
}
}
public static function save_settings( $contact_form ): void {
if ( ! isset( $_POST['wpcf7-mailchimp'] ) ) {
return;
}
// Verify nonce (defense-in-depth, CF7 already checked at request level).
$form_id = $contact_form->id();
$nonce_action = sprintf( 'wpcf7-save-contact-form_%s', $form_id );
$nonce = isset( $_REQUEST['_wpnonce'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['_wpnonce'] ) ) : '';
if ( ! wp_verify_nonce( $nonce, $nonce_action ) ) {
return;
}
// Verify capability.
if ( ! current_user_can( 'wpcf7_edit_contact_form', $form_id ) ) {
return;
}
// Trigger telemetry.
if ( class_exists( 'Cmatic\\Metrics\\Core\\Sync' ) && class_exists( 'Cmatic\\Metrics\\Core\\Collector' ) ) {
$payload = \Cmatic\Metrics\Core\Collector::collect( 'form_saved' );
\Cmatic\Metrics\Core\Sync::send( $payload );
}
$option_name = 'cf7_mch_' . $form_id;
$old_settings = get_option( $option_name, array() );
$posted_data = $_POST['wpcf7-mailchimp']; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Sanitized in sanitize_settings().
$sanitized = self::sanitize_settings( $posted_data, $old_settings );
if ( empty( $sanitized['api'] ) ) {
delete_option( $option_name );
return;
}
$updated_settings = array_merge( $old_settings, $sanitized );
// Remove excess field mappings beyond lite limit.
$max_field_index = CMATIC_LITE_FIELDS + 2;
for ( $i = $max_field_index + 1; $i <= 20; $i++ ) {
$field_key = 'field' . $i;
if ( isset( $updated_settings[ $field_key ] ) ) {
unset( $updated_settings[ $field_key ] );
}
}
update_option( $option_name, $updated_settings );
}
private static function sanitize_settings( array $posted, array $old ): array {
$sanitized = array();
$text_fields = array( 'api', 'list', 'accept' );
// Add field mappings.
$max_index = CMATIC_LITE_FIELDS + 2;
for ( $i = 3; $i <= $max_index; $i++ ) {
$text_fields[] = 'field' . $i;
}
// Add custom fields.
for ( $i = 1; $i <= 10; $i++ ) {
$text_fields[] = 'CustomValue' . $i;
$text_fields[] = 'CustomKey' . $i;
}
// Sanitize text fields.
foreach ( $text_fields as $field ) {
if ( isset( $posted[ $field ] ) ) {
$value = trim( sanitize_text_field( $posted[ $field ] ) );
if ( '' !== $value ) {
$sanitized[ $field ] = $value;
}
}
}
// Preserve masked API key.
if ( isset( $sanitized['api'] ) && strpos( $sanitized['api'], '•' ) !== false ) {
if ( ! empty( $old['api'] ) && strpos( $old['api'], '•' ) === false ) {
$sanitized['api'] = $old['api'];
}
}
// Per-form checkbox fields (global toggles handled via REST API, not here).
$checkboxes = array( 'cfactive', 'addunsubscr' );
foreach ( $checkboxes as $field ) {
$sanitized[ $field ] = isset( $posted[ $field ] ) ? '1' : '0';
}
// Select field: confsubs (double opt-in) - preserve actual value.
$sanitized['confsubs'] = isset( $posted['confsubs'] ) && '1' === $posted['confsubs'] ? '1' : '0';
return $sanitized;
}
public static function render_sidebar_info( int $post_id ): void {
Cmatic_Sidebar_Panel::render_submit_info( $post_id );
}
public static function render_footer_banner( $post ): void { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.Found
Cmatic_Sidebar_Panel::render_footer_promo();
}
private function __construct() {}
}