Plugin Directory

Changeset 3429749


Ignore:
Timestamp:
12/30/2025 05:34:07 PM (3 months ago)
Author:
fullworks
Message:

Release version 4.12

Location:
clean-and-simple-contact-form-by-meg-nicholas
Files:
4 added
92 edited
1 copied

Legend:

Unmodified
Added
Removed
  • clean-and-simple-contact-form-by-meg-nicholas/tags/4.12/ajax.php

    r3339262 r3429749  
    11<?php
     2if ( ! defined( 'ABSPATH' ) ) exit;
    23add_action( "wp_ajax_cscf-submitform", "cscfsubmitform" );
    34add_action( "wp_ajax_nopriv_cscf-submitform", "cscfsubmitform" );
  • clean-and-simple-contact-form-by-meg-nicholas/tags/4.12/changelog.txt

    r3339262 r3429749  
     1= 4.12 =
     2* Added CSS Framework selection for flexible form styling
     3  - Bootstrap (default) - maintains backward compatibility
     4  - Modern (Card style) - opinionated modern design with CSS variables for easy customization
     5  - Theme Native - minimal classes, inherits theme styles with wp-element-button for submit
     6  - Minimal - semantic classes only for complete custom styling
     7* New Modern style features:
     8  - Card-style container with subtle shadow
     9  - Large, comfortable input fields
     10  - Clean typography and spacing
     11  - Dark mode support (auto-detects or via .dark class)
     12  - Full CSS variable system for easy theming
     13  - Responsive design
     14* Added filter hooks for developers to customize CSS classes
     15  - cscf_css_classes filter for complete class mapping override
     16  - cscf_css_class filter for individual element customization
     17* Improved theme compatibility - form now adapts to different CSS frameworks
     18* Added direct file access protection to all PHP files
     19* Update wp tested to 6.9
     20* update plugin free lib
     21
    122= 4.11 =
    223* Added REST API support for headless WordPress implementations
  • clean-and-simple-contact-form-by-meg-nicholas/tags/4.12/class.cscf.php

    r3339262 r3429749  
    11<?php
     2if ( ! defined( 'ABSPATH' ) ) exit;
    23
    34class cscf {
     
    3334            /**  @var $wp_error \WP_Error */
    3435            if ( defined( 'WP_DEBUG' ) && true == WP_DEBUG && is_wp_error( $wp_error ) ) {
     36                // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_trigger_error -- Intentional debug output when WP_DEBUG is enabled
    3537                trigger_error( 'CSCF Email - wp_mail error msg : ' . esc_html( $wp_error->get_error_message() ), E_USER_WARNING );
    3638            }
     
    5456
    5557        wp_register_style( 'cscf-bootstrap', CSCF_PLUGIN_URL . '/css/bootstrap-forms.min.css',
     58            null, CSCF_VERSION_NUM );
     59
     60        wp_register_style( 'cscf-modern', CSCF_PLUGIN_URL . '/css/cscf-modern.css',
    5661            null, CSCF_VERSION_NUM );
    5762
     
    173178    public function SpamFilter( $contact ) {
    174179
     180        // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- WordPress core hook for spam filtering
    175181        $commentData = apply_filters( 'preprocess_comment', array(
    176182            'comment_post_ID'      => $contact->PostID,
  • clean-and-simple-contact-form-by-meg-nicholas/tags/4.12/class.cscf_contact.php

    r3339262 r3429749  
    11<?php
     2if ( ! defined( 'ABSPATH' ) ) exit;
    23
    34/*
  • clean-and-simple-contact-form-by-meg-nicholas/tags/4.12/class.cscf_filters.php

    r3254319 r3429749  
    11<?php
     2if ( ! defined( 'ABSPATH' ) ) exit;
    23
    34/*
  • clean-and-simple-contact-form-by-meg-nicholas/tags/4.12/class.cscf_pluginsettings.php

    r3339262 r3429749  
    11<?php
     2if ( ! defined( 'ABSPATH' ) ) exit;
    23
    34class cscf_PluginSettings
     
    205206        return isset($options['rest_api_capability']) ? $options['rest_api_capability'] : 'edit_posts';
    206207    }
     208
     209    /**
     210     * Get the selected CSS framework
     211     *
     212     * @return string The CSS framework key (bootstrap, theme-native, none)
     213     */
     214    static function CssFramework()
     215    {
     216        $options = get_option(CSCF_OPTIONS_KEY);
     217        return isset($options['css_framework']) ? $options['css_framework'] : 'bootstrap';
     218    }
    207219}
    208220
  • clean-and-simple-contact-form-by-meg-nicholas/tags/4.12/class.cscf_rest_api.php

    r3339262 r3429749  
    11<?php
     2if ( ! defined( 'ABSPATH' ) ) exit;
    23/**
    34 * REST API handler for Clean and Simple Contact Form
  • clean-and-simple-contact-form-by-meg-nicholas/tags/4.12/class.cscf_settings.php

    r3339262 r3429749  
    11<?php
     2if ( ! defined( 'ABSPATH' ) ) exit;
    23
    34/*
     
    5960            <h3><?php esc_html_e( 'Support the developer', 'clean-and-simple-contact-form-by-meg-nicholas' ); ?></h3>
    6061            <p>
    61                 <?php do_action( 'ffpl_ad_display' ); ?>
     62                <?php
     63                // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Hook from Starter Plugin library
     64                do_action( 'ffpl_ad_display' );
     65                ?>
    6266            </p>
    6367
     
    163167            'print_section_info_styling',
    164168        ), 'contact-form-settings' );
     169        add_settings_field( 'css_framework', esc_html__( 'CSS Framework :', 'clean-and-simple-contact-form-by-meg-nicholas' ), array(
     170            $this,
     171            'create_fields',
     172        ), 'contact-form-settings', 'section_styling', array(
     173            'css_framework',
     174        ) );
    165175        add_settings_field( 'load_stylesheet', esc_html__( 'Use the plugin default stylesheet (un-tick to use your theme style sheet instead) :', 'clean-and-simple-contact-form-by-meg-nicholas' ), array(
    166176            $this,
     
    346356            if ( empty( $input['rest_api_capability'] ) ) {
    347357                $input['rest_api_capability'] = 'edit_posts';
     358            }
     359        }
     360
     361        // CSS framework - validate against allowed values
     362        if ( isset( $input['css_framework'] ) ) {
     363            $allowed_frameworks = array_keys( cscf_CSS_Classes::get_presets() );
     364            if ( ! in_array( $input['css_framework'], $allowed_frameworks, true ) ) {
     365                $input['css_framework'] = 'bootstrap';
    348366            }
    349367        }
     
    549567                <?php
    550568                break;
     569            case 'css_framework':
     570                $current = cscf_PluginSettings::CssFramework();
     571                $presets = cscf_CSS_Classes::get_presets();
     572                ?><label for="css_framework" class="screen-reader-text">
     573                <?php esc_html_e('CSS framework', 'clean-and-simple-contact-form-by-meg-nicholas'); ?>
     574                </label>
     575                <select id="css_framework" name="<?php echo esc_attr( CSCF_OPTIONS_KEY ); ?>[css_framework]">
     576                <?php foreach ( $presets as $key => $label ) : ?>
     577                    <option value="<?php echo esc_attr( $key ); ?>" <?php selected( $current, $key ); ?>>
     578                        <?php echo esc_html( $label ); ?>
     579                    </option>
     580                <?php endforeach; ?>
     581                </select>
     582                <p class="description">
     583                    <?php esc_html_e( 'Bootstrap: Full Bootstrap styling (default). Theme Native: Minimal classes, inherits theme styles. Minimal: Semantic classes only for custom styling.', 'clean-and-simple-contact-form-by-meg-nicholas' ); ?>
     584                </p>
     585                <?php
     586                break;
    551587            case 'use_client_validation':
    552588                $checked = cscf_PluginSettings::UseClientValidation() == true ? "checked" : "";
  • clean-and-simple-contact-form-by-meg-nicholas/tags/4.12/class.view.php

    r3254319 r3429749  
    11<?php
     2if ( ! defined( 'ABSPATH' ) ) exit;
    23
    34class CSCF_View {
  • clean-and-simple-contact-form-by-meg-nicholas/tags/4.12/clean-and-simple-contact-form-by-meg-nicholas.php

    r3339262 r3429749  
    11<?php
     2if ( ! defined( 'ABSPATH' ) ) exit;
    23/**
    34 * @package Clean and Simple Contact Form
     
    89Plugin URI: https://fullworks.net/products/clean-and-simple-contact-form
    910Description: A clean and simple contact form with Google reCAPTCHA and Twitter Bootstrap markup.
    10 Version: 4.11
     11Version: 4.12
    1112Requires at least: 5.6
    1213Requires PHP: 7.4
     
    5152require 'class.cscf_filters.php';
    5253require 'class.cscf_rest_api.php';
     54require 'class.cscf_css_classes.php';
    5355require 'ajax.php';
    5456require 'recaptchav2.php';
     
    7678
    7779if ( ! defined( 'CSCF_VERSION_NUM' ) ) {
    78     define( 'CSCF_VERSION_NUM', '4.11' );
     80    define( 'CSCF_VERSION_NUM', '4.12' );
    7981}
    8082
     
    8789new \Fullworks_Free_Plugin_Lib\Main('clean-and-simple-contact-form-by-meg-nicholas/clean-and-simple-contact-form-by-meg-nicholas.php',
    8890    admin_url( 'options-general.php?page=contact-form-settings' ),
    89     'CSCF-Free',
     91    'CSCF',
    9092    'settings_page_contact-form-settings',
    9193    'Clean and Simple Contact Form',);
     
    146148
    147149/*get the current version and update options to the new option*/
    148 $old_version = get_option( CSCF_VERSION_KEY );
     150$cscf_old_version = get_option( CSCF_VERSION_KEY );
    149151update_option( CSCF_VERSION_KEY, CSCF_VERSION_NUM );
    150152
    151153/*If this is a new installation then set some defaults*/
    152 if ( false == $old_version ) {
    153     $options                          = get_option( CSCF_OPTIONS_KEY );
    154     $options['use_client_validation'] = true;
    155     $options['load_stylesheet']       = true;
    156     $options['confirm-email']         = true;
    157     update_option( CSCF_OPTIONS_KEY, $options );
     154if ( false == $cscf_old_version ) {
     155    $cscf_options                          = get_option( CSCF_OPTIONS_KEY );
     156    $cscf_options['use_client_validation'] = true;
     157    $cscf_options['load_stylesheet']       = true;
     158    $cscf_options['confirm-email']         = true;
     159    update_option( CSCF_OPTIONS_KEY, $cscf_options );
    158160}
    159161
    160162/*if necessary do an upgrade*/
    161 if ( $old_version < CSCF_VERSION_NUM ) {
    162     $cscf->Upgrade( $old_version );
     163if ( $cscf_old_version < CSCF_VERSION_NUM ) {
     164    $cscf->Upgrade( $cscf_old_version );
    163165}
  • clean-and-simple-contact-form-by-meg-nicholas/tags/4.12/composer.lock

    r3254319 r3429749  
    99        {
    1010            "name": "alanef/free_plugin_lib",
    11             "version": "v1.0.1",
     11            "version": "1.2.2",
    1212            "source": {
    1313                "type": "git",
    1414                "url": "https://github.com/alanef/free_plugin_lib.git",
    15                 "reference": "ed52c33c73999a1fe1ee5a1b00581b9462111ac8"
     15                "reference": "11f06087774e7d533199809be898117e3ed1ef2f"
    1616            },
    1717            "dist": {
    1818                "type": "zip",
    19                 "url": "https://api.github.com/repos/alanef/free_plugin_lib/zipball/ed52c33c73999a1fe1ee5a1b00581b9462111ac8",
    20                 "reference": "ed52c33c73999a1fe1ee5a1b00581b9462111ac8",
     19                "url": "https://api.github.com/repos/alanef/free_plugin_lib/zipball/11f06087774e7d533199809be898117e3ed1ef2f",
     20                "reference": "11f06087774e7d533199809be898117e3ed1ef2f",
    2121                "shasum": ""
    2222            },
     
    4949            "support": {
    5050                "issues": "https://github.com/alanef/free_plugin_lib/issues",
    51                 "source": "https://github.com/alanef/free_plugin_lib/tree/v1.0.1"
     51                "source": "https://github.com/alanef/free_plugin_lib/tree/v1.2.2"
    5252            },
    53             "time": "2025-02-18T15:16:14+00:00"
     53            "time": "2025-12-21T18:38:49+00:00"
    5454        },
    5555        {
  • clean-and-simple-contact-form-by-meg-nicholas/tags/4.12/languages/clean-and-simple-contact-form-by-meg-nicholas.pot

    r3339262 r3429749  
    1010"Content-Type: text/plain; charset=UTF-8\n"
    1111"Content-Transfer-Encoding: 8bit\n"
    12 "POT-Creation-Date: 2025-08-04T19:28:59+00:00\n"
     12"POT-Creation-Date: 2025-12-30T13:46:08+00:00\n"
    1313"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
    1414"X-Generator: WP-CLI 2.10.0\n"
     
    6868msgstr ""
    6969
    70 #: class.cscf_contact.php:167
    71 msgid "Please enter a valid phone number."
    72 msgstr ""
    73 
    74 #: class.cscf_contact.php:174
     70#: class.cscf_contact.php:168
     71msgid "Phone number can only contain numbers, +, (), - and spaces."
     72msgstr ""
     73
     74#: class.cscf_contact.php:172
     75msgid "Please enter a valid phone number (minimum 8 characters)."
     76msgstr ""
     77
     78#: class.cscf_contact.php:177
     79msgid "Please enter your phone number."
     80msgstr ""
     81
     82#: class.cscf_contact.php:183
    7583#: views/contact-form.view.php:198
    7684msgid "Please give your consent."
    7785msgstr ""
    7886
    79 #: class.cscf_contact.php:184
     87#: class.cscf_contact.php:194
    8088msgid "Please solve the recaptcha to continue."
    8189msgstr ""
    8290
    83 #: class.cscf_contact.php:220
     91#: class.cscf_contact.php:230
    8492msgid "From"
    8593msgstr ""
    8694
    87 #: class.cscf_contact.php:221
     95#: class.cscf_contact.php:231
    8896msgid "Email"
    8997msgstr ""
    9098
    91 #: class.cscf_contact.php:223
    92 #: class.cscf_contact.php:267
     99#: class.cscf_contact.php:233
     100#: class.cscf_contact.php:277
    93101msgid "Phone"
    94102msgstr ""
    95103
    96 #: class.cscf_contact.php:225
     104#: class.cscf_contact.php:235
    97105msgid "Page URL"
    98106msgstr ""
    99107
    100 #: class.cscf_contact.php:226
    101 #: class.cscf_contact.php:269
     108#: class.cscf_contact.php:236
     109#: class.cscf_contact.php:279
    102110msgid "Message"
    103111msgstr ""
    104112
    105 #: class.cscf_contact.php:228
    106 #: class.cscf_contact.php:264
     113#: class.cscf_contact.php:238
     114#: class.cscf_contact.php:274
    107115msgid "yes"
    108116msgstr ""
    109117
    110 #: class.cscf_contact.php:228
    111 #: class.cscf_contact.php:264
     118#: class.cscf_contact.php:238
     119#: class.cscf_contact.php:274
    112120msgid "no"
    113121msgstr ""
    114122
    115 #: class.cscf_contact.php:262
     123#: class.cscf_contact.php:272
    116124msgid "Here is a copy of your message :"
    117125msgstr ""
  • clean-and-simple-contact-form-by-meg-nicholas/tags/4.12/readme.txt

    r3339262 r3429749  
    77License URI: http://www.gnu.org/licenses/gpl.html
    88Tags: contact, form, contact form, feedback form, bootstrap
    9 Tested up to: 6.8
    10 Stable tag: 4.11
    11 
    12 A clean and simple contact form with Bootstrap markup.
     9Tested up to: 6.9
     10Stable tag: 4.12
     11
     12A clean and simple contact form with flexible CSS framework support.
    1313
    1414
    1515== Description ==
    16 A clean and simple AJAX contact form with Google reCAPTCHA, Twitter Bootstrap markup, spam filtering, and REST API support for headless WordPress implementations.
     16A clean and simple AJAX contact form with Google reCAPTCHA, flexible CSS framework support, spam filtering, and REST API support for headless WordPress implementations.
    1717
    1818*   **Clean**: all user inputs are stripped in order to avoid cross-site scripting (XSS) vulnerabilities.
     
    2020*   **Simple**: AJAX enabled validation and submission for immediate response and guidance for your users (can be switched off).
    2121
    22 *   **Stylish**: Use the included stylesheet or switch it off and use your own for seamless integration with your website.
    23 Uses **Twitter Bootstrap** classes.
     22*   **Flexible Styling**: Choose your CSS framework - Bootstrap (default), Theme Native (inherits your theme's styles), or Minimal (semantic classes for complete custom styling).
    2423
    2524*   **REST API Support**: Enable headless WordPress implementations to submit forms via authenticated REST API endpoints.
     
    6059*   The form can **integrate seamlessly into your website**. Turn off the plugin’s default css style sheet so that your theme’s style sheet can be used instead.
    6160
    62 *   If your theme is based on **twitter bootstrap** then this plugin will fit right in because it already has all the right div’s and CSS classes for bootstrap.
     61*   **Flexible CSS styling**: Choose from Bootstrap, Modern (with dark mode), Theme Native, or Minimal styling modes to match your site's design.
    6362
    6463*   This plugin will only link in its jQuery file where it’s needed, it **will not impose** itself on every page of your whole site!
     
    112111*   **Message Sent Content**: The message content or body displayed to the user after the message has been sent.
    113112
    114 *   **Use this plugin’s default stylesheet**: The plugin comes with a default style sheet to make the form look nice for your user. Untick this if you want to use your theme’s stylesheet instead. The default stylesheet will simply not be linked in.
     113*   **CSS Framework**: Choose how the form is styled:
     114    - **Bootstrap (Default)**: Uses Bootstrap CSS classes for full Bootstrap compatibility. Best for themes already using Bootstrap.
     115    - **Modern (Card style)**: A beautiful, opinionated modern design with card-style layout, large inputs, and CSS variables for easy customization. Includes automatic dark mode support.
     116    - **Theme Native**: Uses minimal classes with WordPress's wp-element-button for the submit button. The form inherits your theme's native form styles.
     117    - **Minimal**: Uses semantic CSS classes only (cscf-field, cscf-input, etc.) for complete custom styling control.
     118
     119*   **Use this plugin's default stylesheet**: The plugin comes with a default style sheet to make the form look nice for your user. Untick this if you want to use your theme's stylesheet instead. The default stylesheet will simply not be linked in. This option is most relevant when using the Bootstrap CSS framework.
    115120
    116121*   **Use client side validation (Ajax)**: When ticked the contact form will be validated and submitted on the client giving your user instant feedback if they have filled the form in incorrectly. If you wish the form to be validated and submitted only to the server then untick this option.
     
    324329= How do I change the text box sizes? =
    325330
    326 The plugin now uses Bootstrap 3. The text box widths now use up 100% of the available width.
     331When using Bootstrap (the default), text box widths use up 100% of the available width.
    327332This makes the form responsive to all types of media. If you want to have a fixed width for the form you can put some styling around the shortcode:
    328333`<div style="width:600px;">[cscf-contact-form]</div>`
     334
     335= How do I make the form match my theme's style? =
     336
     337You have several options:
     338
     3391. **Modern mode**: Select "Modern (Card style)" for a beautiful, ready-to-use design that can be customized with CSS variables.
     340
     3412. **Theme Native mode**: Change the CSS Framework setting to "Theme Native". This uses minimal CSS classes and lets your theme's native form styles take over.
     342
     3433. **Minimal mode**: Change the CSS Framework setting to "Minimal" for complete custom styling control using semantic classes like cscf-field, cscf-input, cscf-button.
     344
     3454. **Custom CSS**: Keep Bootstrap mode but disable "Use the plugin default stylesheet" and add your own CSS rules.
     346
     3475. **Developer filters**: Use the `cscf_css_classes` and `cscf_css_class` filters to customize the CSS classes used by the form.
     348
     349= How do I customize the Modern style? =
     350
     351The Modern style uses CSS variables that you can override in your theme. Add this to your theme's CSS:
     352
     353`
     354:root {
     355  --cscf-primary: #0066cc;       /* Button and focus colors */
     356  --cscf-radius: 0.75rem;        /* Border radius */
     357  --cscf-border: #d1d5db;        /* Border color */
     358  --cscf-error: #dc2626;         /* Error color */
     359}
     360`
     361
     362Full list of variables available in the cscf-modern.css file. Dark mode is automatically supported via `prefers-color-scheme` or by adding the `.dark` class to your HTML element.
    329363
    330364= Can I have multiple forms? =
  • clean-and-simple-contact-form-by-meg-nicholas/tags/4.12/shortcodes/contact-form.php

    r3339262 r3429749  
    11<?php
     2if ( ! defined( 'ABSPATH' ) ) exit;
    23add_shortcode( 'contact-form', 'cscf_ContactForm' );
    34add_shortcode( 'cscf-contact-form', 'cscf_ContactForm' );
     
    3334    }
    3435
    35     //only load the stylesheet if required
    36     if ( cscf_PluginSettings::LoadStyleSheet() == true ) {
     36    //load the appropriate stylesheet based on CSS framework
     37    $css_framework = cscf_PluginSettings::CssFramework();
     38    if ( 'modern' === $css_framework ) {
     39        wp_enqueue_style( 'cscf-modern' );
     40    } elseif ( 'bootstrap' === $css_framework && cscf_PluginSettings::LoadStyleSheet() == true ) {
    3741        wp_enqueue_style( 'cscf-bootstrap' );
    3842    }
  • clean-and-simple-contact-form-by-meg-nicholas/tags/4.12/vendor/alanef/free_plugin_lib/composer.json

    r3254319 r3429749  
    11{
    22  "name": "alanef/free_plugin_lib",
     3  "version": "1.2.2",
    34  "description": "Library to add to free plugins, in compliance with wp.org",
    45  "type": "library",
  • clean-and-simple-contact-form-by-meg-nicholas/tags/4.12/vendor/alanef/free_plugin_lib/package.json

    r3254319 r3429749  
    11{
    22  "name": "free_plugin_lib",
    3   "version": "1.0.1"
     3  "version": "1.2.2"
    44}
  • clean-and-simple-contact-form-by-meg-nicholas/tags/4.12/vendor/alanef/free_plugin_lib/src/Classes/Email.php

    r3254319 r3429749  
    44
    55class Email {
    6     private static $plugin_shortname;
     6    private static $plugin_shortname;
    77
    8     public function __construct($plugin_shortname) {
    9         self::$plugin_shortname = $plugin_shortname;
    10     }
     8    // Plugin shortname to ID mapping
     9    private static $plugin_map = [
     10        'SWEGTS' => 'swegts',
     11        'SSFGM'  => 'ssfgm',
     12        'LHF'    => 'lhf',
     13        'SUE'    => 'sue',
     14        'RSHFD'  => 'rshfd',
     15        'FAUM'   => 'faum',
     16        'FSS'    => 'fss',
     17        'MMT'    => 'mmt',
     18        'CSCF'   => 'cscf',
     19    ];
    1120
    12     public function handle_optin_submission($email) {
    13         // Enhanced email validation
    14         if (!filter_var($email, FILTER_VALIDATE_EMAIL) || strlen($email) > 254) {
    15             return false;
    16         }
    17        
    18         // Prepare API endpoint with sanitization
    19         $api_endpoint = esc_url_raw('https://octopus.fullworksplugins.com/wp-json/fullworks-freemius-octopusmail/v2/action');
    20         $list_id = '4c6924da-03e8-11ef-b408-2f0724a38cbd';
    21         $tag = sanitize_key(self::$plugin_shortname);
    22        
    23         // Prepare request with security headers
    24         $response = wp_remote_post('https://octopus.fullworksplugins.com/wp-json/fullworks-freemius-octopusmail/v2/action?list=4c6924da-03e8-11ef-b408-2f0724a38cbd&tag_free=' . self::$plugin_shortname, array(
    25             'headers' => array(
    26                 'Content-Type' => 'application/json',
    27                 'User-Agent' => 'WordPress/' . get_bloginfo('version'),
    28             ),
    29             'body' => wp_json_encode([
    30                 'type' => 'user.marketing.opted_in',
    31                 'plugin_id' => '1330',
    32                 'is_live' => true,
    33                 'objects' => [
    34                     'user' => [
    35                         'is_marketing_allowed' => true,
    36                         'email' => sanitize_email($email),
    37                         'first' => '',
    38                         'last' => '',
    39                         'ip' =>  Security::get_client_ip(),
    40                         'plugin_shortname' => self::$plugin_shortname,
    41                         'source' => get_site_url(),
    42                     ]
    43                 ]
    44             ]),
    45             'timeout' => 15,
    46             'sslverify' => true,
    47             'blocking' => true,
    48         ));
     21    public function __construct($plugin_shortname) {
     22        self::$plugin_shortname = $plugin_shortname;
     23    }
    4924
    50         if (is_wp_error($response)) {
    51             return false;
    52         }
     25    public function handle_optin_submission($email) {
     26        // Enhanced email validation
     27        if (!filter_var($email, FILTER_VALIDATE_EMAIL) || strlen($email) > 254) {
     28            return false;
     29        }
    5330
    54         $response_code = wp_remote_retrieve_response_code($response);
    55         if ($response_code !== 200) {
    56             return false;
    57         }
     31        // Allow filtering of plugin map for testing/extensions
     32        $plugin_map = apply_filters( 'ffpl_plugin_map', self::$plugin_map );
    5833
    59         return true;
    60     }
     34        // Get plugin ID from map
     35        $plugin_id = $plugin_map[self::$plugin_shortname] ?? null;
     36        if (!$plugin_id) {
     37            return false;
     38        }
     39
     40        // Allow filtering of the verification URL for testing
     41        $verify_url = apply_filters( 'ffpl_verify_url', 'https://campaign.email.fw9.uk/api/webhook/product' );
     42
     43        $response = wp_remote_post($verify_url, [
     44            'headers' => [
     45                'Content-Type' => 'application/json',
     46                'User-Agent' => 'WordPress/' . get_bloginfo('version'),
     47            ],
     48            'body' => wp_json_encode([
     49                'type' => 'install.installed',
     50                'plugin_id' => $plugin_id,
     51                'is_live' => true,
     52                'objects' => [
     53                    'user' => [
     54                        'is_marketing_allowed' => true,
     55                        'email' => sanitize_email($email),
     56                        'first' => '',
     57                        'last' => '',
     58                        'ip' => Security::get_client_ip(),
     59                        'id' => null,
     60                    ],
     61                    'install' => [
     62                        'is_premium' => false,
     63                        'is_active' => true,
     64                        'license_id' => null,
     65                        'trial_plan_id' => null,
     66                        'trial_ends' => null,
     67                        'country_code' => '',
     68                        'url' => get_site_url(),
     69                    ]
     70                ]
     71            ]),
     72            'timeout' => 15,
     73            'sslverify' => true,
     74            'blocking' => true,
     75        ]);
     76
     77        if (is_wp_error($response)) {
     78            return false;
     79        }
     80
     81        return wp_remote_retrieve_response_code($response) === 200;
     82    }
    6183}
  • clean-and-simple-contact-form-by-meg-nicholas/tags/4.12/vendor/alanef/free_plugin_lib/src/Classes/Security.php

    r3254319 r3429749  
    1212     */
    1313    public static function verify_nonce($nonce_name, $action) {
    14         return isset($_REQUEST[$nonce_name]) && wp_verify_nonce($_REQUEST[$nonce_name], $action);
     14        if (!isset($_REQUEST[$nonce_name])) {
     15            return false;
     16        }
     17        $nonce = sanitize_text_field(wp_unslash($_REQUEST[$nonce_name]));
     18        return wp_verify_nonce($nonce, $action);
    1519    }
    1620
     
    4347    public static function get_client_ip() {
    4448        $ip = '127.0.0.1';
    45        
     49
    4650        if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
    47             $ip = sanitize_text_field($_SERVER['HTTP_CLIENT_IP']);
     51            $ip = sanitize_text_field(wp_unslash($_SERVER['HTTP_CLIENT_IP']));
    4852        } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
    49             $ip = sanitize_text_field($_SERVER['HTTP_X_FORWARDED_FOR']);
     53            $ip = sanitize_text_field(wp_unslash($_SERVER['HTTP_X_FORWARDED_FOR']));
    5054        } elseif (!empty($_SERVER['REMOTE_ADDR'])) {
    51             $ip = sanitize_text_field($_SERVER['REMOTE_ADDR']);
     55            $ip = sanitize_text_field(wp_unslash($_SERVER['REMOTE_ADDR']));
    5256        }
    53        
     57
    5458        return filter_var($ip, FILTER_VALIDATE_IP) ? $ip : '127.0.0.1';
    5559    }
  • clean-and-simple-contact-form-by-meg-nicholas/tags/4.12/vendor/alanef/free_plugin_lib/src/Main.php

    r3254319 r3429749  
    1313     * @var string
    1414     */
    15     private static $version = '1.0.1';
     15    private static $version = '1.2.1';
    1616    /**
    1717     * @var mixed
     
    3838        $this->settings_page = $settings_page;
    3939        $this->plugin_name = $plugin_name;
    40         register_activation_hook($this->plugin_file, array($this, 'plugin_activate'));
    4140
    4241        register_uninstall_hook($this->plugin_file, array('\Fullworks_Free_Plugin_Lib\Main', 'plugin_uninstall'));
    4342        add_filter('plugin_action_links_' . $this->plugin_file, array($this, 'plugin_action_links'));
    4443        add_action('init', array($this, 'load_text_domain'));
     44        add_action('admin_init', array($this, 'handle_skip_optin'));
     45        add_action('admin_init', array($this, 'handle_optin_page'));
    4546        add_action('admin_menu', array($this, 'add_settings_page'));
    4647
    4748        // Move AJAX handler registration outside current_screen
    4849        add_action('wp_ajax_ffpl_handle_optin', array($this, 'handle_optin_ajax'));
     50        add_action('wp_ajax_ffpl_dismiss_notice', array($this, 'handle_dismiss_notice'));
    4951
    5052        // Move enqueue assets to admin_enqueue_scripts
    5153        add_action('admin_enqueue_scripts', array($this, 'conditional_enqueue_assets'));
    5254
     55        // Admin notice for setup prompt
     56        add_action('admin_notices', array($this, 'maybe_show_setup_notice'));
     57
    5358        add_action('ffpl_ad_display', array(new Classes\Advert(), 'ad_display'));
    54     }
    55 
    56     public function plugin_activate() {
    57         if (!get_site_option(self::$plugin_shortname . '_form_rendered')) {
    58             if (isset($_REQUEST['_wpnonce'])) {
    59                 $bulk_nonce = wp_verify_nonce($_REQUEST['_wpnonce'], 'bulk-plugins');
    60                 $single_nonce = wp_verify_nonce($_REQUEST['_wpnonce'], 'activate-plugin_' . $this->plugin_file);
    61                 if (!$bulk_nonce && !$single_nonce) {
    62                     return;
    63                 }
    64             } else {
    65                 return;
    66             }
    67             if (isset($_GET['activate-multi'])) {
    68                 return;
    69             }
    70             if (isset($_REQUEST['action']) &&
    71                 'activate-selected' === sanitize_text_field(wp_unslash($_REQUEST['action'])) &&
    72                 isset($_REQUEST['checked']) &&
    73                 is_array($_REQUEST['checked']) &&
    74                 count($_REQUEST['checked']) > 1
    75             ) {
    76                 return;
    77             }
    78             update_site_option(self::$plugin_shortname . '_form_rendered', 'pending');
    79         }
    8059    }
    8160
    8261    public static function plugin_uninstall() {
    8362        delete_site_option(self::$plugin_shortname . '_form_rendered');
     63    }
     64
     65    public function handle_skip_optin() {
     66        if (!isset($_GET['ffpl_skip'])) {
     67            return;
     68        }
     69
     70        // Verify nonce - the nonce IS the ffpl_skip value
     71        $nonce = sanitize_text_field(wp_unslash($_GET['ffpl_skip']));
     72        if (!wp_verify_nonce($nonce, 'ffpl_skip_' . self::$plugin_shortname)) {
     73            return;
     74        }
     75
     76        // Set status to optout - user explicitly skipped
     77        update_site_option(self::$plugin_shortname . '_form_rendered', 'optout');
     78
     79        // Redirect to clean URL (remove the skip param)
     80        wp_safe_redirect(remove_query_arg('ffpl_skip'));
     81        exit;
     82    }
     83
     84    public function handle_optin_page() {
     85        // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- This is page routing, not form processing
     86        $current_page = isset($_GET['page']) ? sanitize_text_field(wp_unslash($_GET['page'])) : '';
     87        $option = get_site_option(self::$plugin_shortname . '_form_rendered');
     88        if ('pending' === $option && $current_page === $this->page) {
     89            update_site_option(self::$plugin_shortname . '_form_rendered', 'rendering');
     90            wp_safe_redirect(admin_url('options-general.php?page=ffpl-opt-in-' . self::$plugin_shortname));
     91            exit;
     92        }
    8493    }
    8594
     
    102111
    103112    public function add_settings_page() {
    104         $option = get_site_option(self::$plugin_shortname . '_form_rendered', 'optout');
    105         if ('pending' === $option) {
    106             update_site_option(self::$plugin_shortname . '_form_rendered', 'rendering');
    107             wp_safe_redirect(admin_url('options-general.php?page=ffpl-opt-in-'.self::$plugin_shortname ));
    108             exit;
    109         }
    110         if (in_array($option, array('rendering', 'optout'))) {
     113        // First-run detection - if option doesn't exist, set to pending
     114        $option = get_site_option(self::$plugin_shortname . '_form_rendered');
     115        if (false === $option) {
     116            update_site_option(self::$plugin_shortname . '_form_rendered', 'pending');
     117            $option = 'pending';
     118        }
     119
     120        // Register the opt-in page if not yet completed
     121        if (in_array($option, array('pending', 'rendering', 'optout'))) {
    111122            add_options_page(
    112123                esc_html($this->translate('Opt In ')) . esc_html( $this->plugin_name), // Page title
     
    126137    public function render_opt_in_page() {
    127138        $user = wp_get_current_user();
    128         update_site_option(self::$plugin_shortname . '_form_rendered', 'optout');
     139        // Keep status as 'rendering' while viewing - only change on actual user action
    129140        ?>
    130141        <div class="fpl-page-wrap" role="main">
     
    178189                            </div>
    179190                            <div class="button-2">
    180                                 <a href="<?php echo esc_url($this->settings_page); ?>"
     191                                <a href="<?php echo esc_url(add_query_arg('ffpl_skip', wp_create_nonce('ffpl_skip_' . self::$plugin_shortname), $this->settings_page)); ?>"
    181192                                   class="button button-secondary btn-skip" name="action" value="skip"
    182193                                   tabindex="2">
     
    244255    public function handle_optin_ajax() {
    245256        // Verify request method
    246         if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
     257        if (!isset($_SERVER['REQUEST_METHOD']) || $_SERVER['REQUEST_METHOD'] !== 'POST') {
    247258            wp_send_json_error(['message' => $this->translate('Invalid request method')]);
    248259            wp_die();
     
    273284        }
    274285
    275         $email = sanitize_email(wp_unslash($_POST['email']));
     286        $email = isset($_POST['email']) ? sanitize_email(wp_unslash($_POST['email'])) : '';
    276287
    277288        $email_handler = new Email(self::$plugin_shortname);
     
    292303    }
    293304
     305    public function maybe_show_setup_notice() {
     306        // Only for users who can manage options
     307        if (!current_user_can('manage_options')) {
     308            return;
     309        }
     310
     311        $screen = get_current_screen();
     312        if (!$screen) {
     313            return;
     314        }
     315
     316        $option = get_site_option(self::$plugin_shortname . '_form_rendered');
     317
     318        // Only show notice if no decision has been made yet (pending or rendering)
     319        // Don't show if optin, optout, or any other status - a decision was made
     320        if (!in_array($option, array('pending', 'rendering'), true)) {
     321            return;
     322        }
     323
     324        // Don't show if user dismissed the notice
     325        if (get_user_meta(get_current_user_id(), self::$plugin_shortname . '_notice_dismissed', true)) {
     326            return;
     327        }
     328
     329        // Show on dashboard, plugins page, tools, options-general, or this plugin's settings page
     330        $page = $screen->base;
     331        $display_on_pages = array(
     332            'dashboard',
     333            'plugins',
     334            'tools',
     335            'options-general',
     336            'settings_page_' . $this->page,
     337        );
     338
     339        if (!in_array($page, $display_on_pages, true)) {
     340            return;
     341        }
     342
     343        $opt_in_url = admin_url('options-general.php?page=ffpl-opt-in-' . self::$plugin_shortname);
     344        ?>
     345        <div class="notice notice-info is-dismissible ffpl-setup-notice" data-shortname="<?php echo esc_attr(self::$plugin_shortname); ?>">
     346            <p>
     347                <strong><?php echo esc_html($this->plugin_name); ?>:</strong>
     348                <?php
     349                printf(
     350                    '%s <a href="%s"><strong>%s</strong></a> %s',
     351                    esc_html($this->translate('You haven\'t visited settings yet.')),
     352                    esc_url($this->settings_page),
     353                    esc_html($this->translate('Please check your settings')),
     354                    esc_html($this->translate('for optimal configuration and opt in for security updates, tips and occasional offers.'))
     355                );
     356                ?>
     357            </p>
     358        </div>
     359        <script>
     360        jQuery(document).ready(function($) {
     361            $('.ffpl-setup-notice').on('click', '.notice-dismiss', function() {
     362                var shortname = $(this).closest('.ffpl-setup-notice').data('shortname');
     363                $.post(ajaxurl, {
     364                    action: 'ffpl_dismiss_notice',
     365                    shortname: shortname,
     366                    nonce: '<?php echo esc_js(wp_create_nonce('ffpl_dismiss_notice')); ?>'
     367                });
     368            });
     369        });
     370        </script>
     371        <?php
     372    }
     373
     374    public function handle_dismiss_notice() {
     375        if (!current_user_can('manage_options')) {
     376            wp_send_json_error(['message' => $this->translate('Unauthorized access')], 403);
     377            wp_die();
     378        }
     379
     380        if (!check_ajax_referer('ffpl_dismiss_notice', 'nonce', false)) {
     381            wp_send_json_error(['message' => $this->translate('Security check failed')], 403);
     382            wp_die();
     383        }
     384
     385        $shortname = isset($_POST['shortname']) ? sanitize_key($_POST['shortname']) : '';
     386        if ($shortname === self::$plugin_shortname) {
     387            update_user_meta(get_current_user_id(), self::$plugin_shortname . '_notice_dismissed', true);
     388            wp_send_json_success();
     389        }
     390
     391        wp_send_json_error();
     392        wp_die();
     393    }
     394
    294395    private function translate($text) {
    295396        // deliberately done like this to stop polygots auto adding to translation files as
  • clean-and-simple-contact-form-by-meg-nicholas/tags/4.12/vendor/alanef/free_plugin_lib/src/languages/free-plugin-lib-de_DE.po

    r3254319 r3429749  
    169169msgstr "Zu viele Versuche. Bitte versuchen Sie es später erneut"
    170170
     171#: Main.php
     172msgid "You haven't visited settings yet."
     173msgstr "Sie haben die Einstellungen noch nicht besucht."
     174
     175#: Main.php
     176msgid "Please check your settings"
     177msgstr "Bitte überprüfen Sie Ihre Einstellungen"
     178
     179#: Main.php
     180msgid "for optimal configuration and opt in for security updates, tips and occasional offers."
     181msgstr "für eine optimale Konfiguration und melden Sie sich für Sicherheitsupdates, Tipps und gelegentliche Angebote an."
     182
    171183#: Classes/Advert.php
    172184msgid "Premium Plugin Advertisement"
  • clean-and-simple-contact-form-by-meg-nicholas/tags/4.12/vendor/alanef/free_plugin_lib/src/languages/free-plugin-lib-es_ES.po

    r3254319 r3429749  
    169169msgstr "Demasiados intentos. Por favor, inténtalo de nuevo más tarde"
    170170
     171#: Main.php
     172msgid "You haven't visited settings yet."
     173msgstr "Aún no has visitado la configuración."
     174
     175#: Main.php
     176msgid "Please check your settings"
     177msgstr "Por favor, revisa tu configuración"
     178
     179#: Main.php
     180msgid "for optimal configuration and opt in for security updates, tips and occasional offers."
     181msgstr "para una configuración óptima y suscríbete para recibir actualizaciones de seguridad, consejos y ofertas ocasionales."
     182
    171183#: Classes/Advert.php
    172184msgid "Premium Plugin Advertisement"
  • clean-and-simple-contact-form-by-meg-nicholas/tags/4.12/vendor/alanef/free_plugin_lib/src/languages/free-plugin-lib-fr_FR.po

    r3254319 r3429749  
    169169msgstr "Trop de tentatives. Veuillez réessayer plus tard."
    170170
     171#: Main.php
     172msgid "You haven't visited settings yet."
     173msgstr "Vous n'avez pas encore visité les paramètres."
     174
     175#: Main.php
     176msgid "Please check your settings"
     177msgstr "Veuillez vérifier vos paramètres"
     178
     179#: Main.php
     180msgid "for optimal configuration and opt in for security updates, tips and occasional offers."
     181msgstr "pour une configuration optimale et inscrivez-vous aux mises à jour de sécurité, conseils et offres occasionnelles."
     182
    171183#: Classes/Advert.php
    172184msgid "Premium Plugin Advertisement"
  • clean-and-simple-contact-form-by-meg-nicholas/tags/4.12/vendor/alanef/free_plugin_lib/src/languages/free-plugin-lib-it_IT.po

    r3254319 r3429749  
    169169msgstr "Troppi tentativi. Riprova più tardi."
    170170
     171#: Main.php
     172msgid "You haven't visited settings yet."
     173msgstr "Non hai ancora visitato le impostazioni."
     174
     175#: Main.php
     176msgid "Please check your settings"
     177msgstr "Controlla le tue impostazioni"
     178
     179#: Main.php
     180msgid "for optimal configuration and opt in for security updates, tips and occasional offers."
     181msgstr "per una configurazione ottimale e iscriviti per ricevere aggiornamenti di sicurezza, consigli e offerte occasionali."
     182
    171183#: Classes/Advert.php
    172184msgid "Premium Plugin Advertisement"
  • clean-and-simple-contact-form-by-meg-nicholas/tags/4.12/vendor/alanef/free_plugin_lib/src/languages/free-plugin-lib-ja.po

    r3254319 r3429749  
    169169msgstr "試行回数が上限を超えました。しばらく後で再試行してください"
    170170
     171#: Main.php
     172msgid "You haven't visited settings yet."
     173msgstr "まだ設定ページを訪問していません。"
     174
     175#: Main.php
     176msgid "Please check your settings"
     177msgstr "設定を確認してください"
     178
     179#: Main.php
     180msgid "for optimal configuration and opt in for security updates, tips and occasional offers."
     181msgstr "最適な設定のために、セキュリティアップデート、ヒント、特別オファーの受信を登録してください。"
     182
    171183#: Classes/Advert.php
    172184msgid "Premium Plugin Advertisement"
  • clean-and-simple-contact-form-by-meg-nicholas/tags/4.12/vendor/alanef/free_plugin_lib/src/languages/free-plugin-lib-nl_NL.po

    r3254319 r3429749  
    169169msgstr "Te veel pogingen. Probeer het later opnieuw."
    170170
     171#: Main.php
     172msgid "You haven't visited settings yet."
     173msgstr "Je hebt de instellingen nog niet bezocht."
     174
     175#: Main.php
     176msgid "Please check your settings"
     177msgstr "Controleer je instellingen"
     178
     179#: Main.php
     180msgid "for optimal configuration and opt in for security updates, tips and occasional offers."
     181msgstr "voor een optimale configuratie en meld je aan voor beveiligingsupdates, tips en incidentele aanbiedingen."
     182
    171183#: Classes/Advert.php
    172184msgid "Premium Plugin Advertisement"
  • clean-and-simple-contact-form-by-meg-nicholas/tags/4.12/vendor/alanef/free_plugin_lib/src/languages/free-plugin-lib-pl_PL.po

    r3254319 r3429749  
    169169msgstr "Zbyt wiele prób. Spróbuj ponownie później"
    170170
     171#: Main.php
     172msgid "You haven't visited settings yet."
     173msgstr "Nie odwiedziłeś jeszcze ustawień."
     174
     175#: Main.php
     176msgid "Please check your settings"
     177msgstr "Sprawdź swoje ustawienia"
     178
     179#: Main.php
     180msgid "for optimal configuration and opt in for security updates, tips and occasional offers."
     181msgstr "dla optymalnej konfiguracji i zapisz się na aktualizacje bezpieczeństwa, porady i okazjonalne oferty."
     182
    171183#: Classes/Advert.php
    172184msgid "Premium Plugin Advertisement"
  • clean-and-simple-contact-form-by-meg-nicholas/tags/4.12/vendor/alanef/free_plugin_lib/src/languages/free-plugin-lib-pt_BR.po

    r3254319 r3429749  
    169169msgstr "Muitas tentativas. Tente novamente mais tarde."
    170170
     171#: Main.php
     172msgid "You haven't visited settings yet."
     173msgstr "Você ainda não visitou as configurações."
     174
     175#: Main.php
     176msgid "Please check your settings"
     177msgstr "Por favor, verifique suas configurações"
     178
     179#: Main.php
     180msgid "for optimal configuration and opt in for security updates, tips and occasional offers."
     181msgstr "para uma configuração ideal e inscreva-se para receber atualizações de segurança, dicas e ofertas ocasionais."
     182
    171183#: Classes/Advert.php
    172184msgid "Premium Plugin Advertisement"
  • clean-and-simple-contact-form-by-meg-nicholas/tags/4.12/vendor/alanef/free_plugin_lib/src/languages/free-plugin-lib-pt_PT.po

    r3254319 r3429749  
    169169msgstr "Demasiadas tentativas. Tente novamente mais tarde."
    170170
     171#: Main.php
     172msgid "You haven't visited settings yet."
     173msgstr "Ainda não visitou as definições."
     174
     175#: Main.php
     176msgid "Please check your settings"
     177msgstr "Por favor, verifique as suas definições"
     178
     179#: Main.php
     180msgid "for optimal configuration and opt in for security updates, tips and occasional offers."
     181msgstr "para uma configuração ideal e inscreva-se para receber atualizações de segurança, dicas e ofertas ocasionais."
     182
    171183#: Classes/Advert.php
    172184msgid "Premium Plugin Advertisement"
  • clean-and-simple-contact-form-by-meg-nicholas/tags/4.12/vendor/alanef/free_plugin_lib/src/languages/free-plugin-lib-tr_TR.po

    r3254319 r3429749  
    169169msgstr "Çok fazla deneme yapıldı. Lütfen daha sonra tekrar deneyin."
    170170
     171#: Main.php
     172msgid "You haven't visited settings yet."
     173msgstr "Henüz ayarları ziyaret etmediniz."
     174
     175#: Main.php
     176msgid "Please check your settings"
     177msgstr "Lütfen ayarlarınızı kontrol edin"
     178
     179#: Main.php
     180msgid "for optimal configuration and opt in for security updates, tips and occasional offers."
     181msgstr "en iyi yapılandırma için ve güvenlik güncellemeleri, ipuçları ve ara sıra teklifler almak için kaydolun."
     182
    171183#: Classes/Advert.php
    172184msgid "Premium Plugin Advertisement"
  • clean-and-simple-contact-form-by-meg-nicholas/tags/4.12/vendor/alanef/free_plugin_lib/src/languages/free-plugin-lib.pot

    r3254319 r3429749  
    167167msgstr ""
    168168
     169#: Main.php
     170msgid "You haven't visited settings yet."
     171msgstr ""
     172
     173#: Main.php
     174msgid "Please check your settings"
     175msgstr ""
     176
     177#: Main.php
     178msgid "for optimal configuration and opt in for security updates, tips and occasional offers."
     179msgstr ""
     180
    169181#: Classes/Advert.php
    170182msgid "Premium Plugin Advertisement"
  • clean-and-simple-contact-form-by-meg-nicholas/tags/4.12/vendor/composer/autoload_static.php

    r3339262 r3429749  
    88{
    99    public static $prefixLengthsPsr4 = array (
    10         'F' => 
     10        'F' =>
    1111        array (
    1212            'Fullworks_Free_Plugin_Lib\\' => 26,
     
    1515
    1616    public static $prefixDirsPsr4 = array (
    17         'Fullworks_Free_Plugin_Lib\\' => 
     17        'Fullworks_Free_Plugin_Lib\\' =>
    1818        array (
    1919            0 => __DIR__ . '/..' . '/alanef/free_plugin_lib/src',
     
    2222
    2323    public static $prefixesPsr0 = array (
    24         'C' => 
     24        'C' =>
    2525        array (
    26             'Composer\\Installers\\' => 
     26            'Composer\\Installers\\' =>
    2727            array (
    2828                0 => __DIR__ . '/..' . '/composer/installers/src',
  • clean-and-simple-contact-form-by-meg-nicholas/tags/4.12/vendor/composer/installed.json

    r3254319 r3429749  
    33        {
    44            "name": "alanef/free_plugin_lib",
    5             "version": "v1.0.1",
    6             "version_normalized": "1.0.1.0",
     5            "version": "1.2.2",
     6            "version_normalized": "1.2.2.0",
    77            "source": {
    88                "type": "git",
    99                "url": "https://github.com/alanef/free_plugin_lib.git",
    10                 "reference": "ed52c33c73999a1fe1ee5a1b00581b9462111ac8"
     10                "reference": "11f06087774e7d533199809be898117e3ed1ef2f"
    1111            },
    1212            "dist": {
    1313                "type": "zip",
    14                 "url": "https://api.github.com/repos/alanef/free_plugin_lib/zipball/ed52c33c73999a1fe1ee5a1b00581b9462111ac8",
    15                 "reference": "ed52c33c73999a1fe1ee5a1b00581b9462111ac8",
     14                "url": "https://api.github.com/repos/alanef/free_plugin_lib/zipball/11f06087774e7d533199809be898117e3ed1ef2f",
     15                "reference": "11f06087774e7d533199809be898117e3ed1ef2f",
    1616                "shasum": ""
    1717            },
     
    2525                "yoast/wp-test-utils": "^1.2"
    2626            },
    27             "time": "2025-02-18T15:16:14+00:00",
     27            "time": "2025-12-21T18:38:49+00:00",
    2828            "type": "library",
    2929            "installation-source": "dist",
     
    4646            "support": {
    4747                "issues": "https://github.com/alanef/free_plugin_lib/issues",
    48                 "source": "https://github.com/alanef/free_plugin_lib/tree/v1.0.1"
     48                "source": "https://github.com/alanef/free_plugin_lib/tree/v1.2.2"
    4949            },
    5050            "install-path": "../alanef/free_plugin_lib"
  • clean-and-simple-contact-form-by-meg-nicholas/tags/4.12/vendor/composer/installed.php

    r3339262 r3429749  
    22    'root' => array(
    33        'name' => 'fullworks/clean-and-simple-contact-form',
    4         'pretty_version' => 'v4.11',
    5         'version' => '4.11.0.0',
    6         'reference' => '801b967317613364d9e34394960f064495cb2283',
     4        'pretty_version' => '4.12',
     5        'version' => '4.12.0.0',
     6        'reference' => 'e6f8da67924ce3947db78743e4f95175c6bf98af',
    77        'type' => 'wordpress-plugin',
    88        'install_path' => __DIR__ . '/../../',
     
    1212    'versions' => array(
    1313        'alanef/free_plugin_lib' => array(
    14             'pretty_version' => 'v1.0.1',
    15             'version' => '1.0.1.0',
    16             'reference' => 'ed52c33c73999a1fe1ee5a1b00581b9462111ac8',
     14            'pretty_version' => '1.2.2',
     15            'version' => '1.2.2.0',
     16            'reference' => '11f06087774e7d533199809be898117e3ed1ef2f',
    1717            'type' => 'library',
    1818            'install_path' => __DIR__ . '/../alanef/free_plugin_lib',
     
    3030        ),
    3131        'fullworks/clean-and-simple-contact-form' => array(
    32             'pretty_version' => 'v4.11',
    33             'version' => '4.11.0.0',
    34             'reference' => '801b967317613364d9e34394960f064495cb2283',
     32            'pretty_version' => '4.12',
     33            'version' => '4.12.0.0',
     34            'reference' => 'e6f8da67924ce3947db78743e4f95175c6bf98af',
    3535            'type' => 'wordpress-plugin',
    3636            'install_path' => __DIR__ . '/../../',
  • clean-and-simple-contact-form-by-meg-nicholas/tags/4.12/views/contact-form.view.php

    r3142234 r3429749  
     1<?php if ( ! defined( 'ABSPATH' ) ) exit; ?>
     2<?php
     3// Get CSS classes for current framework
     4$cscf_css = cscf_CSS_Classes::get_all_classes();
     5$cscf_form_group_class = $cscf_css['form_group'];
     6$cscf_form_group_error_class = $cscf_css['form_group_error'];
     7$cscf_input_class = $cscf_css['input'];
     8$cscf_textarea_class = $cscf_css['textarea'];
     9$cscf_button_class = $cscf_css['button'];
     10$cscf_help_text_class = $cscf_css['help_text'];
     11$cscf_input_group_class = $cscf_css['input_group'];
     12$cscf_input_addon_class = $cscf_css['input_addon'];
     13$cscf_text_error_class = $cscf_css['text_error'];
     14?>
    115<div id="cscf" class="cscfBlock">
    216    <div class="cscfMessageSent" style="display:none;">
     
    1428
    1529            <?php if ( isset( $contact->Errors['recaptcha'] ) ) { ?>
    16                 <div class="control-group form-group">
    17                     <p class="text-error"><?php echo esc_html( $contact->Errors['recaptcha'] ); ?></p>
     30                <div class="<?php echo esc_attr( $cscf_form_group_class ); ?>">
     31                    <p class="<?php echo esc_attr( $cscf_text_error_class ); ?>"><?php echo esc_html( $contact->Errors['recaptcha'] ); ?></p>
    1832                </div>
    1933            <?php } ?>
    2034
    2135            <!-- name -->
    22             <div class="control-group form-group<?php if ( isset( $contact->Errors['name'] ) ) {
    23                 echo ' error has-error';
     36            <div class="<?php echo esc_attr( $cscf_form_group_class ); ?><?php if ( isset( $contact->Errors['name'] ) ) {
     37                echo ' ' . esc_attr( $cscf_form_group_error_class );
    2438            } ?>">
    2539                <label for="cscf_name"><?php esc_html_e( 'Name:', 'clean-and-simple-contact-form-by-meg-nicholas' ); ?></label>
    2640
    2741
    28                 <div class="<?php echo ( true === cscf_PluginSettings::InputIcons() ) ? 'input-group' : ''; ?>">
    29                     <?php if ( cscf_PluginSettings::InputIcons() == true ) { ?>
    30                         <span class="input-group-addon"><span class="glyphicon glyphicon-user"></span></span>
     42                <div class="<?php echo ( true === cscf_PluginSettings::InputIcons() && ! empty( $cscf_input_group_class ) ) ? esc_attr( $cscf_input_group_class ) : ''; ?>">
     43                    <?php if ( cscf_PluginSettings::InputIcons() == true && ! empty( $cscf_input_addon_class ) ) { ?>
     44                        <span class="<?php echo esc_attr( $cscf_input_addon_class ); ?>"><span class="glyphicon glyphicon-user"></span></span>
    3145                    <?php } ?>
    32                     <input class="form-control input-xlarge"
     46                    <input class="<?php echo esc_attr( $cscf_input_class ); ?>"
    3347                           data-rule-required="true"
    3448                           data-msg-required="<?php esc_html_e( 'Please give your name.', 'clean-and-simple-contact-form-by-meg-nicholas' ); ?>"
     
    3852                    />
    3953                </div>
    40                 <span for="cscf_name" class="help-inline help-block error"
     54                <span for="cscf_name" class="<?php echo esc_attr( $cscf_help_text_class ); ?>"
    4155                      style="display:<?php echo isset( $contact->Errors['name'] ) ? 'block' : 'none'; ?>;">
    4256
     
    4963
    5064            <!--email address-->
    51             <div class="control-group form-group<?php if ( isset( $contact->Errors['email'] ) ) {
    52                 echo ' error has-error';
     65            <div class="<?php echo esc_attr( $cscf_form_group_class ); ?><?php if ( isset( $contact->Errors['email'] ) ) {
     66                echo ' ' . esc_attr( $cscf_form_group_error_class );
    5367            } ?>">
    5468                <label for="cscf_email"><?php esc_html_e( 'Email Address:', 'clean-and-simple-contact-form-by-meg-nicholas' ); ?></label>
    5569
    56                 <div class="<?php echo ( true === cscf_PluginSettings::InputIcons() ) ? 'input-group' : ''; ?>">
    57                     <?php if ( cscf_PluginSettings::InputIcons() == true ) { ?>
    58                         <span class="input-group-addon"><span class="glyphicon glyphicon-envelope"></span></span>
     70                <div class="<?php echo ( true === cscf_PluginSettings::InputIcons() && ! empty( $cscf_input_group_class ) ) ? esc_attr( $cscf_input_group_class ) : ''; ?>">
     71                    <?php if ( cscf_PluginSettings::InputIcons() == true && ! empty( $cscf_input_addon_class ) ) { ?>
     72                        <span class="<?php echo esc_attr( $cscf_input_addon_class ); ?>"><span class="glyphicon glyphicon-envelope"></span></span>
    5973                    <?php } ?>
    60                     <input class="form-control input-xlarge"
     74                    <input class="<?php echo esc_attr( $cscf_input_class ); ?>"
    6175                           data-rule-required="true"
    6276                           data-rule-email="true"
     
    6882                    />
    6983                </div>
    70                 <span for="cscf_email" class="help-inline help-block error"
     84                <span for="cscf_email" class="<?php echo esc_attr( $cscf_help_text_class ); ?>"
    7185                      style="display:<?php echo isset( $contact->Errors['email'] ) ? 'block' : 'none'; ?>;">
    7286                    <?php if ( isset( $contact->Errors['email'] ) ) {
     
    7892            <?php if ( $confirmEmail ) { ?>
    7993                <!--confirm email address -->
    80                 <div class="control-group form-group<?php if ( isset( $contact->Errors['confirm-email'] ) ) {
    81                     echo ' error has-error';
     94                <div class="<?php echo esc_attr( $cscf_form_group_class ); ?><?php if ( isset( $contact->Errors['confirm-email'] ) ) {
     95                    echo ' ' . esc_attr( $cscf_form_group_error_class );
    8296                } ?>">
    8397                    <label for="cscf_confirm-email"><?php esc_html_e( 'Confirm Email Address:', 'clean-and-simple-contact-form-by-meg-nicholas' ); ?></label>
    84                     <div class="<?php echo ( true === cscf_PluginSettings::InputIcons() ) ? 'input-group' : ''; ?>">
    85                         <?php if ( cscf_PluginSettings::InputIcons() == true ) { ?>
    86                             <span class="input-group-addon"><span class="glyphicon glyphicon-envelope"></span></span>
    87                         <?php } ?>
    88                         <input class="form-control input-xlarge"
     98                    <div class="<?php echo ( true === cscf_PluginSettings::InputIcons() && ! empty( $cscf_input_group_class ) ) ? esc_attr( $cscf_input_group_class ) : ''; ?>">
     99                        <?php if ( cscf_PluginSettings::InputIcons() == true && ! empty( $cscf_input_addon_class ) ) { ?>
     100                            <span class="<?php echo esc_attr( $cscf_input_addon_class ); ?>"><span class="glyphicon glyphicon-envelope"></span></span>
     101                        <?php } ?>
     102                        <input class="<?php echo esc_attr( $cscf_input_class ); ?>"
    89103                               data-rule-required="true"
    90104                               data-rule-email="true"
     
    98112                        />
    99113                    </div>
    100                     <span for="cscf_confirm-email" class="help-inline help-block error"
     114                    <span for="cscf_confirm-email" class="<?php echo esc_attr( $cscf_help_text_class ); ?>"
    101115                          style="display:<?php echo isset( $contact->Errors['confirm-email'] ) ? 'block' : 'none'; ?>;">
    102116                    <?php if ( isset( $contact->Errors['confirm-email'] ) ) {
     
    109123            <?php if ( cscf_PluginSettings::PhoneNumber() ) { ?>
    110124                <!-- telephone number -->
    111                 <div class="control-group form-group<?php if ( isset( $contact->Errors['phone-number'] ) ) {
    112                     echo ' error has-error';
     125                <div class="<?php echo esc_attr( $cscf_form_group_class ); ?><?php if ( isset( $contact->Errors['phone-number'] ) ) {
     126                    echo ' ' . esc_attr( $cscf_form_group_error_class );
    113127                } ?>">
    114128                    <label for="cscf_phone-number"><?php esc_html_e( 'Phone Number:', 'clean-and-simple-contact-form-by-meg-nicholas' ); ?></label>
    115                     <div class="<?php echo ( true === cscf_PluginSettings::InputIcons() ) ? 'input-group' : ''; ?>">
    116                         <?php if ( cscf_PluginSettings::InputIcons() == true ) { ?>
    117                             <span class="input-group-addon"><span class="glyphicon glyphicon-phone-alt"></span></span>
    118                         <?php } ?>
    119                         <input class="form-control input-xlarge"
     129                    <div class="<?php echo ( true === cscf_PluginSettings::InputIcons() && ! empty( $cscf_input_group_class ) ) ? esc_attr( $cscf_input_group_class ) : ''; ?>">
     130                        <?php if ( cscf_PluginSettings::InputIcons() == true && ! empty( $cscf_input_addon_class ) ) { ?>
     131                            <span class="<?php echo esc_attr( $cscf_input_addon_class ); ?>"><span class="glyphicon glyphicon-phone-alt"></span></span>
     132                        <?php } ?>
     133                        <input class="<?php echo esc_attr( $cscf_input_class ); ?>"
    120134                               data-rule-required="<?php echo ( true === cscf_PluginSettings::PhoneNumberMandatory() ) ? 'true' : 'false'; ?>"
    121135                               data-msg-required="<?php esc_html_e( 'Please give your phone number.', 'clean-and-simple-contact-form-by-meg-nicholas' ); ?>"
     
    125139                        />
    126140                    </div>
    127                     <span for="cscf_phone-number" class="help-inline help-block error"
     141                    <span for="cscf_phone-number" class="<?php echo esc_attr( $cscf_help_text_class ); ?>"
    128142                          style="display:<?php echo isset( $contact->Errors['phone-number'] ) ? 'block' : 'none'; ?>;">
    129143                    <?php if ( isset( $contact->Errors['phone-number'] ) ) {
     
    136150
    137151            <!-- message -->
    138             <div class="control-group form-group<?php if ( isset( $contact->Errors['message'] ) ) {
    139                 echo ' error has-error';
     152            <div class="<?php echo esc_attr( $cscf_form_group_class ); ?><?php if ( isset( $contact->Errors['message'] ) ) {
     153                echo ' ' . esc_attr( $cscf_form_group_error_class );
    140154            } ?>">
    141155                <label for="cscf_message"><?php esc_html_e( 'Message:', 'clean-and-simple-contact-form-by-meg-nicholas' ); ?></label>
    142                 <div class="<?php echo ( true === cscf_PluginSettings::InputIcons() ) ? 'input-group' : ''; ?>">
    143                     <?php if ( cscf_PluginSettings::InputIcons() == true ) { ?>
    144                         <span class="input-group-addon"><span class="glyphicon glyphicon-comment"></span></span>
     156                <div class="<?php echo ( true === cscf_PluginSettings::InputIcons() && ! empty( $cscf_input_group_class ) ) ? esc_attr( $cscf_input_group_class ) : ''; ?>">
     157                    <?php if ( cscf_PluginSettings::InputIcons() == true && ! empty( $cscf_input_addon_class ) ) { ?>
     158                        <span class="<?php echo esc_attr( $cscf_input_addon_class ); ?>"><span class="glyphicon glyphicon-comment"></span></span>
    145159                    <?php } ?>
    146                     <textarea class="form-control input-xlarge"
     160                    <textarea class="<?php echo esc_attr( $cscf_textarea_class ); ?>"
    147161                              data-rule-required="true"
    148162                              data-msg-required="<?php esc_html_e( 'Please give a message.', 'clean-and-simple-contact-form-by-meg-nicholas' ); ?>"
     
    151165                </div>
    152166
    153                 <span for="cscf_message" class="help-inline help-block error"
     167                <span for="cscf_message" class="<?php echo esc_attr( $cscf_help_text_class ); ?>"
    154168                      style="display:<?php echo isset( $contact->Errors['message'] ) ? 'block' : 'none'; ?>;">
    155169                    <?php if ( isset( $contact->Errors['message'] ) ) {
     
    161175            <?php if ( cscf_PluginSettings::EmailToSender() ) { ?>
    162176                <!-- email to sender -->
    163                 <div class="control-group form-group<?php if ( isset( $contact->Errors['email-sender'] ) ) {
    164                     echo ' error has-error';
     177                <div class="<?php echo esc_attr( $cscf_form_group_class ); ?><?php if ( isset( $contact->Errors['email-sender'] ) ) {
     178                    echo ' ' . esc_attr( $cscf_form_group_error_class );
    165179                } ?>">
    166180                    <label for="cscf_email-sender"><?php esc_html_e( 'Send me a copy:', 'clean-and-simple-contact-form-by-meg-nicholas' ); ?></label>
    167                     <div class="<?php echo ( true === cscf_PluginSettings::InputIcons() ) ? "input-group" : ""; ?>">
    168                         <?php if ( cscf_PluginSettings::InputIcons() == true ) { ?>
    169                             <span class="input-group-addon"><span class="glyphicon glyphicon-comment"></span></span>
     181                    <div class="<?php echo ( true === cscf_PluginSettings::InputIcons() && ! empty( $cscf_input_group_class ) ) ? esc_attr( $cscf_input_group_class ) : ''; ?>">
     182                        <?php if ( cscf_PluginSettings::InputIcons() == true && ! empty( $cscf_input_addon_class ) ) { ?>
     183                            <span class="<?php echo esc_attr( $cscf_input_addon_class ); ?>"><span class="glyphicon glyphicon-comment"></span></span>
    170184                        <?php } ?>
    171185                        <input <?php echo ( true == $contact->EmailToSender ) ? 'checked' : ''; ?> type="checkbox"
     
    173187                                                                                                   name="cscf[email-sender]">
    174188                    </div>
    175                     <span for="cscf_email-sender" class="help-inline help-block error"
     189                    <span for="cscf_email-sender" class="<?php echo esc_attr( $cscf_help_text_class ); ?>"
    176190                          style="display:<?php echo isset( $contact->Errors['email-sender'] ) ? 'block' : 'none'; ?>;">
    177191                        <?php if ( isset( $contact->Errors['email-sender'] ) ) {
     
    186200            <?php if ( cscf_PluginSettings::ContactConsent() ) { ?>
    187201                <!-- contact consent -->
    188                 <div class="control-group form-group<?php if ( isset( $contact->Errors['contact-consent'] ) ) {
    189                     echo ' error has-error';
     202                <div class="<?php echo esc_attr( $cscf_form_group_class ); ?><?php if ( isset( $contact->Errors['contact-consent'] ) ) {
     203                    echo ' ' . esc_attr( $cscf_form_group_error_class );
    190204                } ?>">
    191205                    <label for="cscf_contact-consent"><?php echo esc_html( cscf_PluginSettings::ContactConsentMsg() ); ?>:</label>
    192                     <div class="<?php echo ( cscf_PluginSettings::InputIcons() ) ? "input-group" : ""; ?>">
    193                         <?php if ( cscf_PluginSettings::InputIcons() == true ) { ?>
    194                             <span class="input-group-addon"><span class="glyphicon glyphicon-comment"></span></span>
    195                         <?php } ?>
    196                         <input class="form-control input-xlarge"
     206                    <div class="<?php echo ( cscf_PluginSettings::InputIcons() && ! empty( $cscf_input_group_class ) ) ? esc_attr( $cscf_input_group_class ) : ''; ?>">
     207                        <?php if ( cscf_PluginSettings::InputIcons() == true && ! empty( $cscf_input_addon_class ) ) { ?>
     208                            <span class="<?php echo esc_attr( $cscf_input_addon_class ); ?>"><span class="glyphicon glyphicon-comment"></span></span>
     209                        <?php } ?>
     210                        <input class="<?php echo esc_attr( $cscf_input_class ); ?>"
    197211                               data-rule-required="true"
    198212                               data-msg-required="<?php esc_html_e( 'Please give your consent.', 'clean-and-simple-contact-form-by-meg-nicholas' ); ?>"
     
    201215                               name="cscf[contact-consent]">
    202216                    </div>
    203                     <span for="cscf[contact-consent]" class="help-inline help-block error"
     217                    <span for="cscf[contact-consent]" class="<?php echo esc_attr( $cscf_help_text_class ); ?>"
    204218                          style="display:<?php echo isset( $contact->Errors['contact-consent'] ) ? 'block' : 'none'; ?>;">
    205219                        <?php if ( isset( $contact->Errors['contact-consent'] ) ) {
     
    213227            <?php if ( $contact->RecaptchaPublicKey <> '' && $contact->RecaptchaPrivateKey <> '' ) { ?>
    214228
    215                 <div class="control-group form-group<?php
     229                <div class="<?php echo esc_attr( $cscf_form_group_class ); ?><?php
    216230                if ( isset( $contact->Errors['recaptcha'] ) ) {
    217                     echo ' error has-error';
     231                    echo ' ' . esc_attr( $cscf_form_group_error_class );
    218232                } ?>">
    219233                    <div id="recaptcha_div">
     
    223237
    224238                        <div for="cscf_recaptcha"
    225                              class="help-block has-error error"><?php if ( isset( $contact->Errors['recaptcha'] ) ) {
     239                             class="<?php echo esc_attr( $cscf_help_text_class ); ?>"><?php if ( isset( $contact->Errors['recaptcha'] ) ) {
    226240                                echo esc_html( $contact->Errors['recaptcha'] );
    227241                            } ?></div>
     
    254268                </div>
    255269            <?php } ?>
    256             <input type="submit" id="cscf_SubmitButton" class="btn btn-default"
     270            <input type="submit" id="cscf_SubmitButton" class="<?php echo esc_attr( $cscf_button_class ); ?>"
    257271                   value="<?php esc_html_e( 'Send Message', 'clean-and-simple-contact-form-by-meg-nicholas' ); ?>"/>
    258272        </form>
  • clean-and-simple-contact-form-by-meg-nicholas/tags/4.12/views/message-not-sent.view.php

    r3142234 r3429749  
     1<?php if ( ! defined( 'ABSPATH' ) ) exit; ?>
    12<p>
    23    <?php esc_html_e('Sorry, there has been a problem and your message was not sent.','clean-and-simple-contact-form-by-meg-nicholas') ?></p>
  • clean-and-simple-contact-form-by-meg-nicholas/tags/4.12/views/message-sent.view.php

    r2551686 r3429749  
     1<?php if ( ! defined( 'ABSPATH' ) ) exit; ?>
    12<h3><?php echo esc_html($heading); ?></h3>
    23<p><?php echo esc_html($message); ?> </p>
  • clean-and-simple-contact-form-by-meg-nicholas/trunk/ajax.php

    r3339262 r3429749  
    11<?php
     2if ( ! defined( 'ABSPATH' ) ) exit;
    23add_action( "wp_ajax_cscf-submitform", "cscfsubmitform" );
    34add_action( "wp_ajax_nopriv_cscf-submitform", "cscfsubmitform" );
  • clean-and-simple-contact-form-by-meg-nicholas/trunk/changelog.txt

    r3339262 r3429749  
     1= 4.12 =
     2* Added CSS Framework selection for flexible form styling
     3  - Bootstrap (default) - maintains backward compatibility
     4  - Modern (Card style) - opinionated modern design with CSS variables for easy customization
     5  - Theme Native - minimal classes, inherits theme styles with wp-element-button for submit
     6  - Minimal - semantic classes only for complete custom styling
     7* New Modern style features:
     8  - Card-style container with subtle shadow
     9  - Large, comfortable input fields
     10  - Clean typography and spacing
     11  - Dark mode support (auto-detects or via .dark class)
     12  - Full CSS variable system for easy theming
     13  - Responsive design
     14* Added filter hooks for developers to customize CSS classes
     15  - cscf_css_classes filter for complete class mapping override
     16  - cscf_css_class filter for individual element customization
     17* Improved theme compatibility - form now adapts to different CSS frameworks
     18* Added direct file access protection to all PHP files
     19* Update wp tested to 6.9
     20* update plugin free lib
     21
    122= 4.11 =
    223* Added REST API support for headless WordPress implementations
  • clean-and-simple-contact-form-by-meg-nicholas/trunk/class.cscf.php

    r3339262 r3429749  
    11<?php
     2if ( ! defined( 'ABSPATH' ) ) exit;
    23
    34class cscf {
     
    3334            /**  @var $wp_error \WP_Error */
    3435            if ( defined( 'WP_DEBUG' ) && true == WP_DEBUG && is_wp_error( $wp_error ) ) {
     36                // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_trigger_error -- Intentional debug output when WP_DEBUG is enabled
    3537                trigger_error( 'CSCF Email - wp_mail error msg : ' . esc_html( $wp_error->get_error_message() ), E_USER_WARNING );
    3638            }
     
    5456
    5557        wp_register_style( 'cscf-bootstrap', CSCF_PLUGIN_URL . '/css/bootstrap-forms.min.css',
     58            null, CSCF_VERSION_NUM );
     59
     60        wp_register_style( 'cscf-modern', CSCF_PLUGIN_URL . '/css/cscf-modern.css',
    5661            null, CSCF_VERSION_NUM );
    5762
     
    173178    public function SpamFilter( $contact ) {
    174179
     180        // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- WordPress core hook for spam filtering
    175181        $commentData = apply_filters( 'preprocess_comment', array(
    176182            'comment_post_ID'      => $contact->PostID,
  • clean-and-simple-contact-form-by-meg-nicholas/trunk/class.cscf_contact.php

    r3339262 r3429749  
    11<?php
     2if ( ! defined( 'ABSPATH' ) ) exit;
    23
    34/*
  • clean-and-simple-contact-form-by-meg-nicholas/trunk/class.cscf_filters.php

    r3254319 r3429749  
    11<?php
     2if ( ! defined( 'ABSPATH' ) ) exit;
    23
    34/*
  • clean-and-simple-contact-form-by-meg-nicholas/trunk/class.cscf_pluginsettings.php

    r3339262 r3429749  
    11<?php
     2if ( ! defined( 'ABSPATH' ) ) exit;
    23
    34class cscf_PluginSettings
     
    205206        return isset($options['rest_api_capability']) ? $options['rest_api_capability'] : 'edit_posts';
    206207    }
     208
     209    /**
     210     * Get the selected CSS framework
     211     *
     212     * @return string The CSS framework key (bootstrap, theme-native, none)
     213     */
     214    static function CssFramework()
     215    {
     216        $options = get_option(CSCF_OPTIONS_KEY);
     217        return isset($options['css_framework']) ? $options['css_framework'] : 'bootstrap';
     218    }
    207219}
    208220
  • clean-and-simple-contact-form-by-meg-nicholas/trunk/class.cscf_rest_api.php

    r3339262 r3429749  
    11<?php
     2if ( ! defined( 'ABSPATH' ) ) exit;
    23/**
    34 * REST API handler for Clean and Simple Contact Form
  • clean-and-simple-contact-form-by-meg-nicholas/trunk/class.cscf_settings.php

    r3339262 r3429749  
    11<?php
     2if ( ! defined( 'ABSPATH' ) ) exit;
    23
    34/*
     
    5960            <h3><?php esc_html_e( 'Support the developer', 'clean-and-simple-contact-form-by-meg-nicholas' ); ?></h3>
    6061            <p>
    61                 <?php do_action( 'ffpl_ad_display' ); ?>
     62                <?php
     63                // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Hook from Starter Plugin library
     64                do_action( 'ffpl_ad_display' );
     65                ?>
    6266            </p>
    6367
     
    163167            'print_section_info_styling',
    164168        ), 'contact-form-settings' );
     169        add_settings_field( 'css_framework', esc_html__( 'CSS Framework :', 'clean-and-simple-contact-form-by-meg-nicholas' ), array(
     170            $this,
     171            'create_fields',
     172        ), 'contact-form-settings', 'section_styling', array(
     173            'css_framework',
     174        ) );
    165175        add_settings_field( 'load_stylesheet', esc_html__( 'Use the plugin default stylesheet (un-tick to use your theme style sheet instead) :', 'clean-and-simple-contact-form-by-meg-nicholas' ), array(
    166176            $this,
     
    346356            if ( empty( $input['rest_api_capability'] ) ) {
    347357                $input['rest_api_capability'] = 'edit_posts';
     358            }
     359        }
     360
     361        // CSS framework - validate against allowed values
     362        if ( isset( $input['css_framework'] ) ) {
     363            $allowed_frameworks = array_keys( cscf_CSS_Classes::get_presets() );
     364            if ( ! in_array( $input['css_framework'], $allowed_frameworks, true ) ) {
     365                $input['css_framework'] = 'bootstrap';
    348366            }
    349367        }
     
    549567                <?php
    550568                break;
     569            case 'css_framework':
     570                $current = cscf_PluginSettings::CssFramework();
     571                $presets = cscf_CSS_Classes::get_presets();
     572                ?><label for="css_framework" class="screen-reader-text">
     573                <?php esc_html_e('CSS framework', 'clean-and-simple-contact-form-by-meg-nicholas'); ?>
     574                </label>
     575                <select id="css_framework" name="<?php echo esc_attr( CSCF_OPTIONS_KEY ); ?>[css_framework]">
     576                <?php foreach ( $presets as $key => $label ) : ?>
     577                    <option value="<?php echo esc_attr( $key ); ?>" <?php selected( $current, $key ); ?>>
     578                        <?php echo esc_html( $label ); ?>
     579                    </option>
     580                <?php endforeach; ?>
     581                </select>
     582                <p class="description">
     583                    <?php esc_html_e( 'Bootstrap: Full Bootstrap styling (default). Theme Native: Minimal classes, inherits theme styles. Minimal: Semantic classes only for custom styling.', 'clean-and-simple-contact-form-by-meg-nicholas' ); ?>
     584                </p>
     585                <?php
     586                break;
    551587            case 'use_client_validation':
    552588                $checked = cscf_PluginSettings::UseClientValidation() == true ? "checked" : "";
  • clean-and-simple-contact-form-by-meg-nicholas/trunk/class.view.php

    r3254319 r3429749  
    11<?php
     2if ( ! defined( 'ABSPATH' ) ) exit;
    23
    34class CSCF_View {
  • clean-and-simple-contact-form-by-meg-nicholas/trunk/clean-and-simple-contact-form-by-meg-nicholas.php

    r3339262 r3429749  
    11<?php
     2if ( ! defined( 'ABSPATH' ) ) exit;
    23/**
    34 * @package Clean and Simple Contact Form
     
    89Plugin URI: https://fullworks.net/products/clean-and-simple-contact-form
    910Description: A clean and simple contact form with Google reCAPTCHA and Twitter Bootstrap markup.
    10 Version: 4.11
     11Version: 4.12
    1112Requires at least: 5.6
    1213Requires PHP: 7.4
     
    5152require 'class.cscf_filters.php';
    5253require 'class.cscf_rest_api.php';
     54require 'class.cscf_css_classes.php';
    5355require 'ajax.php';
    5456require 'recaptchav2.php';
     
    7678
    7779if ( ! defined( 'CSCF_VERSION_NUM' ) ) {
    78     define( 'CSCF_VERSION_NUM', '4.11' );
     80    define( 'CSCF_VERSION_NUM', '4.12' );
    7981}
    8082
     
    8789new \Fullworks_Free_Plugin_Lib\Main('clean-and-simple-contact-form-by-meg-nicholas/clean-and-simple-contact-form-by-meg-nicholas.php',
    8890    admin_url( 'options-general.php?page=contact-form-settings' ),
    89     'CSCF-Free',
     91    'CSCF',
    9092    'settings_page_contact-form-settings',
    9193    'Clean and Simple Contact Form',);
     
    146148
    147149/*get the current version and update options to the new option*/
    148 $old_version = get_option( CSCF_VERSION_KEY );
     150$cscf_old_version = get_option( CSCF_VERSION_KEY );
    149151update_option( CSCF_VERSION_KEY, CSCF_VERSION_NUM );
    150152
    151153/*If this is a new installation then set some defaults*/
    152 if ( false == $old_version ) {
    153     $options                          = get_option( CSCF_OPTIONS_KEY );
    154     $options['use_client_validation'] = true;
    155     $options['load_stylesheet']       = true;
    156     $options['confirm-email']         = true;
    157     update_option( CSCF_OPTIONS_KEY, $options );
     154if ( false == $cscf_old_version ) {
     155    $cscf_options                          = get_option( CSCF_OPTIONS_KEY );
     156    $cscf_options['use_client_validation'] = true;
     157    $cscf_options['load_stylesheet']       = true;
     158    $cscf_options['confirm-email']         = true;
     159    update_option( CSCF_OPTIONS_KEY, $cscf_options );
    158160}
    159161
    160162/*if necessary do an upgrade*/
    161 if ( $old_version < CSCF_VERSION_NUM ) {
    162     $cscf->Upgrade( $old_version );
     163if ( $cscf_old_version < CSCF_VERSION_NUM ) {
     164    $cscf->Upgrade( $cscf_old_version );
    163165}
  • clean-and-simple-contact-form-by-meg-nicholas/trunk/composer.lock

    r3254319 r3429749  
    99        {
    1010            "name": "alanef/free_plugin_lib",
    11             "version": "v1.0.1",
     11            "version": "1.2.2",
    1212            "source": {
    1313                "type": "git",
    1414                "url": "https://github.com/alanef/free_plugin_lib.git",
    15                 "reference": "ed52c33c73999a1fe1ee5a1b00581b9462111ac8"
     15                "reference": "11f06087774e7d533199809be898117e3ed1ef2f"
    1616            },
    1717            "dist": {
    1818                "type": "zip",
    19                 "url": "https://api.github.com/repos/alanef/free_plugin_lib/zipball/ed52c33c73999a1fe1ee5a1b00581b9462111ac8",
    20                 "reference": "ed52c33c73999a1fe1ee5a1b00581b9462111ac8",
     19                "url": "https://api.github.com/repos/alanef/free_plugin_lib/zipball/11f06087774e7d533199809be898117e3ed1ef2f",
     20                "reference": "11f06087774e7d533199809be898117e3ed1ef2f",
    2121                "shasum": ""
    2222            },
     
    4949            "support": {
    5050                "issues": "https://github.com/alanef/free_plugin_lib/issues",
    51                 "source": "https://github.com/alanef/free_plugin_lib/tree/v1.0.1"
     51                "source": "https://github.com/alanef/free_plugin_lib/tree/v1.2.2"
    5252            },
    53             "time": "2025-02-18T15:16:14+00:00"
     53            "time": "2025-12-21T18:38:49+00:00"
    5454        },
    5555        {
  • clean-and-simple-contact-form-by-meg-nicholas/trunk/languages/clean-and-simple-contact-form-by-meg-nicholas.pot

    r3339262 r3429749  
    1010"Content-Type: text/plain; charset=UTF-8\n"
    1111"Content-Transfer-Encoding: 8bit\n"
    12 "POT-Creation-Date: 2025-08-04T19:28:59+00:00\n"
     12"POT-Creation-Date: 2025-12-30T13:46:08+00:00\n"
    1313"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
    1414"X-Generator: WP-CLI 2.10.0\n"
     
    6868msgstr ""
    6969
    70 #: class.cscf_contact.php:167
    71 msgid "Please enter a valid phone number."
    72 msgstr ""
    73 
    74 #: class.cscf_contact.php:174
     70#: class.cscf_contact.php:168
     71msgid "Phone number can only contain numbers, +, (), - and spaces."
     72msgstr ""
     73
     74#: class.cscf_contact.php:172
     75msgid "Please enter a valid phone number (minimum 8 characters)."
     76msgstr ""
     77
     78#: class.cscf_contact.php:177
     79msgid "Please enter your phone number."
     80msgstr ""
     81
     82#: class.cscf_contact.php:183
    7583#: views/contact-form.view.php:198
    7684msgid "Please give your consent."
    7785msgstr ""
    7886
    79 #: class.cscf_contact.php:184
     87#: class.cscf_contact.php:194
    8088msgid "Please solve the recaptcha to continue."
    8189msgstr ""
    8290
    83 #: class.cscf_contact.php:220
     91#: class.cscf_contact.php:230
    8492msgid "From"
    8593msgstr ""
    8694
    87 #: class.cscf_contact.php:221
     95#: class.cscf_contact.php:231
    8896msgid "Email"
    8997msgstr ""
    9098
    91 #: class.cscf_contact.php:223
    92 #: class.cscf_contact.php:267
     99#: class.cscf_contact.php:233
     100#: class.cscf_contact.php:277
    93101msgid "Phone"
    94102msgstr ""
    95103
    96 #: class.cscf_contact.php:225
     104#: class.cscf_contact.php:235
    97105msgid "Page URL"
    98106msgstr ""
    99107
    100 #: class.cscf_contact.php:226
    101 #: class.cscf_contact.php:269
     108#: class.cscf_contact.php:236
     109#: class.cscf_contact.php:279
    102110msgid "Message"
    103111msgstr ""
    104112
    105 #: class.cscf_contact.php:228
    106 #: class.cscf_contact.php:264
     113#: class.cscf_contact.php:238
     114#: class.cscf_contact.php:274
    107115msgid "yes"
    108116msgstr ""
    109117
    110 #: class.cscf_contact.php:228
    111 #: class.cscf_contact.php:264
     118#: class.cscf_contact.php:238
     119#: class.cscf_contact.php:274
    112120msgid "no"
    113121msgstr ""
    114122
    115 #: class.cscf_contact.php:262
     123#: class.cscf_contact.php:272
    116124msgid "Here is a copy of your message :"
    117125msgstr ""
  • clean-and-simple-contact-form-by-meg-nicholas/trunk/readme.txt

    r3339262 r3429749  
    77License URI: http://www.gnu.org/licenses/gpl.html
    88Tags: contact, form, contact form, feedback form, bootstrap
    9 Tested up to: 6.8
    10 Stable tag: 4.11
    11 
    12 A clean and simple contact form with Bootstrap markup.
     9Tested up to: 6.9
     10Stable tag: 4.12
     11
     12A clean and simple contact form with flexible CSS framework support.
    1313
    1414
    1515== Description ==
    16 A clean and simple AJAX contact form with Google reCAPTCHA, Twitter Bootstrap markup, spam filtering, and REST API support for headless WordPress implementations.
     16A clean and simple AJAX contact form with Google reCAPTCHA, flexible CSS framework support, spam filtering, and REST API support for headless WordPress implementations.
    1717
    1818*   **Clean**: all user inputs are stripped in order to avoid cross-site scripting (XSS) vulnerabilities.
     
    2020*   **Simple**: AJAX enabled validation and submission for immediate response and guidance for your users (can be switched off).
    2121
    22 *   **Stylish**: Use the included stylesheet or switch it off and use your own for seamless integration with your website.
    23 Uses **Twitter Bootstrap** classes.
     22*   **Flexible Styling**: Choose your CSS framework - Bootstrap (default), Theme Native (inherits your theme's styles), or Minimal (semantic classes for complete custom styling).
    2423
    2524*   **REST API Support**: Enable headless WordPress implementations to submit forms via authenticated REST API endpoints.
     
    6059*   The form can **integrate seamlessly into your website**. Turn off the plugin’s default css style sheet so that your theme’s style sheet can be used instead.
    6160
    62 *   If your theme is based on **twitter bootstrap** then this plugin will fit right in because it already has all the right div’s and CSS classes for bootstrap.
     61*   **Flexible CSS styling**: Choose from Bootstrap, Modern (with dark mode), Theme Native, or Minimal styling modes to match your site's design.
    6362
    6463*   This plugin will only link in its jQuery file where it’s needed, it **will not impose** itself on every page of your whole site!
     
    112111*   **Message Sent Content**: The message content or body displayed to the user after the message has been sent.
    113112
    114 *   **Use this plugin’s default stylesheet**: The plugin comes with a default style sheet to make the form look nice for your user. Untick this if you want to use your theme’s stylesheet instead. The default stylesheet will simply not be linked in.
     113*   **CSS Framework**: Choose how the form is styled:
     114    - **Bootstrap (Default)**: Uses Bootstrap CSS classes for full Bootstrap compatibility. Best for themes already using Bootstrap.
     115    - **Modern (Card style)**: A beautiful, opinionated modern design with card-style layout, large inputs, and CSS variables for easy customization. Includes automatic dark mode support.
     116    - **Theme Native**: Uses minimal classes with WordPress's wp-element-button for the submit button. The form inherits your theme's native form styles.
     117    - **Minimal**: Uses semantic CSS classes only (cscf-field, cscf-input, etc.) for complete custom styling control.
     118
     119*   **Use this plugin's default stylesheet**: The plugin comes with a default style sheet to make the form look nice for your user. Untick this if you want to use your theme's stylesheet instead. The default stylesheet will simply not be linked in. This option is most relevant when using the Bootstrap CSS framework.
    115120
    116121*   **Use client side validation (Ajax)**: When ticked the contact form will be validated and submitted on the client giving your user instant feedback if they have filled the form in incorrectly. If you wish the form to be validated and submitted only to the server then untick this option.
     
    324329= How do I change the text box sizes? =
    325330
    326 The plugin now uses Bootstrap 3. The text box widths now use up 100% of the available width.
     331When using Bootstrap (the default), text box widths use up 100% of the available width.
    327332This makes the form responsive to all types of media. If you want to have a fixed width for the form you can put some styling around the shortcode:
    328333`<div style="width:600px;">[cscf-contact-form]</div>`
     334
     335= How do I make the form match my theme's style? =
     336
     337You have several options:
     338
     3391. **Modern mode**: Select "Modern (Card style)" for a beautiful, ready-to-use design that can be customized with CSS variables.
     340
     3412. **Theme Native mode**: Change the CSS Framework setting to "Theme Native". This uses minimal CSS classes and lets your theme's native form styles take over.
     342
     3433. **Minimal mode**: Change the CSS Framework setting to "Minimal" for complete custom styling control using semantic classes like cscf-field, cscf-input, cscf-button.
     344
     3454. **Custom CSS**: Keep Bootstrap mode but disable "Use the plugin default stylesheet" and add your own CSS rules.
     346
     3475. **Developer filters**: Use the `cscf_css_classes` and `cscf_css_class` filters to customize the CSS classes used by the form.
     348
     349= How do I customize the Modern style? =
     350
     351The Modern style uses CSS variables that you can override in your theme. Add this to your theme's CSS:
     352
     353`
     354:root {
     355  --cscf-primary: #0066cc;       /* Button and focus colors */
     356  --cscf-radius: 0.75rem;        /* Border radius */
     357  --cscf-border: #d1d5db;        /* Border color */
     358  --cscf-error: #dc2626;         /* Error color */
     359}
     360`
     361
     362Full list of variables available in the cscf-modern.css file. Dark mode is automatically supported via `prefers-color-scheme` or by adding the `.dark` class to your HTML element.
    329363
    330364= Can I have multiple forms? =
  • clean-and-simple-contact-form-by-meg-nicholas/trunk/shortcodes/contact-form.php

    r3339262 r3429749  
    11<?php
     2if ( ! defined( 'ABSPATH' ) ) exit;
    23add_shortcode( 'contact-form', 'cscf_ContactForm' );
    34add_shortcode( 'cscf-contact-form', 'cscf_ContactForm' );
     
    3334    }
    3435
    35     //only load the stylesheet if required
    36     if ( cscf_PluginSettings::LoadStyleSheet() == true ) {
     36    //load the appropriate stylesheet based on CSS framework
     37    $css_framework = cscf_PluginSettings::CssFramework();
     38    if ( 'modern' === $css_framework ) {
     39        wp_enqueue_style( 'cscf-modern' );
     40    } elseif ( 'bootstrap' === $css_framework && cscf_PluginSettings::LoadStyleSheet() == true ) {
    3741        wp_enqueue_style( 'cscf-bootstrap' );
    3842    }
  • clean-and-simple-contact-form-by-meg-nicholas/trunk/vendor/alanef/free_plugin_lib/composer.json

    r3254319 r3429749  
    11{
    22  "name": "alanef/free_plugin_lib",
     3  "version": "1.2.2",
    34  "description": "Library to add to free plugins, in compliance with wp.org",
    45  "type": "library",
  • clean-and-simple-contact-form-by-meg-nicholas/trunk/vendor/alanef/free_plugin_lib/package.json

    r3254319 r3429749  
    11{
    22  "name": "free_plugin_lib",
    3   "version": "1.0.1"
     3  "version": "1.2.2"
    44}
  • clean-and-simple-contact-form-by-meg-nicholas/trunk/vendor/alanef/free_plugin_lib/src/Classes/Email.php

    r3254319 r3429749  
    44
    55class Email {
    6     private static $plugin_shortname;
     6    private static $plugin_shortname;
    77
    8     public function __construct($plugin_shortname) {
    9         self::$plugin_shortname = $plugin_shortname;
    10     }
     8    // Plugin shortname to ID mapping
     9    private static $plugin_map = [
     10        'SWEGTS' => 'swegts',
     11        'SSFGM'  => 'ssfgm',
     12        'LHF'    => 'lhf',
     13        'SUE'    => 'sue',
     14        'RSHFD'  => 'rshfd',
     15        'FAUM'   => 'faum',
     16        'FSS'    => 'fss',
     17        'MMT'    => 'mmt',
     18        'CSCF'   => 'cscf',
     19    ];
    1120
    12     public function handle_optin_submission($email) {
    13         // Enhanced email validation
    14         if (!filter_var($email, FILTER_VALIDATE_EMAIL) || strlen($email) > 254) {
    15             return false;
    16         }
    17        
    18         // Prepare API endpoint with sanitization
    19         $api_endpoint = esc_url_raw('https://octopus.fullworksplugins.com/wp-json/fullworks-freemius-octopusmail/v2/action');
    20         $list_id = '4c6924da-03e8-11ef-b408-2f0724a38cbd';
    21         $tag = sanitize_key(self::$plugin_shortname);
    22        
    23         // Prepare request with security headers
    24         $response = wp_remote_post('https://octopus.fullworksplugins.com/wp-json/fullworks-freemius-octopusmail/v2/action?list=4c6924da-03e8-11ef-b408-2f0724a38cbd&tag_free=' . self::$plugin_shortname, array(
    25             'headers' => array(
    26                 'Content-Type' => 'application/json',
    27                 'User-Agent' => 'WordPress/' . get_bloginfo('version'),
    28             ),
    29             'body' => wp_json_encode([
    30                 'type' => 'user.marketing.opted_in',
    31                 'plugin_id' => '1330',
    32                 'is_live' => true,
    33                 'objects' => [
    34                     'user' => [
    35                         'is_marketing_allowed' => true,
    36                         'email' => sanitize_email($email),
    37                         'first' => '',
    38                         'last' => '',
    39                         'ip' =>  Security::get_client_ip(),
    40                         'plugin_shortname' => self::$plugin_shortname,
    41                         'source' => get_site_url(),
    42                     ]
    43                 ]
    44             ]),
    45             'timeout' => 15,
    46             'sslverify' => true,
    47             'blocking' => true,
    48         ));
     21    public function __construct($plugin_shortname) {
     22        self::$plugin_shortname = $plugin_shortname;
     23    }
    4924
    50         if (is_wp_error($response)) {
    51             return false;
    52         }
     25    public function handle_optin_submission($email) {
     26        // Enhanced email validation
     27        if (!filter_var($email, FILTER_VALIDATE_EMAIL) || strlen($email) > 254) {
     28            return false;
     29        }
    5330
    54         $response_code = wp_remote_retrieve_response_code($response);
    55         if ($response_code !== 200) {
    56             return false;
    57         }
     31        // Allow filtering of plugin map for testing/extensions
     32        $plugin_map = apply_filters( 'ffpl_plugin_map', self::$plugin_map );
    5833
    59         return true;
    60     }
     34        // Get plugin ID from map
     35        $plugin_id = $plugin_map[self::$plugin_shortname] ?? null;
     36        if (!$plugin_id) {
     37            return false;
     38        }
     39
     40        // Allow filtering of the verification URL for testing
     41        $verify_url = apply_filters( 'ffpl_verify_url', 'https://campaign.email.fw9.uk/api/webhook/product' );
     42
     43        $response = wp_remote_post($verify_url, [
     44            'headers' => [
     45                'Content-Type' => 'application/json',
     46                'User-Agent' => 'WordPress/' . get_bloginfo('version'),
     47            ],
     48            'body' => wp_json_encode([
     49                'type' => 'install.installed',
     50                'plugin_id' => $plugin_id,
     51                'is_live' => true,
     52                'objects' => [
     53                    'user' => [
     54                        'is_marketing_allowed' => true,
     55                        'email' => sanitize_email($email),
     56                        'first' => '',
     57                        'last' => '',
     58                        'ip' => Security::get_client_ip(),
     59                        'id' => null,
     60                    ],
     61                    'install' => [
     62                        'is_premium' => false,
     63                        'is_active' => true,
     64                        'license_id' => null,
     65                        'trial_plan_id' => null,
     66                        'trial_ends' => null,
     67                        'country_code' => '',
     68                        'url' => get_site_url(),
     69                    ]
     70                ]
     71            ]),
     72            'timeout' => 15,
     73            'sslverify' => true,
     74            'blocking' => true,
     75        ]);
     76
     77        if (is_wp_error($response)) {
     78            return false;
     79        }
     80
     81        return wp_remote_retrieve_response_code($response) === 200;
     82    }
    6183}
  • clean-and-simple-contact-form-by-meg-nicholas/trunk/vendor/alanef/free_plugin_lib/src/Classes/Security.php

    r3254319 r3429749  
    1212     */
    1313    public static function verify_nonce($nonce_name, $action) {
    14         return isset($_REQUEST[$nonce_name]) && wp_verify_nonce($_REQUEST[$nonce_name], $action);
     14        if (!isset($_REQUEST[$nonce_name])) {
     15            return false;
     16        }
     17        $nonce = sanitize_text_field(wp_unslash($_REQUEST[$nonce_name]));
     18        return wp_verify_nonce($nonce, $action);
    1519    }
    1620
     
    4347    public static function get_client_ip() {
    4448        $ip = '127.0.0.1';
    45        
     49
    4650        if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
    47             $ip = sanitize_text_field($_SERVER['HTTP_CLIENT_IP']);
     51            $ip = sanitize_text_field(wp_unslash($_SERVER['HTTP_CLIENT_IP']));
    4852        } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
    49             $ip = sanitize_text_field($_SERVER['HTTP_X_FORWARDED_FOR']);
     53            $ip = sanitize_text_field(wp_unslash($_SERVER['HTTP_X_FORWARDED_FOR']));
    5054        } elseif (!empty($_SERVER['REMOTE_ADDR'])) {
    51             $ip = sanitize_text_field($_SERVER['REMOTE_ADDR']);
     55            $ip = sanitize_text_field(wp_unslash($_SERVER['REMOTE_ADDR']));
    5256        }
    53        
     57
    5458        return filter_var($ip, FILTER_VALIDATE_IP) ? $ip : '127.0.0.1';
    5559    }
  • clean-and-simple-contact-form-by-meg-nicholas/trunk/vendor/alanef/free_plugin_lib/src/Main.php

    r3254319 r3429749  
    1313     * @var string
    1414     */
    15     private static $version = '1.0.1';
     15    private static $version = '1.2.1';
    1616    /**
    1717     * @var mixed
     
    3838        $this->settings_page = $settings_page;
    3939        $this->plugin_name = $plugin_name;
    40         register_activation_hook($this->plugin_file, array($this, 'plugin_activate'));
    4140
    4241        register_uninstall_hook($this->plugin_file, array('\Fullworks_Free_Plugin_Lib\Main', 'plugin_uninstall'));
    4342        add_filter('plugin_action_links_' . $this->plugin_file, array($this, 'plugin_action_links'));
    4443        add_action('init', array($this, 'load_text_domain'));
     44        add_action('admin_init', array($this, 'handle_skip_optin'));
     45        add_action('admin_init', array($this, 'handle_optin_page'));
    4546        add_action('admin_menu', array($this, 'add_settings_page'));
    4647
    4748        // Move AJAX handler registration outside current_screen
    4849        add_action('wp_ajax_ffpl_handle_optin', array($this, 'handle_optin_ajax'));
     50        add_action('wp_ajax_ffpl_dismiss_notice', array($this, 'handle_dismiss_notice'));
    4951
    5052        // Move enqueue assets to admin_enqueue_scripts
    5153        add_action('admin_enqueue_scripts', array($this, 'conditional_enqueue_assets'));
    5254
     55        // Admin notice for setup prompt
     56        add_action('admin_notices', array($this, 'maybe_show_setup_notice'));
     57
    5358        add_action('ffpl_ad_display', array(new Classes\Advert(), 'ad_display'));
    54     }
    55 
    56     public function plugin_activate() {
    57         if (!get_site_option(self::$plugin_shortname . '_form_rendered')) {
    58             if (isset($_REQUEST['_wpnonce'])) {
    59                 $bulk_nonce = wp_verify_nonce($_REQUEST['_wpnonce'], 'bulk-plugins');
    60                 $single_nonce = wp_verify_nonce($_REQUEST['_wpnonce'], 'activate-plugin_' . $this->plugin_file);
    61                 if (!$bulk_nonce && !$single_nonce) {
    62                     return;
    63                 }
    64             } else {
    65                 return;
    66             }
    67             if (isset($_GET['activate-multi'])) {
    68                 return;
    69             }
    70             if (isset($_REQUEST['action']) &&
    71                 'activate-selected' === sanitize_text_field(wp_unslash($_REQUEST['action'])) &&
    72                 isset($_REQUEST['checked']) &&
    73                 is_array($_REQUEST['checked']) &&
    74                 count($_REQUEST['checked']) > 1
    75             ) {
    76                 return;
    77             }
    78             update_site_option(self::$plugin_shortname . '_form_rendered', 'pending');
    79         }
    8059    }
    8160
    8261    public static function plugin_uninstall() {
    8362        delete_site_option(self::$plugin_shortname . '_form_rendered');
     63    }
     64
     65    public function handle_skip_optin() {
     66        if (!isset($_GET['ffpl_skip'])) {
     67            return;
     68        }
     69
     70        // Verify nonce - the nonce IS the ffpl_skip value
     71        $nonce = sanitize_text_field(wp_unslash($_GET['ffpl_skip']));
     72        if (!wp_verify_nonce($nonce, 'ffpl_skip_' . self::$plugin_shortname)) {
     73            return;
     74        }
     75
     76        // Set status to optout - user explicitly skipped
     77        update_site_option(self::$plugin_shortname . '_form_rendered', 'optout');
     78
     79        // Redirect to clean URL (remove the skip param)
     80        wp_safe_redirect(remove_query_arg('ffpl_skip'));
     81        exit;
     82    }
     83
     84    public function handle_optin_page() {
     85        // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- This is page routing, not form processing
     86        $current_page = isset($_GET['page']) ? sanitize_text_field(wp_unslash($_GET['page'])) : '';
     87        $option = get_site_option(self::$plugin_shortname . '_form_rendered');
     88        if ('pending' === $option && $current_page === $this->page) {
     89            update_site_option(self::$plugin_shortname . '_form_rendered', 'rendering');
     90            wp_safe_redirect(admin_url('options-general.php?page=ffpl-opt-in-' . self::$plugin_shortname));
     91            exit;
     92        }
    8493    }
    8594
     
    102111
    103112    public function add_settings_page() {
    104         $option = get_site_option(self::$plugin_shortname . '_form_rendered', 'optout');
    105         if ('pending' === $option) {
    106             update_site_option(self::$plugin_shortname . '_form_rendered', 'rendering');
    107             wp_safe_redirect(admin_url('options-general.php?page=ffpl-opt-in-'.self::$plugin_shortname ));
    108             exit;
    109         }
    110         if (in_array($option, array('rendering', 'optout'))) {
     113        // First-run detection - if option doesn't exist, set to pending
     114        $option = get_site_option(self::$plugin_shortname . '_form_rendered');
     115        if (false === $option) {
     116            update_site_option(self::$plugin_shortname . '_form_rendered', 'pending');
     117            $option = 'pending';
     118        }
     119
     120        // Register the opt-in page if not yet completed
     121        if (in_array($option, array('pending', 'rendering', 'optout'))) {
    111122            add_options_page(
    112123                esc_html($this->translate('Opt In ')) . esc_html( $this->plugin_name), // Page title
     
    126137    public function render_opt_in_page() {
    127138        $user = wp_get_current_user();
    128         update_site_option(self::$plugin_shortname . '_form_rendered', 'optout');
     139        // Keep status as 'rendering' while viewing - only change on actual user action
    129140        ?>
    130141        <div class="fpl-page-wrap" role="main">
     
    178189                            </div>
    179190                            <div class="button-2">
    180                                 <a href="<?php echo esc_url($this->settings_page); ?>"
     191                                <a href="<?php echo esc_url(add_query_arg('ffpl_skip', wp_create_nonce('ffpl_skip_' . self::$plugin_shortname), $this->settings_page)); ?>"
    181192                                   class="button button-secondary btn-skip" name="action" value="skip"
    182193                                   tabindex="2">
     
    244255    public function handle_optin_ajax() {
    245256        // Verify request method
    246         if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
     257        if (!isset($_SERVER['REQUEST_METHOD']) || $_SERVER['REQUEST_METHOD'] !== 'POST') {
    247258            wp_send_json_error(['message' => $this->translate('Invalid request method')]);
    248259            wp_die();
     
    273284        }
    274285
    275         $email = sanitize_email(wp_unslash($_POST['email']));
     286        $email = isset($_POST['email']) ? sanitize_email(wp_unslash($_POST['email'])) : '';
    276287
    277288        $email_handler = new Email(self::$plugin_shortname);
     
    292303    }
    293304
     305    public function maybe_show_setup_notice() {
     306        // Only for users who can manage options
     307        if (!current_user_can('manage_options')) {
     308            return;
     309        }
     310
     311        $screen = get_current_screen();
     312        if (!$screen) {
     313            return;
     314        }
     315
     316        $option = get_site_option(self::$plugin_shortname . '_form_rendered');
     317
     318        // Only show notice if no decision has been made yet (pending or rendering)
     319        // Don't show if optin, optout, or any other status - a decision was made
     320        if (!in_array($option, array('pending', 'rendering'), true)) {
     321            return;
     322        }
     323
     324        // Don't show if user dismissed the notice
     325        if (get_user_meta(get_current_user_id(), self::$plugin_shortname . '_notice_dismissed', true)) {
     326            return;
     327        }
     328
     329        // Show on dashboard, plugins page, tools, options-general, or this plugin's settings page
     330        $page = $screen->base;
     331        $display_on_pages = array(
     332            'dashboard',
     333            'plugins',
     334            'tools',
     335            'options-general',
     336            'settings_page_' . $this->page,
     337        );
     338
     339        if (!in_array($page, $display_on_pages, true)) {
     340            return;
     341        }
     342
     343        $opt_in_url = admin_url('options-general.php?page=ffpl-opt-in-' . self::$plugin_shortname);
     344        ?>
     345        <div class="notice notice-info is-dismissible ffpl-setup-notice" data-shortname="<?php echo esc_attr(self::$plugin_shortname); ?>">
     346            <p>
     347                <strong><?php echo esc_html($this->plugin_name); ?>:</strong>
     348                <?php
     349                printf(
     350                    '%s <a href="%s"><strong>%s</strong></a> %s',
     351                    esc_html($this->translate('You haven\'t visited settings yet.')),
     352                    esc_url($this->settings_page),
     353                    esc_html($this->translate('Please check your settings')),
     354                    esc_html($this->translate('for optimal configuration and opt in for security updates, tips and occasional offers.'))
     355                );
     356                ?>
     357            </p>
     358        </div>
     359        <script>
     360        jQuery(document).ready(function($) {
     361            $('.ffpl-setup-notice').on('click', '.notice-dismiss', function() {
     362                var shortname = $(this).closest('.ffpl-setup-notice').data('shortname');
     363                $.post(ajaxurl, {
     364                    action: 'ffpl_dismiss_notice',
     365                    shortname: shortname,
     366                    nonce: '<?php echo esc_js(wp_create_nonce('ffpl_dismiss_notice')); ?>'
     367                });
     368            });
     369        });
     370        </script>
     371        <?php
     372    }
     373
     374    public function handle_dismiss_notice() {
     375        if (!current_user_can('manage_options')) {
     376            wp_send_json_error(['message' => $this->translate('Unauthorized access')], 403);
     377            wp_die();
     378        }
     379
     380        if (!check_ajax_referer('ffpl_dismiss_notice', 'nonce', false)) {
     381            wp_send_json_error(['message' => $this->translate('Security check failed')], 403);
     382            wp_die();
     383        }
     384
     385        $shortname = isset($_POST['shortname']) ? sanitize_key($_POST['shortname']) : '';
     386        if ($shortname === self::$plugin_shortname) {
     387            update_user_meta(get_current_user_id(), self::$plugin_shortname . '_notice_dismissed', true);
     388            wp_send_json_success();
     389        }
     390
     391        wp_send_json_error();
     392        wp_die();
     393    }
     394
    294395    private function translate($text) {
    295396        // deliberately done like this to stop polygots auto adding to translation files as
  • clean-and-simple-contact-form-by-meg-nicholas/trunk/vendor/alanef/free_plugin_lib/src/languages/free-plugin-lib-de_DE.po

    r3254319 r3429749  
    169169msgstr "Zu viele Versuche. Bitte versuchen Sie es später erneut"
    170170
     171#: Main.php
     172msgid "You haven't visited settings yet."
     173msgstr "Sie haben die Einstellungen noch nicht besucht."
     174
     175#: Main.php
     176msgid "Please check your settings"
     177msgstr "Bitte überprüfen Sie Ihre Einstellungen"
     178
     179#: Main.php
     180msgid "for optimal configuration and opt in for security updates, tips and occasional offers."
     181msgstr "für eine optimale Konfiguration und melden Sie sich für Sicherheitsupdates, Tipps und gelegentliche Angebote an."
     182
    171183#: Classes/Advert.php
    172184msgid "Premium Plugin Advertisement"
  • clean-and-simple-contact-form-by-meg-nicholas/trunk/vendor/alanef/free_plugin_lib/src/languages/free-plugin-lib-es_ES.po

    r3254319 r3429749  
    169169msgstr "Demasiados intentos. Por favor, inténtalo de nuevo más tarde"
    170170
     171#: Main.php
     172msgid "You haven't visited settings yet."
     173msgstr "Aún no has visitado la configuración."
     174
     175#: Main.php
     176msgid "Please check your settings"
     177msgstr "Por favor, revisa tu configuración"
     178
     179#: Main.php
     180msgid "for optimal configuration and opt in for security updates, tips and occasional offers."
     181msgstr "para una configuración óptima y suscríbete para recibir actualizaciones de seguridad, consejos y ofertas ocasionales."
     182
    171183#: Classes/Advert.php
    172184msgid "Premium Plugin Advertisement"
  • clean-and-simple-contact-form-by-meg-nicholas/trunk/vendor/alanef/free_plugin_lib/src/languages/free-plugin-lib-fr_FR.po

    r3254319 r3429749  
    169169msgstr "Trop de tentatives. Veuillez réessayer plus tard."
    170170
     171#: Main.php
     172msgid "You haven't visited settings yet."
     173msgstr "Vous n'avez pas encore visité les paramètres."
     174
     175#: Main.php
     176msgid "Please check your settings"
     177msgstr "Veuillez vérifier vos paramètres"
     178
     179#: Main.php
     180msgid "for optimal configuration and opt in for security updates, tips and occasional offers."
     181msgstr "pour une configuration optimale et inscrivez-vous aux mises à jour de sécurité, conseils et offres occasionnelles."
     182
    171183#: Classes/Advert.php
    172184msgid "Premium Plugin Advertisement"
  • clean-and-simple-contact-form-by-meg-nicholas/trunk/vendor/alanef/free_plugin_lib/src/languages/free-plugin-lib-it_IT.po

    r3254319 r3429749  
    169169msgstr "Troppi tentativi. Riprova più tardi."
    170170
     171#: Main.php
     172msgid "You haven't visited settings yet."
     173msgstr "Non hai ancora visitato le impostazioni."
     174
     175#: Main.php
     176msgid "Please check your settings"
     177msgstr "Controlla le tue impostazioni"
     178
     179#: Main.php
     180msgid "for optimal configuration and opt in for security updates, tips and occasional offers."
     181msgstr "per una configurazione ottimale e iscriviti per ricevere aggiornamenti di sicurezza, consigli e offerte occasionali."
     182
    171183#: Classes/Advert.php
    172184msgid "Premium Plugin Advertisement"
  • clean-and-simple-contact-form-by-meg-nicholas/trunk/vendor/alanef/free_plugin_lib/src/languages/free-plugin-lib-ja.po

    r3254319 r3429749  
    169169msgstr "試行回数が上限を超えました。しばらく後で再試行してください"
    170170
     171#: Main.php
     172msgid "You haven't visited settings yet."
     173msgstr "まだ設定ページを訪問していません。"
     174
     175#: Main.php
     176msgid "Please check your settings"
     177msgstr "設定を確認してください"
     178
     179#: Main.php
     180msgid "for optimal configuration and opt in for security updates, tips and occasional offers."
     181msgstr "最適な設定のために、セキュリティアップデート、ヒント、特別オファーの受信を登録してください。"
     182
    171183#: Classes/Advert.php
    172184msgid "Premium Plugin Advertisement"
  • clean-and-simple-contact-form-by-meg-nicholas/trunk/vendor/alanef/free_plugin_lib/src/languages/free-plugin-lib-nl_NL.po

    r3254319 r3429749  
    169169msgstr "Te veel pogingen. Probeer het later opnieuw."
    170170
     171#: Main.php
     172msgid "You haven't visited settings yet."
     173msgstr "Je hebt de instellingen nog niet bezocht."
     174
     175#: Main.php
     176msgid "Please check your settings"
     177msgstr "Controleer je instellingen"
     178
     179#: Main.php
     180msgid "for optimal configuration and opt in for security updates, tips and occasional offers."
     181msgstr "voor een optimale configuratie en meld je aan voor beveiligingsupdates, tips en incidentele aanbiedingen."
     182
    171183#: Classes/Advert.php
    172184msgid "Premium Plugin Advertisement"
  • clean-and-simple-contact-form-by-meg-nicholas/trunk/vendor/alanef/free_plugin_lib/src/languages/free-plugin-lib-pl_PL.po

    r3254319 r3429749  
    169169msgstr "Zbyt wiele prób. Spróbuj ponownie później"
    170170
     171#: Main.php
     172msgid "You haven't visited settings yet."
     173msgstr "Nie odwiedziłeś jeszcze ustawień."
     174
     175#: Main.php
     176msgid "Please check your settings"
     177msgstr "Sprawdź swoje ustawienia"
     178
     179#: Main.php
     180msgid "for optimal configuration and opt in for security updates, tips and occasional offers."
     181msgstr "dla optymalnej konfiguracji i zapisz się na aktualizacje bezpieczeństwa, porady i okazjonalne oferty."
     182
    171183#: Classes/Advert.php
    172184msgid "Premium Plugin Advertisement"
  • clean-and-simple-contact-form-by-meg-nicholas/trunk/vendor/alanef/free_plugin_lib/src/languages/free-plugin-lib-pt_BR.po

    r3254319 r3429749  
    169169msgstr "Muitas tentativas. Tente novamente mais tarde."
    170170
     171#: Main.php
     172msgid "You haven't visited settings yet."
     173msgstr "Você ainda não visitou as configurações."
     174
     175#: Main.php
     176msgid "Please check your settings"
     177msgstr "Por favor, verifique suas configurações"
     178
     179#: Main.php
     180msgid "for optimal configuration and opt in for security updates, tips and occasional offers."
     181msgstr "para uma configuração ideal e inscreva-se para receber atualizações de segurança, dicas e ofertas ocasionais."
     182
    171183#: Classes/Advert.php
    172184msgid "Premium Plugin Advertisement"
  • clean-and-simple-contact-form-by-meg-nicholas/trunk/vendor/alanef/free_plugin_lib/src/languages/free-plugin-lib-pt_PT.po

    r3254319 r3429749  
    169169msgstr "Demasiadas tentativas. Tente novamente mais tarde."
    170170
     171#: Main.php
     172msgid "You haven't visited settings yet."
     173msgstr "Ainda não visitou as definições."
     174
     175#: Main.php
     176msgid "Please check your settings"
     177msgstr "Por favor, verifique as suas definições"
     178
     179#: Main.php
     180msgid "for optimal configuration and opt in for security updates, tips and occasional offers."
     181msgstr "para uma configuração ideal e inscreva-se para receber atualizações de segurança, dicas e ofertas ocasionais."
     182
    171183#: Classes/Advert.php
    172184msgid "Premium Plugin Advertisement"
  • clean-and-simple-contact-form-by-meg-nicholas/trunk/vendor/alanef/free_plugin_lib/src/languages/free-plugin-lib-tr_TR.po

    r3254319 r3429749  
    169169msgstr "Çok fazla deneme yapıldı. Lütfen daha sonra tekrar deneyin."
    170170
     171#: Main.php
     172msgid "You haven't visited settings yet."
     173msgstr "Henüz ayarları ziyaret etmediniz."
     174
     175#: Main.php
     176msgid "Please check your settings"
     177msgstr "Lütfen ayarlarınızı kontrol edin"
     178
     179#: Main.php
     180msgid "for optimal configuration and opt in for security updates, tips and occasional offers."
     181msgstr "en iyi yapılandırma için ve güvenlik güncellemeleri, ipuçları ve ara sıra teklifler almak için kaydolun."
     182
    171183#: Classes/Advert.php
    172184msgid "Premium Plugin Advertisement"
  • clean-and-simple-contact-form-by-meg-nicholas/trunk/vendor/alanef/free_plugin_lib/src/languages/free-plugin-lib.pot

    r3254319 r3429749  
    167167msgstr ""
    168168
     169#: Main.php
     170msgid "You haven't visited settings yet."
     171msgstr ""
     172
     173#: Main.php
     174msgid "Please check your settings"
     175msgstr ""
     176
     177#: Main.php
     178msgid "for optimal configuration and opt in for security updates, tips and occasional offers."
     179msgstr ""
     180
    169181#: Classes/Advert.php
    170182msgid "Premium Plugin Advertisement"
  • clean-and-simple-contact-form-by-meg-nicholas/trunk/vendor/composer/autoload_static.php

    r3339262 r3429749  
    88{
    99    public static $prefixLengthsPsr4 = array (
    10         'F' => 
     10        'F' =>
    1111        array (
    1212            'Fullworks_Free_Plugin_Lib\\' => 26,
     
    1515
    1616    public static $prefixDirsPsr4 = array (
    17         'Fullworks_Free_Plugin_Lib\\' => 
     17        'Fullworks_Free_Plugin_Lib\\' =>
    1818        array (
    1919            0 => __DIR__ . '/..' . '/alanef/free_plugin_lib/src',
     
    2222
    2323    public static $prefixesPsr0 = array (
    24         'C' => 
     24        'C' =>
    2525        array (
    26             'Composer\\Installers\\' => 
     26            'Composer\\Installers\\' =>
    2727            array (
    2828                0 => __DIR__ . '/..' . '/composer/installers/src',
  • clean-and-simple-contact-form-by-meg-nicholas/trunk/vendor/composer/installed.json

    r3254319 r3429749  
    33        {
    44            "name": "alanef/free_plugin_lib",
    5             "version": "v1.0.1",
    6             "version_normalized": "1.0.1.0",
     5            "version": "1.2.2",
     6            "version_normalized": "1.2.2.0",
    77            "source": {
    88                "type": "git",
    99                "url": "https://github.com/alanef/free_plugin_lib.git",
    10                 "reference": "ed52c33c73999a1fe1ee5a1b00581b9462111ac8"
     10                "reference": "11f06087774e7d533199809be898117e3ed1ef2f"
    1111            },
    1212            "dist": {
    1313                "type": "zip",
    14                 "url": "https://api.github.com/repos/alanef/free_plugin_lib/zipball/ed52c33c73999a1fe1ee5a1b00581b9462111ac8",
    15                 "reference": "ed52c33c73999a1fe1ee5a1b00581b9462111ac8",
     14                "url": "https://api.github.com/repos/alanef/free_plugin_lib/zipball/11f06087774e7d533199809be898117e3ed1ef2f",
     15                "reference": "11f06087774e7d533199809be898117e3ed1ef2f",
    1616                "shasum": ""
    1717            },
     
    2525                "yoast/wp-test-utils": "^1.2"
    2626            },
    27             "time": "2025-02-18T15:16:14+00:00",
     27            "time": "2025-12-21T18:38:49+00:00",
    2828            "type": "library",
    2929            "installation-source": "dist",
     
    4646            "support": {
    4747                "issues": "https://github.com/alanef/free_plugin_lib/issues",
    48                 "source": "https://github.com/alanef/free_plugin_lib/tree/v1.0.1"
     48                "source": "https://github.com/alanef/free_plugin_lib/tree/v1.2.2"
    4949            },
    5050            "install-path": "../alanef/free_plugin_lib"
  • clean-and-simple-contact-form-by-meg-nicholas/trunk/vendor/composer/installed.php

    r3339262 r3429749  
    22    'root' => array(
    33        'name' => 'fullworks/clean-and-simple-contact-form',
    4         'pretty_version' => 'v4.11',
    5         'version' => '4.11.0.0',
    6         'reference' => '801b967317613364d9e34394960f064495cb2283',
     4        'pretty_version' => '4.12',
     5        'version' => '4.12.0.0',
     6        'reference' => 'e6f8da67924ce3947db78743e4f95175c6bf98af',
    77        'type' => 'wordpress-plugin',
    88        'install_path' => __DIR__ . '/../../',
     
    1212    'versions' => array(
    1313        'alanef/free_plugin_lib' => array(
    14             'pretty_version' => 'v1.0.1',
    15             'version' => '1.0.1.0',
    16             'reference' => 'ed52c33c73999a1fe1ee5a1b00581b9462111ac8',
     14            'pretty_version' => '1.2.2',
     15            'version' => '1.2.2.0',
     16            'reference' => '11f06087774e7d533199809be898117e3ed1ef2f',
    1717            'type' => 'library',
    1818            'install_path' => __DIR__ . '/../alanef/free_plugin_lib',
     
    3030        ),
    3131        'fullworks/clean-and-simple-contact-form' => array(
    32             'pretty_version' => 'v4.11',
    33             'version' => '4.11.0.0',
    34             'reference' => '801b967317613364d9e34394960f064495cb2283',
     32            'pretty_version' => '4.12',
     33            'version' => '4.12.0.0',
     34            'reference' => 'e6f8da67924ce3947db78743e4f95175c6bf98af',
    3535            'type' => 'wordpress-plugin',
    3636            'install_path' => __DIR__ . '/../../',
  • clean-and-simple-contact-form-by-meg-nicholas/trunk/views/contact-form.view.php

    r3142234 r3429749  
     1<?php if ( ! defined( 'ABSPATH' ) ) exit; ?>
     2<?php
     3// Get CSS classes for current framework
     4$cscf_css = cscf_CSS_Classes::get_all_classes();
     5$cscf_form_group_class = $cscf_css['form_group'];
     6$cscf_form_group_error_class = $cscf_css['form_group_error'];
     7$cscf_input_class = $cscf_css['input'];
     8$cscf_textarea_class = $cscf_css['textarea'];
     9$cscf_button_class = $cscf_css['button'];
     10$cscf_help_text_class = $cscf_css['help_text'];
     11$cscf_input_group_class = $cscf_css['input_group'];
     12$cscf_input_addon_class = $cscf_css['input_addon'];
     13$cscf_text_error_class = $cscf_css['text_error'];
     14?>
    115<div id="cscf" class="cscfBlock">
    216    <div class="cscfMessageSent" style="display:none;">
     
    1428
    1529            <?php if ( isset( $contact->Errors['recaptcha'] ) ) { ?>
    16                 <div class="control-group form-group">
    17                     <p class="text-error"><?php echo esc_html( $contact->Errors['recaptcha'] ); ?></p>
     30                <div class="<?php echo esc_attr( $cscf_form_group_class ); ?>">
     31                    <p class="<?php echo esc_attr( $cscf_text_error_class ); ?>"><?php echo esc_html( $contact->Errors['recaptcha'] ); ?></p>
    1832                </div>
    1933            <?php } ?>
    2034
    2135            <!-- name -->
    22             <div class="control-group form-group<?php if ( isset( $contact->Errors['name'] ) ) {
    23                 echo ' error has-error';
     36            <div class="<?php echo esc_attr( $cscf_form_group_class ); ?><?php if ( isset( $contact->Errors['name'] ) ) {
     37                echo ' ' . esc_attr( $cscf_form_group_error_class );
    2438            } ?>">
    2539                <label for="cscf_name"><?php esc_html_e( 'Name:', 'clean-and-simple-contact-form-by-meg-nicholas' ); ?></label>
    2640
    2741
    28                 <div class="<?php echo ( true === cscf_PluginSettings::InputIcons() ) ? 'input-group' : ''; ?>">
    29                     <?php if ( cscf_PluginSettings::InputIcons() == true ) { ?>
    30                         <span class="input-group-addon"><span class="glyphicon glyphicon-user"></span></span>
     42                <div class="<?php echo ( true === cscf_PluginSettings::InputIcons() && ! empty( $cscf_input_group_class ) ) ? esc_attr( $cscf_input_group_class ) : ''; ?>">
     43                    <?php if ( cscf_PluginSettings::InputIcons() == true && ! empty( $cscf_input_addon_class ) ) { ?>
     44                        <span class="<?php echo esc_attr( $cscf_input_addon_class ); ?>"><span class="glyphicon glyphicon-user"></span></span>
    3145                    <?php } ?>
    32                     <input class="form-control input-xlarge"
     46                    <input class="<?php echo esc_attr( $cscf_input_class ); ?>"
    3347                           data-rule-required="true"
    3448                           data-msg-required="<?php esc_html_e( 'Please give your name.', 'clean-and-simple-contact-form-by-meg-nicholas' ); ?>"
     
    3852                    />
    3953                </div>
    40                 <span for="cscf_name" class="help-inline help-block error"
     54                <span for="cscf_name" class="<?php echo esc_attr( $cscf_help_text_class ); ?>"
    4155                      style="display:<?php echo isset( $contact->Errors['name'] ) ? 'block' : 'none'; ?>;">
    4256
     
    4963
    5064            <!--email address-->
    51             <div class="control-group form-group<?php if ( isset( $contact->Errors['email'] ) ) {
    52                 echo ' error has-error';
     65            <div class="<?php echo esc_attr( $cscf_form_group_class ); ?><?php if ( isset( $contact->Errors['email'] ) ) {
     66                echo ' ' . esc_attr( $cscf_form_group_error_class );
    5367            } ?>">
    5468                <label for="cscf_email"><?php esc_html_e( 'Email Address:', 'clean-and-simple-contact-form-by-meg-nicholas' ); ?></label>
    5569
    56                 <div class="<?php echo ( true === cscf_PluginSettings::InputIcons() ) ? 'input-group' : ''; ?>">
    57                     <?php if ( cscf_PluginSettings::InputIcons() == true ) { ?>
    58                         <span class="input-group-addon"><span class="glyphicon glyphicon-envelope"></span></span>
     70                <div class="<?php echo ( true === cscf_PluginSettings::InputIcons() && ! empty( $cscf_input_group_class ) ) ? esc_attr( $cscf_input_group_class ) : ''; ?>">
     71                    <?php if ( cscf_PluginSettings::InputIcons() == true && ! empty( $cscf_input_addon_class ) ) { ?>
     72                        <span class="<?php echo esc_attr( $cscf_input_addon_class ); ?>"><span class="glyphicon glyphicon-envelope"></span></span>
    5973                    <?php } ?>
    60                     <input class="form-control input-xlarge"
     74                    <input class="<?php echo esc_attr( $cscf_input_class ); ?>"
    6175                           data-rule-required="true"
    6276                           data-rule-email="true"
     
    6882                    />
    6983                </div>
    70                 <span for="cscf_email" class="help-inline help-block error"
     84                <span for="cscf_email" class="<?php echo esc_attr( $cscf_help_text_class ); ?>"
    7185                      style="display:<?php echo isset( $contact->Errors['email'] ) ? 'block' : 'none'; ?>;">
    7286                    <?php if ( isset( $contact->Errors['email'] ) ) {
     
    7892            <?php if ( $confirmEmail ) { ?>
    7993                <!--confirm email address -->
    80                 <div class="control-group form-group<?php if ( isset( $contact->Errors['confirm-email'] ) ) {
    81                     echo ' error has-error';
     94                <div class="<?php echo esc_attr( $cscf_form_group_class ); ?><?php if ( isset( $contact->Errors['confirm-email'] ) ) {
     95                    echo ' ' . esc_attr( $cscf_form_group_error_class );
    8296                } ?>">
    8397                    <label for="cscf_confirm-email"><?php esc_html_e( 'Confirm Email Address:', 'clean-and-simple-contact-form-by-meg-nicholas' ); ?></label>
    84                     <div class="<?php echo ( true === cscf_PluginSettings::InputIcons() ) ? 'input-group' : ''; ?>">
    85                         <?php if ( cscf_PluginSettings::InputIcons() == true ) { ?>
    86                             <span class="input-group-addon"><span class="glyphicon glyphicon-envelope"></span></span>
    87                         <?php } ?>
    88                         <input class="form-control input-xlarge"
     98                    <div class="<?php echo ( true === cscf_PluginSettings::InputIcons() && ! empty( $cscf_input_group_class ) ) ? esc_attr( $cscf_input_group_class ) : ''; ?>">
     99                        <?php if ( cscf_PluginSettings::InputIcons() == true && ! empty( $cscf_input_addon_class ) ) { ?>
     100                            <span class="<?php echo esc_attr( $cscf_input_addon_class ); ?>"><span class="glyphicon glyphicon-envelope"></span></span>
     101                        <?php } ?>
     102                        <input class="<?php echo esc_attr( $cscf_input_class ); ?>"
    89103                               data-rule-required="true"
    90104                               data-rule-email="true"
     
    98112                        />
    99113                    </div>
    100                     <span for="cscf_confirm-email" class="help-inline help-block error"
     114                    <span for="cscf_confirm-email" class="<?php echo esc_attr( $cscf_help_text_class ); ?>"
    101115                          style="display:<?php echo isset( $contact->Errors['confirm-email'] ) ? 'block' : 'none'; ?>;">
    102116                    <?php if ( isset( $contact->Errors['confirm-email'] ) ) {
     
    109123            <?php if ( cscf_PluginSettings::PhoneNumber() ) { ?>
    110124                <!-- telephone number -->
    111                 <div class="control-group form-group<?php if ( isset( $contact->Errors['phone-number'] ) ) {
    112                     echo ' error has-error';
     125                <div class="<?php echo esc_attr( $cscf_form_group_class ); ?><?php if ( isset( $contact->Errors['phone-number'] ) ) {
     126                    echo ' ' . esc_attr( $cscf_form_group_error_class );
    113127                } ?>">
    114128                    <label for="cscf_phone-number"><?php esc_html_e( 'Phone Number:', 'clean-and-simple-contact-form-by-meg-nicholas' ); ?></label>
    115                     <div class="<?php echo ( true === cscf_PluginSettings::InputIcons() ) ? 'input-group' : ''; ?>">
    116                         <?php if ( cscf_PluginSettings::InputIcons() == true ) { ?>
    117                             <span class="input-group-addon"><span class="glyphicon glyphicon-phone-alt"></span></span>
    118                         <?php } ?>
    119                         <input class="form-control input-xlarge"
     129                    <div class="<?php echo ( true === cscf_PluginSettings::InputIcons() && ! empty( $cscf_input_group_class ) ) ? esc_attr( $cscf_input_group_class ) : ''; ?>">
     130                        <?php if ( cscf_PluginSettings::InputIcons() == true && ! empty( $cscf_input_addon_class ) ) { ?>
     131                            <span class="<?php echo esc_attr( $cscf_input_addon_class ); ?>"><span class="glyphicon glyphicon-phone-alt"></span></span>
     132                        <?php } ?>
     133                        <input class="<?php echo esc_attr( $cscf_input_class ); ?>"
    120134                               data-rule-required="<?php echo ( true === cscf_PluginSettings::PhoneNumberMandatory() ) ? 'true' : 'false'; ?>"
    121135                               data-msg-required="<?php esc_html_e( 'Please give your phone number.', 'clean-and-simple-contact-form-by-meg-nicholas' ); ?>"
     
    125139                        />
    126140                    </div>
    127                     <span for="cscf_phone-number" class="help-inline help-block error"
     141                    <span for="cscf_phone-number" class="<?php echo esc_attr( $cscf_help_text_class ); ?>"
    128142                          style="display:<?php echo isset( $contact->Errors['phone-number'] ) ? 'block' : 'none'; ?>;">
    129143                    <?php if ( isset( $contact->Errors['phone-number'] ) ) {
     
    136150
    137151            <!-- message -->
    138             <div class="control-group form-group<?php if ( isset( $contact->Errors['message'] ) ) {
    139                 echo ' error has-error';
     152            <div class="<?php echo esc_attr( $cscf_form_group_class ); ?><?php if ( isset( $contact->Errors['message'] ) ) {
     153                echo ' ' . esc_attr( $cscf_form_group_error_class );
    140154            } ?>">
    141155                <label for="cscf_message"><?php esc_html_e( 'Message:', 'clean-and-simple-contact-form-by-meg-nicholas' ); ?></label>
    142                 <div class="<?php echo ( true === cscf_PluginSettings::InputIcons() ) ? 'input-group' : ''; ?>">
    143                     <?php if ( cscf_PluginSettings::InputIcons() == true ) { ?>
    144                         <span class="input-group-addon"><span class="glyphicon glyphicon-comment"></span></span>
     156                <div class="<?php echo ( true === cscf_PluginSettings::InputIcons() && ! empty( $cscf_input_group_class ) ) ? esc_attr( $cscf_input_group_class ) : ''; ?>">
     157                    <?php if ( cscf_PluginSettings::InputIcons() == true && ! empty( $cscf_input_addon_class ) ) { ?>
     158                        <span class="<?php echo esc_attr( $cscf_input_addon_class ); ?>"><span class="glyphicon glyphicon-comment"></span></span>
    145159                    <?php } ?>
    146                     <textarea class="form-control input-xlarge"
     160                    <textarea class="<?php echo esc_attr( $cscf_textarea_class ); ?>"
    147161                              data-rule-required="true"
    148162                              data-msg-required="<?php esc_html_e( 'Please give a message.', 'clean-and-simple-contact-form-by-meg-nicholas' ); ?>"
     
    151165                </div>
    152166
    153                 <span for="cscf_message" class="help-inline help-block error"
     167                <span for="cscf_message" class="<?php echo esc_attr( $cscf_help_text_class ); ?>"
    154168                      style="display:<?php echo isset( $contact->Errors['message'] ) ? 'block' : 'none'; ?>;">
    155169                    <?php if ( isset( $contact->Errors['message'] ) ) {
     
    161175            <?php if ( cscf_PluginSettings::EmailToSender() ) { ?>
    162176                <!-- email to sender -->
    163                 <div class="control-group form-group<?php if ( isset( $contact->Errors['email-sender'] ) ) {
    164                     echo ' error has-error';
     177                <div class="<?php echo esc_attr( $cscf_form_group_class ); ?><?php if ( isset( $contact->Errors['email-sender'] ) ) {
     178                    echo ' ' . esc_attr( $cscf_form_group_error_class );
    165179                } ?>">
    166180                    <label for="cscf_email-sender"><?php esc_html_e( 'Send me a copy:', 'clean-and-simple-contact-form-by-meg-nicholas' ); ?></label>
    167                     <div class="<?php echo ( true === cscf_PluginSettings::InputIcons() ) ? "input-group" : ""; ?>">
    168                         <?php if ( cscf_PluginSettings::InputIcons() == true ) { ?>
    169                             <span class="input-group-addon"><span class="glyphicon glyphicon-comment"></span></span>
     181                    <div class="<?php echo ( true === cscf_PluginSettings::InputIcons() && ! empty( $cscf_input_group_class ) ) ? esc_attr( $cscf_input_group_class ) : ''; ?>">
     182                        <?php if ( cscf_PluginSettings::InputIcons() == true && ! empty( $cscf_input_addon_class ) ) { ?>
     183                            <span class="<?php echo esc_attr( $cscf_input_addon_class ); ?>"><span class="glyphicon glyphicon-comment"></span></span>
    170184                        <?php } ?>
    171185                        <input <?php echo ( true == $contact->EmailToSender ) ? 'checked' : ''; ?> type="checkbox"
     
    173187                                                                                                   name="cscf[email-sender]">
    174188                    </div>
    175                     <span for="cscf_email-sender" class="help-inline help-block error"
     189                    <span for="cscf_email-sender" class="<?php echo esc_attr( $cscf_help_text_class ); ?>"
    176190                          style="display:<?php echo isset( $contact->Errors['email-sender'] ) ? 'block' : 'none'; ?>;">
    177191                        <?php if ( isset( $contact->Errors['email-sender'] ) ) {
     
    186200            <?php if ( cscf_PluginSettings::ContactConsent() ) { ?>
    187201                <!-- contact consent -->
    188                 <div class="control-group form-group<?php if ( isset( $contact->Errors['contact-consent'] ) ) {
    189                     echo ' error has-error';
     202                <div class="<?php echo esc_attr( $cscf_form_group_class ); ?><?php if ( isset( $contact->Errors['contact-consent'] ) ) {
     203                    echo ' ' . esc_attr( $cscf_form_group_error_class );
    190204                } ?>">
    191205                    <label for="cscf_contact-consent"><?php echo esc_html( cscf_PluginSettings::ContactConsentMsg() ); ?>:</label>
    192                     <div class="<?php echo ( cscf_PluginSettings::InputIcons() ) ? "input-group" : ""; ?>">
    193                         <?php if ( cscf_PluginSettings::InputIcons() == true ) { ?>
    194                             <span class="input-group-addon"><span class="glyphicon glyphicon-comment"></span></span>
    195                         <?php } ?>
    196                         <input class="form-control input-xlarge"
     206                    <div class="<?php echo ( cscf_PluginSettings::InputIcons() && ! empty( $cscf_input_group_class ) ) ? esc_attr( $cscf_input_group_class ) : ''; ?>">
     207                        <?php if ( cscf_PluginSettings::InputIcons() == true && ! empty( $cscf_input_addon_class ) ) { ?>
     208                            <span class="<?php echo esc_attr( $cscf_input_addon_class ); ?>"><span class="glyphicon glyphicon-comment"></span></span>
     209                        <?php } ?>
     210                        <input class="<?php echo esc_attr( $cscf_input_class ); ?>"
    197211                               data-rule-required="true"
    198212                               data-msg-required="<?php esc_html_e( 'Please give your consent.', 'clean-and-simple-contact-form-by-meg-nicholas' ); ?>"
     
    201215                               name="cscf[contact-consent]">
    202216                    </div>
    203                     <span for="cscf[contact-consent]" class="help-inline help-block error"
     217                    <span for="cscf[contact-consent]" class="<?php echo esc_attr( $cscf_help_text_class ); ?>"
    204218                          style="display:<?php echo isset( $contact->Errors['contact-consent'] ) ? 'block' : 'none'; ?>;">
    205219                        <?php if ( isset( $contact->Errors['contact-consent'] ) ) {
     
    213227            <?php if ( $contact->RecaptchaPublicKey <> '' && $contact->RecaptchaPrivateKey <> '' ) { ?>
    214228
    215                 <div class="control-group form-group<?php
     229                <div class="<?php echo esc_attr( $cscf_form_group_class ); ?><?php
    216230                if ( isset( $contact->Errors['recaptcha'] ) ) {
    217                     echo ' error has-error';
     231                    echo ' ' . esc_attr( $cscf_form_group_error_class );
    218232                } ?>">
    219233                    <div id="recaptcha_div">
     
    223237
    224238                        <div for="cscf_recaptcha"
    225                              class="help-block has-error error"><?php if ( isset( $contact->Errors['recaptcha'] ) ) {
     239                             class="<?php echo esc_attr( $cscf_help_text_class ); ?>"><?php if ( isset( $contact->Errors['recaptcha'] ) ) {
    226240                                echo esc_html( $contact->Errors['recaptcha'] );
    227241                            } ?></div>
     
    254268                </div>
    255269            <?php } ?>
    256             <input type="submit" id="cscf_SubmitButton" class="btn btn-default"
     270            <input type="submit" id="cscf_SubmitButton" class="<?php echo esc_attr( $cscf_button_class ); ?>"
    257271                   value="<?php esc_html_e( 'Send Message', 'clean-and-simple-contact-form-by-meg-nicholas' ); ?>"/>
    258272        </form>
  • clean-and-simple-contact-form-by-meg-nicholas/trunk/views/message-not-sent.view.php

    r3142234 r3429749  
     1<?php if ( ! defined( 'ABSPATH' ) ) exit; ?>
    12<p>
    23    <?php esc_html_e('Sorry, there has been a problem and your message was not sent.','clean-and-simple-contact-form-by-meg-nicholas') ?></p>
  • clean-and-simple-contact-form-by-meg-nicholas/trunk/views/message-sent.view.php

    r2551686 r3429749  
     1<?php if ( ! defined( 'ABSPATH' ) ) exit; ?>
    12<h3><?php echo esc_html($heading); ?></h3>
    23<p><?php echo esc_html($message); ?> </p>
Note: See TracChangeset for help on using the changeset viewer.