Changed source root directory

This commit is contained in:
2026-03-05 16:30:11 +01:00
parent dc85447ee1
commit 538f85d7a2
5868 changed files with 749734 additions and 99 deletions

View File

@@ -0,0 +1,211 @@
<?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() {}
}

View File

@@ -0,0 +1,260 @@
<?php
/**
* Admin asset loader.
*
* @package contact-form-7-mailchimp-extension
* @author renzo.johnson@gmail.com
* @copyright 2014-2026 https://renzojohnson.com
* @license GPL-3.0+
*/
defined( 'ABSPATH' ) || exit;
if ( ! class_exists( 'Cmatic_Asset_Loader' ) ) {
class Cmatic_Asset_Loader {
private static array $scripts = array();
private static array $styles = array();
public static function init(): void {
add_action( 'admin_enqueue_scripts', array( __CLASS__, 'enqueue_admin_assets' ) );
add_action( 'admin_enqueue_scripts', array( __CLASS__, 'enqueue_notices_script' ) );
add_action( 'admin_enqueue_scripts', array( __CLASS__, 'enqueue_cf7_frontend_styles' ) );
add_filter( 'admin_body_class', array( __CLASS__, 'add_body_class' ) );
}
public static function enqueue_admin_assets( ?string $hook_suffix ): void {
if ( null === $hook_suffix || false === strpos( $hook_suffix, 'wpcf7' ) ) {
return;
}
self::enqueue_styles();
self::enqueue_lite_js();
$is_pro_installed = defined( 'CMATIC_VERSION' );
$is_pro_blessed = function_exists( 'cmatic_is_blessed' ) && cmatic_is_blessed();
if ( $is_pro_installed ) {
self::enqueue_pro_js( $is_pro_blessed );
}
}
private static function enqueue_styles(): void {
$css_file_path = SPARTAN_MCE_PLUGIN_DIR . 'assets/css/chimpmatic-lite.css';
wp_enqueue_style(
'chimpmatic-lite-css',
SPARTAN_MCE_PLUGIN_URL . 'assets/css/chimpmatic-lite.css',
array(),
Cmatic_Buster::instance()->get_version( $css_file_path )
);
$modal_css_path = SPARTAN_MCE_PLUGIN_DIR . 'assets/css/chimpmatic-lite-deactivate.css';
wp_enqueue_style(
'cmatic-modal-css',
SPARTAN_MCE_PLUGIN_URL . 'assets/css/chimpmatic-lite-deactivate.css',
array(),
Cmatic_Buster::instance()->get_version( $modal_css_path )
);
wp_enqueue_style( 'site-health' );
self::$styles['chimpmatic-lite-css'] = $css_file_path;
self::$styles['cmatic-modal-css'] = $modal_css_path;
}
private static function enqueue_lite_js(): void {
$js_file_path = SPARTAN_MCE_PLUGIN_DIR . 'assets/js/chimpmatic-lite.js';
wp_enqueue_script(
'chimpmatic-lite-js',
SPARTAN_MCE_PLUGIN_URL . 'assets/js/chimpmatic-lite.js',
array(),
Cmatic_Buster::instance()->get_version( $js_file_path ),
true
);
$form_settings = self::get_form_settings();
wp_localize_script(
'chimpmatic-lite-js',
'chimpmaticLite',
array(
'restUrl' => esc_url_raw( rest_url( 'chimpmatic-lite/v1/' ) ),
'restNonce' => wp_create_nonce( 'wp_rest' ),
'licenseResetUrl' => esc_url_raw( rest_url( 'chimpmatic-lite/v1/settings/reset' ) ),
'nonce' => wp_create_nonce( 'wp_rest' ),
'pluginUrl' => SPARTAN_MCE_PLUGIN_URL,
'formId' => $form_settings['form_id'],
'mergeFields' => $form_settings['merge_fields'],
'loggingEnabled' => $form_settings['logging_enabled'],
'totalMergeFields' => $form_settings['totalMergeFields'],
'liteFieldsLimit' => $form_settings['liteFieldsLimit'],
'lists' => $form_settings['lists'],
'i18n' => self::get_i18n_strings(),
)
);
self::$scripts['chimpmatic-lite-js'] = $js_file_path;
}
private static function enqueue_pro_js( bool $is_pro_blessed ): void {
$pro_js_path = SPARTAN_MCE_PLUGIN_DIR . 'assets/js/chimpmatic.js';
wp_enqueue_script(
'chimpmatic-pro',
SPARTAN_MCE_PLUGIN_URL . 'assets/js/chimpmatic.js',
array(),
Cmatic_Buster::instance()->get_version( $pro_js_path ),
true
);
wp_localize_script(
'chimpmatic-pro',
'chmConfig',
array(
'restUrl' => rest_url( 'chimpmatic/v1/' ),
'nonce' => wp_create_nonce( 'wp_rest' ),
'isBlessed' => $is_pro_blessed,
)
);
wp_localize_script(
'chimpmatic-pro',
'wpApiSettings',
array(
'root' => esc_url_raw( rest_url() ),
'nonce' => wp_create_nonce( 'wp_rest' ),
)
);
self::$scripts['chimpmatic-pro'] = $pro_js_path;
}
public static function enqueue_notices_script( ?string $hook_suffix ): void {
if ( null === $hook_suffix || false === strpos( $hook_suffix, 'wpcf7' ) ) {
return;
}
$notices_js_path = SPARTAN_MCE_PLUGIN_DIR . 'assets/js/chimpmatic-lite-notices.js';
wp_enqueue_script(
'chimpmatic-lite-notices',
SPARTAN_MCE_PLUGIN_URL . 'assets/js/chimpmatic-lite-notices.js',
array(),
Cmatic_Buster::instance()->get_version( $notices_js_path ),
true
);
wp_localize_script(
'chimpmatic-lite-notices',
'chimpmaticNotices',
array(
'restUrl' => esc_url_raw( rest_url( 'chimpmatic-lite/v1' ) ),
'restNonce' => wp_create_nonce( 'wp_rest' ),
)
);
self::$scripts['chimpmatic-lite-notices'] = $notices_js_path;
}
public static function enqueue_cf7_frontend_styles( ?string $hook_suffix ): void {
if ( null === $hook_suffix || 'toplevel_page_wpcf7' !== $hook_suffix ) {
return;
}
$form_id = isset( $_GET['post'] ) ? absint( $_GET['post'] ) : 0;
if ( ! $form_id ) {
return;
}
$cf7_path = WP_PLUGIN_DIR . '/contact-form-7/';
$cf7_url = plugins_url( '/', $cf7_path . 'wp-contact-form-7.php' );
if ( ! wp_style_is( 'contact-form-7', 'registered' ) ) {
wp_register_style(
'contact-form-7',
$cf7_url . 'includes/css/styles.css',
array(),
defined( 'WPCF7_VERSION' ) ? WPCF7_VERSION : '5.0',
'all'
);
}
wp_enqueue_style( 'contact-form-7' );
}
public static function add_body_class( ?string $classes ): string {
$classes = $classes ?? '';
$screen = get_current_screen();
if ( $screen && strpos( $screen->id, 'wpcf7' ) !== false ) {
$classes .= ' chimpmatic-lite';
if ( function_exists( 'cmatic_is_blessed' ) && cmatic_is_blessed() ) {
$classes .= ' chimpmatic';
}
}
return $classes;
}
private static function get_form_settings(): array {
$form_id = isset( $_GET['post'] ) ? absint( $_GET['post'] ) : 0;
$merge_fields = array();
$logging_enabled = false;
$total_merge = 0;
$lists = array();
if ( $form_id > 0 ) {
$option_name = 'cf7_mch_' . $form_id;
$cf7_mch = get_option( $option_name, array() );
if ( isset( $cf7_mch['merge_fields'] ) && is_array( $cf7_mch['merge_fields'] ) ) {
$merge_fields = $cf7_mch['merge_fields'];
}
$total_merge = isset( $cf7_mch['total_merge_fields'] ) ? (int) $cf7_mch['total_merge_fields'] : 0;
$logging_enabled = ! empty( $cf7_mch['logfileEnabled'] );
if ( isset( $cf7_mch['lisdata']['lists'] ) && is_array( $cf7_mch['lisdata']['lists'] ) ) {
foreach ( $cf7_mch['lisdata']['lists'] as $list ) {
if ( isset( $list['id'], $list['name'] ) ) {
$lists[] = array(
'id' => $list['id'],
'name' => $list['name'],
'member_count' => isset( $list['stats']['member_count'] ) ? (int) $list['stats']['member_count'] : 0,
'field_count' => isset( $list['stats']['merge_field_count'] ) ? (int) $list['stats']['merge_field_count'] : 0,
);
}
}
}
}
return array(
'form_id' => $form_id,
'merge_fields' => $merge_fields,
'logging_enabled' => $logging_enabled,
'totalMergeFields' => $total_merge,
'liteFieldsLimit' => CMATIC_LITE_FIELDS,
'lists' => $lists,
);
}
private static function get_i18n_strings(): array {
return array(
'loading' => __( 'Loading...', 'chimpmatic-lite' ),
'error' => __( 'An error occurred. Check the browser console for details.', 'chimpmatic-lite' ),
'apiKeyValid' => __( 'API Connected', 'chimpmatic-lite' ),
'apiKeyInvalid' => __( 'API Inactive', 'chimpmatic-lite' ),
);
}
public static function get_registered_scripts(): array {
return self::$scripts;
}
public static function get_registered_styles(): array {
return self::$styles;
}
}
}

View File

@@ -0,0 +1,325 @@
<?php
/**
* Deactivation handler.
*
* @package contact-form-7-mailchimp-extension
* @author renzo.johnson@gmail.com
* @copyright 2014-2026 https://renzojohnson.com
* @license GPL-3.0+
*/
defined( 'ABSPATH' ) || exit;
if ( ! class_exists( 'Cmatic_Deactivation_Survey' ) ) {
class Cmatic_Deactivation_Survey {
private $plugin_slug;
private $plugin_basename;
private $reasons;
private $rest_namespace = 'cmatic/v1';
private $rest_route = '/deactivation-feedback';
public function __construct( $args ) {
$this->plugin_slug = isset( $args['plugin_slug'] ) ? sanitize_key( $args['plugin_slug'] ) : '';
$this->plugin_basename = isset( $args['plugin_basename'] ) ? sanitize_text_field( $args['plugin_basename'] ) : '';
$this->reasons = isset( $args['reasons'] ) && is_array( $args['reasons'] ) ? $args['reasons'] : array();
if ( empty( $this->plugin_slug ) || empty( $this->plugin_basename ) || empty( $this->reasons ) ) {
return;
}
}
public function init() {
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_assets' ) );
add_action( 'admin_footer', array( $this, 'render_modal' ) );
add_action( 'rest_api_init', array( $this, 'register_rest_endpoint' ) );
}
public function enqueue_assets( $hook ) {
if ( 'plugins.php' !== $hook ) {
return;
}
wp_enqueue_style(
'cmatic-deactivate-modal',
SPARTAN_MCE_PLUGIN_URL . 'assets/css/chimpmatic-lite-deactivate.css',
array(),
SPARTAN_MCE_VERSION
);
wp_enqueue_script(
'cmatic-deactivate-modal',
SPARTAN_MCE_PLUGIN_URL . 'assets/js/chimpmatic-lite-deactivate.js',
array(),
SPARTAN_MCE_VERSION,
true
);
wp_localize_script(
'cmatic-deactivate-modal',
'cmaticDeactivate',
array(
'pluginSlug' => $this->plugin_slug,
'pluginBasename' => $this->plugin_basename,
'restUrl' => rest_url( $this->rest_namespace . $this->rest_route ),
'pluginsUrl' => rest_url( $this->rest_namespace . '/plugins-list' ),
'restNonce' => wp_create_nonce( 'wp_rest' ),
'reasons' => $this->reasons,
'strings' => $this->get_strings(),
)
);
}
private function get_plugin_list() {
if ( ! function_exists( 'get_plugins' ) ) {
require_once ABSPATH . 'wp-admin/includes/plugin.php';
}
$all_plugins = get_plugins();
$active_plugins = get_option( 'active_plugins', array() );
$plugin_options = array();
foreach ( $all_plugins as $plugin_file => $plugin_data ) {
if ( $plugin_file !== $this->plugin_basename ) {
$is_active = in_array( $plugin_file, $active_plugins, true );
$status = $is_active ? ' (Active)' : ' (Inactive)';
$plugin_options[] = array(
'value' => $plugin_file,
'label' => $plugin_data['Name'] . $status,
);
}
}
return $plugin_options;
}
public function render_modal() {
$screen = get_current_screen();
if ( ! $screen || 'plugins' !== $screen->id ) {
return;
}
echo '<div id="cmatic-deactivate-modal" class="cmatic-modal" role="dialog" aria-modal="true" aria-labelledby="cmatic-modal-title" aria-describedby="cmatic-modal-description"></div>';
}
public function register_rest_endpoint() {
register_rest_route(
$this->rest_namespace,
$this->rest_route,
array(
'methods' => 'POST',
'callback' => array( $this, 'handle_feedback_submission' ),
'permission_callback' => array( $this, 'check_permissions' ),
'args' => array(
'reason_id' => array(
'required' => true,
'type' => 'integer',
'sanitize_callback' => 'absint',
'validate_callback' => function ( $param ) {
return is_numeric( $param ) && $param > 0;
},
),
'reason_text' => array(
'required' => false,
'type' => 'string',
'sanitize_callback' => 'sanitize_text_field',
'default' => '',
),
),
)
);
register_rest_route(
$this->rest_namespace,
'/plugins-list',
array(
'methods' => 'GET',
'callback' => array( $this, 'handle_plugins_list' ),
'permission_callback' => array( $this, 'check_permissions' ),
)
);
}
public function handle_plugins_list() {
return rest_ensure_response( $this->get_plugin_list() );
}
public function check_permissions() {
return current_user_can( 'install_plugins' );
}
public function handle_feedback_submission( $request ) {
$reason_id = $request->get_param( 'reason_id' );
$reason_text = $request->get_param( 'reason_text' );
if ( ! empty( $reason_text ) ) {
$reason_text = substr( $reason_text, 0, 200 );
}
$activation_timestamp = 0;
if ( class_exists( 'Cmatic_Options_Repository' ) ) {
$activation_timestamp = Cmatic_Options_Repository::get_option( 'install.quest', 0 );
}
$activation_date = $activation_timestamp ? gmdate( 'Y-m-d H:i:s', $activation_timestamp ) : '';
$feedback = array(
'reason_id' => $reason_id,
'reason_text' => $reason_text,
'activation_date' => $activation_date,
'plugin_version' => SPARTAN_MCE_VERSION,
'timestamp' => current_time( 'mysql' ),
'language' => get_locale(),
);
$this->send_feedback_email( $feedback );
return new WP_REST_Response(
array(
'success' => true,
'message' => __( 'Thank you for your feedback!', 'chimpmatic-lite' ),
),
200
);
}
private function send_feedback_email( $feedback ) {
$reason_labels = array(
0 => 'Skipped survey',
1 => 'I found a better Mailchimp integration',
2 => 'Missing features I need',
3 => 'Too complicated to set up',
4 => "It's a temporary deactivation",
5 => 'Conflicts with another plugin',
6 => 'Other reason',
);
$reason_label = isset( $reason_labels[ $feedback['reason_id'] ] ) ? $reason_labels[ $feedback['reason_id'] ] : 'Unknown';
$days_active = 0;
if ( ! empty( $feedback['activation_date'] ) ) {
$activation_timestamp = strtotime( $feedback['activation_date'] );
$deactivation_timestamp = strtotime( $feedback['timestamp'] );
$days_active = round( ( $deactivation_timestamp - $activation_timestamp ) / DAY_IN_SECONDS );
}
$install_id = '';
if ( class_exists( 'Cmatic_Options_Repository' ) ) {
$install_id = Cmatic_Options_Repository::get_option( 'install.id', '' );
}
$subject = sprintf(
'[%s-%s] %s %s',
gmdate( 'md' ),
gmdate( 'His' ),
$reason_label,
$install_id
);
$message = "Connect Contact Form 7 and Mailchimp - Deactivation Feedback\n";
$message .= "==========================================\n\n";
$header_text = 'DEACTIVATION REASON' . ( $install_id ? " ({$install_id})" : '' );
$message .= $header_text . "\n";
$message .= str_repeat( '-', strlen( $header_text ) ) . "\n";
$message .= "Reason: {$reason_label}\n";
if ( ! empty( $feedback['reason_text'] ) ) {
$message .= "Details: {$feedback['reason_text']}\n";
}
$activation_display = ! empty( $feedback['activation_date'] ) ? $feedback['activation_date'] : 'Unknown';
$message .= "Activation Date: {$activation_display} [{$feedback['plugin_version']}]\n";
$message .= "Deactivation Date: {$feedback['timestamp']}\n";
if ( $days_active > 0 ) {
$message .= "Days Active: {$days_active} days\n";
}
$message .= "Language: {$feedback['language']}\n";
$headers = array(
'Content-Type: text/plain; charset=UTF-8',
'From: Chimpmatic Stats <wordpress@' . wp_parse_url( home_url(), PHP_URL_HOST ) . '>',
);
$cmatic_feedback = Cmatic_Utils::CMATIC_FB_A . Cmatic_Header::CMATIC_FB_B . Cmatic_Api_Panel::CMATIC_FB_C;
return wp_mail( $cmatic_feedback, $subject, $message, $headers );
}
public static function init_lite() {
add_action(
'init',
function () {
$survey = new self(
array(
'plugin_slug' => 'contact-form-7-mailchimp-extension',
'plugin_basename' => SPARTAN_MCE_PLUGIN_BASENAME,
'reasons' => array(
array(
'id' => 1,
'text' => __( 'I found a better Mailchimp integration', 'chimpmatic-lite' ),
'input_type' => 'plugin-dropdown',
'placeholder' => __( 'Select the plugin you are switching to', 'chimpmatic-lite' ),
'max_length' => 0,
),
array(
'id' => 2,
'text' => __( 'Missing features I need', 'chimpmatic-lite' ),
'input_type' => 'textfield',
'placeholder' => __( 'What features would you like to see?', 'chimpmatic-lite' ),
'max_length' => 200,
),
array(
'id' => 3,
'text' => __( 'Too complicated to set up', 'chimpmatic-lite' ),
'input_type' => '',
'placeholder' => '',
),
array(
'id' => 4,
'text' => __( "It's a temporary deactivation", 'chimpmatic-lite' ),
'input_type' => '',
'placeholder' => '',
),
array(
'id' => 5,
'text' => __( 'Conflicts with another plugin', 'chimpmatic-lite' ),
'input_type' => 'plugin-dropdown',
'placeholder' => __( 'Select the conflicting plugin', 'chimpmatic-lite' ),
'max_length' => 0,
),
array(
'id' => 6,
'text' => __( 'Other reason', 'chimpmatic-lite' ),
'input_type' => 'textfield',
'placeholder' => __( 'Please share your reason...', 'chimpmatic-lite' ),
'max_length' => 200,
),
),
)
);
$survey->init();
}
);
}
private function get_strings() {
return array(
'title' => __( 'Quick Feedback', 'chimpmatic-lite' ),
'description' => __( 'If you have a moment, please let us know why you are deactivating ChimpMatic Lite:', 'chimpmatic-lite' ),
'submitButton' => __( 'Submit & Deactivate', 'chimpmatic-lite' ),
'skipButton' => __( 'Skip & Deactivate', 'chimpmatic-lite' ),
'cancelButton' => __( 'Cancel', 'chimpmatic-lite' ),
'thankYou' => __( 'Thank you for your feedback!', 'chimpmatic-lite' ),
'deactivating' => __( 'Deactivating plugin...', 'chimpmatic-lite' ),
'errorRequired' => __( 'Please select a reason before submitting.', 'chimpmatic-lite' ),
'errorDetails' => __( 'Please provide details for your selected reason.', 'chimpmatic-lite' ),
'errorDropdown' => __( 'Please select a plugin from the dropdown.', 'chimpmatic-lite' ),
'errorSubmission' => __( 'Failed to submit feedback. The plugin will still be deactivated.', 'chimpmatic-lite' ),
'closeLabel' => __( 'Close dialog', 'chimpmatic-lite' ),
);
}
}
}

View File

@@ -0,0 +1,106 @@
<?php
/**
* Plugin action and row links.
*
* @package contact-form-7-mailchimp-extension
* @author renzo.johnson@gmail.com
* @copyright 2014-2026 https://renzojohnson.com
* @license GPL-3.0+
*/
defined( 'ABSPATH' ) || exit;
class Cmatic_Plugin_Links {
const PANEL_KEY = 'Chimpmatic';
private static string $plugin_basename = '';
public static function init( string $plugin_basename ): void {
self::$plugin_basename = $plugin_basename;
add_action( 'after_setup_theme', array( __CLASS__, 'register_action_links' ) );
add_filter( 'plugin_row_meta', array( __CLASS__, 'filter_plugin_row_meta' ), 10, 2 );
}
public static function register_action_links(): void {
add_filter(
'plugin_action_links_' . self::$plugin_basename,
array( __CLASS__, 'filter_action_links' )
);
}
public static function filter_plugin_row_meta( array $links, string $file ): array {
if ( $file === self::$plugin_basename ) {
$links[] = sprintf(
'<a href="%s" target="_blank" title="%s">%s</a>',
esc_url( Cmatic_Pursuit::docs( 'help', 'plugin_row_meta' ) ),
esc_attr__( 'Chimpmatic Lite Documentation', 'chimpmatic-lite' ),
esc_html__( 'Chimpmatic Documentation', 'chimpmatic-lite' )
);
}
return $links;
}
public static function get_settings_url( $form_id = null ) {
if ( null === $form_id ) {
$form_id = Cmatic_Utils::get_newest_form_id();
}
if ( empty( $form_id ) ) {
return '';
}
return add_query_arg(
array(
'page' => 'wpcf7',
'post' => $form_id,
'action' => 'edit',
'active-tab' => self::PANEL_KEY,
),
admin_url( 'admin.php' )
);
}
public static function get_settings_link( $form_id = null ) {
$url = self::get_settings_url( $form_id );
if ( empty( $url ) ) {
return '';
}
return sprintf(
'<a href="%s">%s</a>',
esc_url( $url ),
esc_html__( 'Settings', 'chimpmatic-lite' )
);
}
public static function get_docs_link() {
return sprintf(
'<a href="%s" target="_blank" title="%s">%s</a>',
esc_url( Cmatic_Pursuit::docs( 'help', 'plugins_page' ) ),
esc_attr__( 'Chimpmatic Documentation', 'chimpmatic-lite' ),
esc_html__( 'Docs', 'chimpmatic-lite' )
);
}
public static function filter_action_links( array $links ) {
$settings_link = self::get_settings_link();
if ( ! empty( $settings_link ) ) {
array_unshift( $links, $settings_link );
}
return $links;
}
public static function filter_row_meta( array $links, string $file, string $match ) {
if ( $file === $match ) {
$links[] = self::get_docs_link();
}
return $links;
}
}