convertkit
/
includes
/
integrations
/
contactform7
/
class-convertkit-contactform7-admin-section.php
class-convertkit-contactform7-admin-section.php in Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages 3.4.5, at includes/integrations/contactform7/class-convertkit-contactform7-admin-section.php
| 1 | <?php |
| 2 | /** |
| 3 | * ConvertKit Contact Form 7 Admin Settings class. |
| 4 | * |
| 5 | * @package ConvertKit |
| 6 | * @author ConvertKit |
| 7 | */ |
| 8 | |
| 9 | /** |
| 10 | * Registers Contact Form 7 Settings that can be edited at Settings > Kit > Contact Form 7. |
| 11 | * |
| 12 | * @package ConvertKit |
| 13 | * @author ConvertKit |
| 14 | */ |
| 15 | class ConvertKit_ContactForm7_Admin_Section extends ConvertKit_Admin_Section_Base { |
| 16 | |
| 17 | /** |
| 18 | * Constructor |
| 19 | */ |
| 20 | public function __construct() { |
| 21 | |
| 22 | // Define the class that reads/writes settings. |
| 23 | $this->settings = new ConvertKit_ContactForm7_Settings(); |
| 24 | |
| 25 | // Define the settings key. |
| 26 | $this->settings_key = $this->settings::SETTINGS_NAME; |
| 27 | |
| 28 | // Define the programmatic name, Title and Tab Text. |
| 29 | $this->name = 'contactform7'; |
| 30 | $this->title = __( 'Contact Form 7 Integration Settings', 'convertkit' ); |
| 31 | $this->tab_text = __( 'Contact Form 7', 'convertkit' ); |
| 32 | |
| 33 | // Define settings sections. |
| 34 | $this->settings_sections = array( |
| 35 | 'general' => array( |
| 36 | 'title' => $this->title, |
| 37 | 'callback' => array( $this, 'print_section_info' ), |
| 38 | 'wrap' => false, |
| 39 | ), |
| 40 | ); |
| 41 | |
| 42 | parent::__construct(); |
| 43 | |
| 44 | } |
| 45 | |
| 46 | /** |
| 47 | * Register fields for this section |
| 48 | */ |
| 49 | public function register_fields() { |
| 50 | |
| 51 | // No fields are registered, because they are output in a WP_List_Table |
| 52 | // in this class' render() function. |
| 53 | // This function is deliberately blank. |
| 54 | } |
| 55 | |
| 56 | /** |
| 57 | * Prints help info for this section. |
| 58 | */ |
| 59 | public function print_section_info() { |
| 60 | |
| 61 | ?> |
| 62 | <p> |
| 63 | <?php |
| 64 | esc_html_e( 'Kit seamlessly integrates with Contact Form 7 to let you add subscribers using Contact Form 7 forms.', 'convertkit' ); |
| 65 | ?> |
| 66 | </p> |
| 67 | <p> |
| 68 | <?php |
| 69 | printf( |
| 70 | '%s <code>text*</code> %s <code>your-name</code> %s <code>email*</code> %s <code>your-email</code>%s', |
| 71 | esc_html__( 'The Contact Form 7 form must have a', 'convertkit' ), |
| 72 | esc_html__( 'field named', 'convertkit' ), |
| 73 | esc_html__( 'and an', 'convertkit' ), |
| 74 | esc_html__( 'field named', 'convertkit' ), |
| 75 | esc_html__( '. These fields will be sent to Kit for the subscription.', 'convertkit' ) |
| 76 | ); |
| 77 | ?> |
| 78 | </p> |
| 79 | <p> |
| 80 | <?php esc_html_e( 'Each Contact Form 7 Form has the following Kit options:', 'convertkit' ); ?> |
| 81 | <br /> |
| 82 | <code><?php esc_html_e( 'Do not subscribe', 'convertkit' ); ?></code>: <?php esc_html_e( 'Do not subscribe the email address to Kit', 'convertkit' ); ?> |
| 83 | <br /> |
| 84 | <code><?php esc_html_e( 'Subscribe', 'convertkit' ); ?></code>: <?php esc_html_e( 'Subscribes the email address to Kit', 'convertkit' ); ?> |
| 85 | <br /> |
| 86 | <code><?php esc_html_e( 'Form', 'convertkit' ); ?></code>: <?php esc_html_e( 'Subscribes the email address to Kit, and adds the subscriber to the Kit form', 'convertkit' ); ?> |
| 87 | <br /> |
| 88 | <code><?php esc_html_e( 'Tag', 'convertkit' ); ?></code>: <?php esc_html_e( 'Subscribes the email address to Kit, tagging the subscriber', 'convertkit' ); ?> |
| 89 | <br /> |
| 90 | <code><?php esc_html_e( 'Sequence', 'convertkit' ); ?></code>: <?php esc_html_e( 'Subscribes the email address to Kit, and adds the subscriber to the Kit sequence', 'convertkit' ); ?> |
| 91 | </p> |
| 92 | <?php |
| 93 | |
| 94 | } |
| 95 | |
| 96 | /** |
| 97 | * Returns the URL for the ConvertKit documentation for this setting section. |
| 98 | * |
| 99 | * @since 2.0.8 |
| 100 | * |
| 101 | * @return string Documentation URL. |
| 102 | */ |
| 103 | public function documentation_url() { |
| 104 | |
| 105 | return 'https://help.kit.com/en/articles/2502591-how-to-set-up-the-kit-plugin-on-your-wordpress-website'; |
| 106 | |
| 107 | } |
| 108 | |
| 109 | /** |
| 110 | * Outputs the section as a WP_List_Table of Contact Form 7 Forms, with options to choose |
| 111 | * a ConvertKit Form mapping for each. |
| 112 | * |
| 113 | * @since 1.9.6 |
| 114 | */ |
| 115 | public function render() { |
| 116 | |
| 117 | // Render opening container. |
| 118 | $this->render_container_start(); |
| 119 | |
| 120 | do_settings_sections( $this->settings_key ); |
| 121 | |
| 122 | // Get Contact Form 7 Forms. |
| 123 | $cf7_forms = $this->get_cf7_forms(); |
| 124 | |
| 125 | // Bail with an error if no Contact Form 7 Forms exist. |
| 126 | if ( ! $cf7_forms ) { |
| 127 | $this->output_error( __( 'No Contact Form 7 Forms exist in the Contact Form 7 Plugin.', 'convertkit' ) ); |
| 128 | $this->render_container_end(); |
| 129 | return; |
| 130 | } |
| 131 | |
| 132 | // Warn the user if any Contact Form 7 Form subscribes to Kit, and Contact Form 7 |
| 133 | // has no spam protection enabled. |
| 134 | $this->maybe_output_spam_protection_warning( $cf7_forms ); |
| 135 | |
| 136 | // Get Creator Network Recommendations script. |
| 137 | $creator_network_recommendations = new ConvertKit_Resource_Creator_Network_Recommendations( 'contact_form_7' ); |
| 138 | $creator_network_recommendations_enabled = $creator_network_recommendations->enabled(); |
| 139 | |
| 140 | // Setup WP_List_Table. |
| 141 | $table = new ConvertKit_WP_List_Table(); |
| 142 | $table->add_column( 'title', __( 'Contact Form 7 Form', 'convertkit' ), true ); |
| 143 | $table->add_column( 'form', __( 'Kit', 'convertkit' ), false ); |
| 144 | $table->add_column( 'email', __( 'Contact Form 7 Email Field', 'convertkit' ), false ); |
| 145 | $table->add_column( 'name', __( 'Contact Form 7 Name Field', 'convertkit' ), false ); |
| 146 | $table->add_column( 'creator_network_recommendations', __( 'Enable Creator Network Recommendations', 'convertkit' ), false ); |
| 147 | |
| 148 | // Iterate through Contact Form 7 Forms, building table array. |
| 149 | $table_rows = array(); |
| 150 | foreach ( $cf7_forms as $cf7_form ) { |
| 151 | // Build row. |
| 152 | $table_row = array( |
| 153 | 'title' => $cf7_form['name'], |
| 154 | 'form' => convertkit_get_subscription_dropdown_field( |
| 155 | '_wp_convertkit_integration_contactform7_settings[' . $cf7_form['id'] . ']', |
| 156 | (string) $this->settings->get_convertkit_subscribe_setting_by_cf7_form_id( $cf7_form['id'] ), |
| 157 | '_wp_convertkit_integration_contactform7_settings_' . $cf7_form['id'], |
| 158 | 'widefat', |
| 159 | 'contact_form_7' |
| 160 | ), |
| 161 | 'email' => 'your-email', |
| 162 | 'name' => 'your-name', |
| 163 | ); |
| 164 | |
| 165 | // Add Creator Network Recommendations table column. |
| 166 | if ( $creator_network_recommendations_enabled ) { |
| 167 | // Show checkbox to enable Creator Network Recommendations for this Contact Form 7 Form. |
| 168 | $table_row['creator_network_recommendations'] = $this->get_checkbox_field( |
| 169 | 'creator_network_recommendations_' . $cf7_form['id'], |
| 170 | '1', |
| 171 | $this->settings->get_creator_network_recommendations_enabled_by_cf7_form_id( $cf7_form['id'] ) |
| 172 | ); |
| 173 | } else { |
| 174 | // Show a link to the ConvertKit billing page, as a paid plan is required for Creator Network Recommendations. |
| 175 | $table_row['creator_network_recommendations'] = sprintf( |
| 176 | '%s <a href="%s" target="_blank">%s</a>', |
| 177 | esc_html__( 'Creator Network Recommendations requires a', 'convertkit' ), |
| 178 | convertkit_get_billing_url(), |
| 179 | esc_html__( 'paid Kit Plan', 'convertkit' ) |
| 180 | ); |
| 181 | } |
| 182 | |
| 183 | // Add row to table of settings. |
| 184 | $table_rows[] = $table_row; |
| 185 | } |
| 186 | |
| 187 | // Sort table rows. |
| 188 | $table_rows = $table->reorder( $table_rows ); |
| 189 | |
| 190 | // Set items. |
| 191 | $table->add_items( $table_rows ); |
| 192 | $table->set_total_items( count( $table_rows ) ); |
| 193 | |
| 194 | // Prepare and display WP_List_Table. |
| 195 | $table->prepare_items(); |
| 196 | $table->display(); |
| 197 | |
| 198 | // Register settings field. |
| 199 | settings_fields( $this->settings_key ); |
| 200 | |
| 201 | // Render closing container. |
| 202 | $this->render_container_end(); |
| 203 | |
| 204 | // Render submit button. |
| 205 | submit_button(); |
| 206 | |
| 207 | } |
| 208 | |
| 209 | /** |
| 210 | * Outputs a warning naming Contact Form 7 Forms that subscribe email addresses |
| 211 | * to Kit, and have no spam protection. |
| 212 | * |
| 213 | * @since 3.4.5 |
| 214 | * |
| 215 | * @param array $cf7_forms Contact Form 7 Forms. |
| 216 | */ |
| 217 | private function maybe_output_spam_protection_warning( $cf7_forms ) { |
| 218 | |
| 219 | // Build a list of Contact Form 7 Forms that subscribe to Kit, with no spam protection. |
| 220 | $unprotected_forms = array(); |
| 221 | foreach ( $cf7_forms as $cf7_form ) { |
| 222 | if ( ! $this->settings->get_convertkit_subscribe_setting_by_cf7_form_id( $cf7_form['id'] ) ) { |
| 223 | continue; |
| 224 | } |
| 225 | |
| 226 | if ( $this->form_has_spam_protection( $cf7_form['id'] ) ) { |
| 227 | continue; |
| 228 | } |
| 229 | |
| 230 | $unprotected_forms[] = $cf7_form['name']; |
| 231 | } |
| 232 | |
| 233 | // Bail if all Contact Form 7 Forms subscribing to Kit have spam protection. |
| 234 | if ( ! count( $unprotected_forms ) ) { |
| 235 | return; |
| 236 | } |
| 237 | |
| 238 | // Akismet only checks Contact Form 7 Forms whose fields define an `akismet:` option, |
| 239 | // so tell the user to configure their fields instead of enabling a provider. |
| 240 | if ( $this->has_akismet() ) { |
| 241 | $call_to_action_url = 'https://contactform7.com/spam-filtering-with-akismet/'; |
| 242 | $call_to_action_text = __( 'Akismet is enabled in Contact Form 7, but these forms do not use it. Add Akismet options to each form\'s fields.', 'convertkit' ); |
| 243 | } else { |
| 244 | $call_to_action_url = admin_url( 'admin.php?page=wpcf7-integration' ); |
| 245 | $call_to_action_text = __( 'Enable reCAPTCHA, Turnstile or Akismet in Contact Form 7.', 'convertkit' ); |
| 246 | } |
| 247 | |
| 248 | $this->output_warning( |
| 249 | sprintf( |
| 250 | '%s <strong>%s</strong>. %s <a href="%s">%s</a>', |
| 251 | esc_html__( 'The following Contact Form 7 Forms subscribe email addresses to Kit, but have no spam protection:', 'convertkit' ), |
| 252 | esc_html( implode( ', ', $unprotected_forms ) ), |
| 253 | esc_html__( 'Bots may submit fake email addresses, which are then added to your Kit account.', 'convertkit' ), |
| 254 | esc_url( $call_to_action_url ), |
| 255 | esc_html( $call_to_action_text ) |
| 256 | ), |
| 257 | 'convertkit-spam-protection-warning' |
| 258 | ); |
| 259 | |
| 260 | } |
| 261 | |
| 262 | /** |
| 263 | * Determines if the given Contact Form 7 Form has spam protection. |
| 264 | * |
| 265 | * @since 3.4.5 |
| 266 | * |
| 267 | * @param int $cf7_form_id Contact Form 7 Form ID. |
| 268 | * @return bool |
| 269 | */ |
| 270 | private function form_has_spam_protection( $cf7_form_id ) { |
| 271 | |
| 272 | // Contact Form 7 configures reCAPTCHA and Turnstile site wide, applying to |
| 273 | // every Contact Form 7 Form. |
| 274 | if ( $this->has_site_wide_spam_protection() ) { |
| 275 | return true; |
| 276 | } |
| 277 | |
| 278 | return $this->form_has_akismet( $cf7_form_id ); |
| 279 | |
| 280 | } |
| 281 | |
| 282 | /** |
| 283 | * Determines if Contact Form 7 has reCAPTCHA or Turnstile configured, which |
| 284 | * apply to every Contact Form 7 Form. |
| 285 | * |
| 286 | * @since 3.4.5 |
| 287 | * |
| 288 | * @return bool |
| 289 | */ |
| 290 | private function has_site_wide_spam_protection() { |
| 291 | |
| 292 | if ( ! class_exists( 'WPCF7_Integration' ) ) { |
| 293 | return false; |
| 294 | } |
| 295 | |
| 296 | $integration = WPCF7_Integration::get_instance(); |
| 297 | |
| 298 | foreach ( array( 'recaptcha', 'turnstile' ) as $name ) { |
| 299 | $service = $integration->get_service( $name ); |
| 300 | if ( $service && $service->is_active() ) { |
| 301 | return true; |
| 302 | } |
| 303 | } |
| 304 | |
| 305 | return false; |
| 306 | |
| 307 | } |
| 308 | |
| 309 | /** |
| 310 | * Determines if Contact Form 7's Akismet service is configured. |
| 311 | * |
| 312 | * @since 3.4.5 |
| 313 | * |
| 314 | * @return bool |
| 315 | */ |
| 316 | private function has_akismet() { |
| 317 | |
| 318 | if ( ! class_exists( 'WPCF7_Integration' ) ) { |
| 319 | return false; |
| 320 | } |
| 321 | |
| 322 | $service = WPCF7_Integration::get_instance()->get_service( 'akismet' ); |
| 323 | |
| 324 | return ( $service && $service->is_active() ); |
| 325 | |
| 326 | } |
| 327 | |
| 328 | /** |
| 329 | * Determines if Akismet checks the given Contact Form 7 Form. |
| 330 | * |
| 331 | * Contact Form 7 only sends a Form to Akismet when one or more of the Form's |
| 332 | * fields define an akismet: option, so an active Akismet service alone doesn't |
| 333 | * mean the Form is checked. |
| 334 | * |
| 335 | * @since 3.4.5 |
| 336 | * |
| 337 | * @param int $cf7_form_id Contact Form 7 Form ID. |
| 338 | * @return bool |
| 339 | */ |
| 340 | private function form_has_akismet( $cf7_form_id ) { |
| 341 | |
| 342 | if ( ! class_exists( 'WPCF7_ContactForm' ) ) { |
| 343 | return false; |
| 344 | } |
| 345 | |
| 346 | // Bail if Akismet isn't configured. |
| 347 | if ( ! $this->has_akismet() ) { |
| 348 | return false; |
| 349 | } |
| 350 | |
| 351 | // Bail if the Form can't be read. |
| 352 | $contact_form = WPCF7_ContactForm::get_instance( $cf7_form_id ); |
| 353 | if ( ! $contact_form ) { |
| 354 | return false; |
| 355 | } |
| 356 | |
| 357 | // Determine if any of the Form's fields define an akismet: option. |
| 358 | foreach ( $contact_form->scan_form_tags() as $tag ) { |
| 359 | if ( $tag->get_option( 'akismet', '(author|author_email|author_url)', true ) ) { |
| 360 | return true; |
| 361 | } |
| 362 | } |
| 363 | |
| 364 | return false; |
| 365 | |
| 366 | } |
| 367 | |
| 368 | /** |
| 369 | * Gets available forms from CF7 |
| 370 | */ |
| 371 | private function get_cf7_forms() { |
| 372 | |
| 373 | $forms = array(); |
| 374 | |
| 375 | $result = new WP_Query( |
| 376 | array( |
| 377 | 'post_type' => 'wpcf7_contact_form', |
| 378 | 'posts_per_page' => -1, |
| 379 | 'orderby' => 'ID', |
| 380 | 'order' => 'ASC', |
| 381 | ) |
| 382 | ); |
| 383 | |
| 384 | if ( ! count( $result->posts ) ) { |
| 385 | return false; |
| 386 | } |
| 387 | |
| 388 | foreach ( $result->posts as $post ) { |
| 389 | $forms[] = array( |
| 390 | 'id' => $post->ID, |
| 391 | 'name' => $post->post_title, |
| 392 | ); |
| 393 | } |
| 394 | |
| 395 | return $forms; |
| 396 | |
| 397 | } |
| 398 | |
| 399 | } |
| 400 | |
| 401 | // Register Admin Settings section. |
| 402 | add_filter( |
| 403 | 'convertkit_admin_settings_register_sections', |
| 404 | /** |
| 405 | * Register WishList Member as a section at Settings > Kit. |
| 406 | * |
| 407 | * @param array $sections Settings Sections. |
| 408 | * @return array |
| 409 | */ |
| 410 | function ( $sections ) { |
| 411 | |
| 412 | // Bail if Contact Form 7 isn't enabled. |
| 413 | if ( ! defined( 'WPCF7_VERSION' ) ) { |
| 414 | return $sections; |
| 415 | } |
| 416 | |
| 417 | // Register this class as a section at Settings > Kit. |
| 418 | $sections['contactform7'] = new ConvertKit_ContactForm7_Admin_Section(); |
| 419 | return $sections; |
| 420 | |
| 421 | } |
| 422 | ); |
| 423 |