PluginProbe
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages / 2.4.0
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages v2.4.0
3.4.4 3.4.3 3.4.2 3.4.1 3.4.0 3.3.9 3.3.8 3.3.7 3.3.6 3.3.5 3.3.4 3.3.3 3.3.2 3.3.1 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.2.7 2.2.8 2.2.9 2.3.0 All 197 releases
← All changes | includes/class-convertkit-output.php +68 -521 3.3.72.4.0 View file →
@@ -66,15 +66,13 @@
66 66 * @since 1.9.6
67 67 */
68 68 public function __construct() {
69 69
70 - add_action( 'wp', array( $this, 'maybe_tag_subscriber' ) );
70 + add_action( 'init', array( $this, 'get_subscriber_id_from_request' ), 1 );
71 71 add_action( 'template_redirect', array( $this, 'output_form' ) );
72 72 add_action( 'template_redirect', array( $this, 'page_takeover' ) );
73 73 add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
74 74 add_filter( 'the_content', array( $this, 'append_form_to_content' ) );
75 - add_filter( 'hooked_block_types', array( $this, 'maybe_register_form_block_on_category_archive' ), 10, 4 );
76 - add_filter( 'hooked_block_convertkit/form', array( $this, 'append_form_block_to_category_archive' ), 10, 1 );
77 75 add_action( 'wp_footer', array( $this, 'output_global_non_inline_form' ), 1 );
78 76 add_action( 'wp_footer', array( $this, 'output_scripts_footer' ) );
79 77
80 78 }
@@ -79,88 +77,8 @@
79 77
80 78 }
81 79
82 80 /**
83 - * Tags the subscriber, if:
84 - * - a subscriber ID exists in the cookie or URL,
85 - * - the WordPress Page has the "Add a Tag" setting specified
86 - *
87 - * @since 2.4.9.1
88 - */
89 - public function maybe_tag_subscriber() {
90 -
91 - // Bail if not a singular Post Type supported by ConvertKit.
92 - if ( ! is_singular( convertkit_get_supported_post_types() ) ) {
93 - return;
94 - }
95 -
96 - // Get Post ID.
97 - $post_id = get_the_ID();
98 -
99 - // Bail if a Post ID couldn't be identified.
100 - if ( ! $post_id ) {
101 - return;
102 - }
103 -
104 - // Get Settings, if they have not yet been loaded.
105 - if ( ! $this->settings ) {
106 - $this->settings = new ConvertKit_Settings();
107 - }
108 -
109 - // Bail if the API hasn't been configured.
110 - if ( ! $this->settings->has_access_and_refresh_token() ) {
111 - return;
112 - }
113 -
114 - // Get ConvertKit Post's Settings, if they have not yet been loaded.
115 - if ( ! $this->post_settings ) {
116 - $this->post_settings = new ConvertKit_Post( $post_id );
117 - }
118 -
119 - // Bail if no "Add a Tag" setting specified for this Page.
120 - if ( ! $this->post_settings->has_tag() ) {
121 - return;
122 - }
123 -
124 - // Get subscriber ID from URL or cookie.
125 - $this->get_subscriber_id_from_request();
126 -
127 - // Bail if no subscriber ID detected.
128 - if ( ! $this->subscriber_id ) {
129 - return;
130 - }
131 -
132 - // Initialize the API.
133 - $api = new ConvertKit_API_V4(
134 - CONVERTKIT_OAUTH_CLIENT_ID,
135 - CONVERTKIT_OAUTH_CLIENT_REDIRECT_URI,
136 - $this->settings->get_access_token(),
137 - $this->settings->get_refresh_token(),
138 - $this->settings->debug_enabled(),
139 - 'output'
140 - );
141 -
142 - // If the subscriber ID is not numeric, it's a cryptographically-signed subscriber ID, set
143 - // when using the Member Content functionality by Kit's API.
144 - // Fetch the underlying subscriber ID for the tag_subscriber() method.
145 - if ( ! is_numeric( $this->subscriber_id ) ) {
146 - $result = $api->profile( $this->subscriber_id );
147 -
148 - // If an error occurred, the subscriber ID is invalid.
149 - if ( is_wp_error( $result ) ) {
150 - return;
151 - }
152 -
153 - // Set the subscriber ID.
154 - $this->subscriber_id = $result['id'];
155 - }
156 -
157 - // Tag subscriber.
158 - $api->tag_subscriber( $this->post_settings->get_tag(), $this->subscriber_id );
159 -
160 - }
161 -
162 - /**
163 81 * Runs the `convertkit_output_output_form` action for singular Post Types that don't use the_content()
164 82 * or apply_filters( 'the_content' ) to output a ConvertKit Form.
165 83 *
166 84 * @since 1.9.6
@@ -234,9 +152,9 @@
234 152
235 153 // Get Landing Page.
236 154 $landing_page = $this->landing_pages->get_html( $this->post_settings->get_landing_page() );
237 155
238 - // Bail if an error occurred.
156 + // Bail if an error occured.
239 157 if ( is_wp_error( $landing_page ) ) {
240 158 return;
241 159 }
242 160
@@ -242,23 +160,8 @@
242 160
243 161 // Replace the favicon with the WordPress site's favicon, if specified.
244 162 $landing_page = $this->landing_pages->replace_favicon( $landing_page );
245 163
246 - /**
247 - * Perform any actions immediately prior to outputting the Landing Page.
248 - *
249 - * Caching and minification Plugins may need to hook here to prevent
250 - * CSS / JS minification and lazy loading images, which can interfere
251 - * with Landing Pages.
252 - *
253 - * @since 2.4.4
254 - *
255 - * @param string $landing_page ConvertKit Landing Page HTML.
256 - * @param int $landing_page_id ConvertKit Landing Page ID.
257 - * @param int $post_id WordPress Page ID.
258 - */
259 - do_action( 'convertkit_output_landing_page_before', $landing_page, $landing_page_id, $post_id );
260 -
261 164 // Output Landing Page.
262 165 // Output is supplied from ConvertKit's API, which is already sanitized.
263 166 echo $landing_page; // phpcs:ignore WordPress.Security.EscapeOutput
264 167 exit;
@@ -265,9 +168,9 @@
265 168
266 169 }
267 170
268 171 /**
269 - * Inserts a form to the singular Page, Post or Custom Post Type's Content.
172 + * Appends a form to the singular Page, Post or Custom Post Type's Content.
270 173 *
271 174 * @param string $content Post Content.
272 175 * @return string Post Content with Form Appended, if applicable
273 176 */
@@ -277,17 +180,10 @@
277 180 if ( ! is_singular( convertkit_get_supported_post_types() ) ) {
278 181 return $content;
279 182 }
280 183
281 - // Get Post ID.
184 + // Get Post ID and ConvertKit Form ID for the Post.
282 185 $post_id = get_the_ID();
283 -
284 - // Bail if Post Type is not supported by Kit.
285 - if ( ! in_array( get_post_type( $post_id ), convertkit_get_supported_post_types(), true ) ) {
286 - return $content;
287 - }
288 -
289 - // Get Form ID for the Post.
290 186 $form_id = $this->get_post_form_id( $post_id );
291 187
292 188 /**
293 189 * Define the ConvertKit Form ID to display for the given Post ID,
@@ -312,17 +208,17 @@
312 208 $this->forms = new ConvertKit_Resource_Forms( 'output_form' );
313 209 }
314 210
315 211 // Get Form HTML.
316 - $form = $this->forms->get_html( $form_id, $post_id );
212 + $form = $this->forms->get_html( $form_id );
317 213
318 - // If an error occurred, it could be because the specified Form ID for the Post either:
214 + // If an error occured, it could be because the specified Form ID for the Post either:
319 215 // - belongs to another ConvertKit account (i.e. API credentials were changed in the Plugin, but this Post's specified Form was not changed), or
320 216 // - the form was deleted from the ConvertKit account.
321 217 // Attempt to fallback to the default form for this Post Type.
322 218 if ( is_wp_error( $form ) ) {
323 219 if ( $this->settings->debug_enabled() ) {
324 - $content .= '<!-- Kit append_form_to_content(): ' . $form->get_error_message() . ' Attempting fallback to Default Form. -->';
220 + $content .= '<!-- ConvertKit append_form_to_content(): ' . $form->get_error_message() . ' Attempting fallback to Default Form. -->';
325 221 }
326 222
327 223 // Get Default Form ID for this Post's Type.
328 224 $form_id = $this->settings->get_default_form( get_post_type( $post_id ) );
@@ -329,9 +225,9 @@
329 225
330 226 // If no Default Form is specified, just return the Post Content, unedited.
331 227 if ( ! $form_id ) {
332 228 if ( $this->settings->debug_enabled() ) {
333 - $content .= '<!-- Kit append_form_to_content(): No Default Form exists as a fallback. -->';
229 + $content .= '<!-- ConvertKit append_form_to_content(): No Default Form exists as a fallback. -->';
334 230 }
335 231
336 232 return $content;
337 233 }
@@ -336,15 +232,15 @@
336 232 return $content;
337 233 }
338 234
339 235 // Get Form HTML.
340 - $form = $this->forms->get_html( $form_id, $post_id );
236 + $form = $this->forms->get_html( $form_id );
341 237
342 - // If an error occurred again, the default form doesn't exist in this ConvertKit account.
238 + // If an error occured again, the default form doesn't exist in this ConvertKit account.
343 239 // Just return the Post Content, unedited.
344 240 if ( is_wp_error( $form ) ) {
345 241 if ( $this->settings->debug_enabled() ) {
346 - $content .= '<!-- Kit append_form_to_content(): Default Form: ' . $form->get_error_message() . ' -->';
242 + $content .= '<!-- ConvertKit append_form_to_content(): Default Form: ' . $form->get_error_message() . ' -->';
347 243 }
348 244
349 245 return $content;
350 246 }
@@ -349,70 +245,23 @@
349 245 return $content;
350 246 }
351 247 }
352 248
353 - // If the Form HTML is empty, it's a modal form that has been set to load in the footer of the site.
354 - // We don't need to append anything to the content.
355 - if ( empty( $form ) ) {
356 - if ( $this->settings->debug_enabled() ) {
357 - $content .= '<!-- Kit append_form_to_content(): Form is non-inline, appended to footer. -->';
358 - }
359 -
360 - return $content;
361 - }
362 -
363 249 // If here, we have a ConvertKit Form.
364 - // Append form to Post's Content, based on the position setting.
365 - $form_position = $this->settings->get_default_form_position( get_post_type( $post_id ) );
250 + // Append form to Post's Content.
251 + $content = $content .= $form;
366 252
367 - if ( $this->settings->debug_enabled() ) {
368 - $content .= '<!-- Kit append_form_to_content(): Form Position: ' . esc_html( $form_position ) . ' -->';
369 - }
370 -
371 - switch ( $form_position ) {
372 - case 'before_after_content':
373 - $content = $form . $content . $form;
374 - break;
375 -
376 - case 'before_content':
377 - $content = $form . $content;
378 - break;
379 -
380 - case 'after_element':
381 - $element = $this->settings->get_default_form_position_element( get_post_type( $post_id ) );
382 - $index = $this->settings->get_default_form_position_element_index( get_post_type( $post_id ) );
383 -
384 - // Check if DOMDocument is installed.
385 - // It should be installed as mosts hosts include php-dom and php-xml modules.
386 - // If not, fallback to using preg_match_all(), which is less reliable.
387 - if ( ! class_exists( 'DOMDocument' ) ) {
388 - $content = $this->inject_form_after_element_fallback( $content, $element, $index, $form );
389 - break;
390 - }
391 -
392 - // Use DOMDocument.
393 - $content = $this->inject_form_after_element( $content, $element, $index, $form );
394 - break;
395 -
396 - case 'after_content':
397 - default:
398 - // Default behaviour < 2.5.8 was to append the Form after the content.
399 - $content .= $form;
400 - break;
401 - }
402 -
403 253 /**
404 254 * Filter the Post's Content, which includes a ConvertKit Form, immediately before it is output.
405 255 *
406 256 * @since 1.9.6
407 257 *
408 - * @param string $content Post Content
409 - * @param string $form ConvertKit Form HTML
410 - * @param int $post_id Post ID
411 - * @param int $form_id ConvertKit Form ID
412 - * @param string $form_position Form Position setting for the Post's Type.
258 + * @param string $content Post Content
259 + * @param string $form ConvertKit Form HTML
260 + * @param int $post_id Post ID
261 + * @param int $form_id ConvertKit Form ID
413 262 */
414 - $content = apply_filters( 'convertkit_frontend_append_form', $content, $form, $post_id, $form_id, $form_position );
263 + $content = apply_filters( 'convertkit_frontend_append_form', $content, $form, $post_id, $form_id );
415 264
416 265 return $content;
417 266
418 267 }
@@ -417,219 +266,8 @@
417 266
418 267 }
419 268
420 269 /**
421 - * Injects the form after the given element and index, using DOMDocument.
422 - *
423 - * @since 2.6.2
424 - *
425 - * @param string $content Page / Post Content.
426 - * @param string $tag HTML tag to insert form after.
427 - * @param int $index Number of $tag elements to find before inserting form.
428 - * @param string $form Form HTML to inject.
429 - * @return string
430 - */
431 - private function inject_form_after_element( $content, $tag, $index, $form ) {
432 -
433 - // If the form is empty, don't inject anything.
434 - if ( empty( $form ) ) {
435 - return $content;
436 - }
437 -
438 - // Load the content into the parser.
439 - $parser = new ConvertKit_HTML_Parser( $content, LIBXML_HTML_NODEFDTD );
440 -
441 - // Find the element to append the form to.
442 - // item() is a zero based index.
443 - $element_node = $parser->html->getElementsByTagName( $tag )->item( $index - 1 );
444 -
445 - // If the element could not be found, either the number of elements by tag name is less
446 - // than the requested position the form be inserted in, or no element exists.
447 - // Append the form to the original content and return.
448 - if ( is_null( $element_node ) ) {
449 - return $content . $form;
450 - }
451 -
452 - // Load the form into the parser.
453 - $form_parser = new ConvertKit_HTML_Parser( $form, LIBXML_HTML_NODEFDTD );
454 - $form_body = $form_parser->html->getElementsByTagName( 'body' )->item( 0 );
455 -
456 - // Collect nodes first to avoid live NodeList mutation issues.
457 - $nodes_to_insert = array();
458 - foreach ( $form_body->childNodes as $child ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
459 - $nodes_to_insert[] = $parser->html->importNode( $child, true );
460 - }
461 -
462 - // Inject the form node(s) after the element node e.g. after the paragraph, heading etc.
463 - $next_sibling = $element_node->nextSibling; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
464 - foreach ( $nodes_to_insert as $node ) {
465 - $element_node->parentNode->insertBefore( $node, $element_node->nextSibling ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
466 - }
467 -
468 - // Return modified HTML string.
469 - return $parser->get_body_html();
470 -
471 - }
472 -
473 - /**
474 - * Injects the form after the given element and index, using preg_match_all().
475 - * This is less reliable than DOMDocument, and is called if DOMDocument is
476 - * not installed on the server.
477 - *
478 - * @since 2.6.2
479 - *
480 - * @param string $content Page / Post Content.
481 - * @param string $tag HTML tag to insert form after.
482 - * @param int $index Number of $tag elements to find before inserting form.
483 - * @param string $form Form HTML to inject.
484 - * @return string
485 - */
486 - private function inject_form_after_element_fallback( $content, $tag, $index, $form ) {
487 -
488 - // If the form is empty, don't inject anything.
489 - if ( empty( $form ) ) {
490 - return $content;
491 - }
492 -
493 - // Calculate tag length.
494 - $tag_length = ( strlen( $tag ) + 3 );
495 -
496 - // Find all closing elements.
497 - preg_match_all( '/<\/' . $tag . '>/', $content, $matches );
498 -
499 - // If no elements exist, just append the form.
500 - if ( count( $matches[0] ) === 0 ) {
501 - $content = $content . $form;
502 - return $content;
503 - }
504 -
505 - // If the number of elements is less than the index, we don't have enough elements to add the form to.
506 - // Just add the form after the content.
507 - if ( count( $matches[0] ) <= $index ) {
508 - $content = $content . $form;
509 - return $content;
510 - }
511 -
512 - // Iterate through the content to find the element at the configured index e.g. find the 4th closing paragraph.
513 - $offset = 0;
514 - foreach ( $matches[0] as $element_index => $element ) {
515 - $position = strpos( $content, $element, $offset );
516 - if ( ( $element_index + 1 ) === $index ) {
517 - return substr( $content, 0, $position + 4 ) . $form . substr( $content, $position + 4 );
518 - }
519 -
520 - // Increment offset.
521 - $offset = $position + 1;
522 - }
523 -
524 - // If here, something went wrong.
525 - // Just add the form after the content.
526 - $content = $content . $form;
527 - return $content;
528 -
529 - }
530 -
531 - /**
532 - * Registers the ConvertKit Form block to before or after the Query Loop block, when viewing a Category archive.
533 - *
534 - * See append_form_block_on_category_archive() configures the block to display the applicable category's Form.
535 - *
536 - * @since 2.4.9.1
537 - *
538 - * @param array $hooked_blocks The list of hooked block types.
539 - * @param string $position The relative position of the hooked blocks.
540 - * @param string $anchor_block The anchor block type.
541 - * @param WP_Block_Template|WP_Post|array $context The block template, template part, wp_navigation post type, or pattern that the anchor block belongs to.
542 - * @return array
543 - */
544 - public function maybe_register_form_block_on_category_archive( $hooked_blocks, $position, $anchor_block, $context ) {
545 -
546 - // Don't append if we're not viewing a category archive.
547 - if ( ! is_category() ) {
548 - return $hooked_blocks;
549 - }
550 -
551 - if ( $context instanceof WP_Block_Template && $context->slug !== 'archive' ) {
552 - return $hooked_blocks;
553 - }
554 -
555 - // Don't append if the anchor block isn't the Query Loop block.
556 - if ( $anchor_block !== 'core/query' ) {
557 - return $hooked_blocks;
558 - }
559 -
560 - // Don't append if the Category's form position setting is not defined.
561 - $form_position = $this->get_term_form_position();
562 - if ( ! $form_position ) {
563 - // Unhook this function as we don't need to check again in this request, as we'll
564 - // never output a form on the Category archive.
565 - remove_filter( 'hooked_block_types', array( $this, 'maybe_register_form_block_on_category_archive' ), 10 );
566 -
567 - return $hooked_blocks;
568 - }
569 -
570 - // Don't append if the position doesn't match.
571 - if ( $form_position !== $position ) {
572 - return $hooked_blocks;
573 - }
574 -
575 - // Hook the ConvertKit Form block.
576 - $hooked_blocks[] = 'convertkit/form';
577 -
578 - // Unhook this function as we don't need to check again in this request, as
579 - // we have now appended the form.
580 - remove_filter( 'hooked_block_types', array( $this, 'maybe_register_form_block_on_category_archive' ), 10 );
581 -
582 - return $hooked_blocks;
583 -
584 - }
585 -
586 - /**
587 - * Configures the ConvertKit Form block that was hooked below the Query Loop block by maybe_register_form_block_on_category_archive,
588 - * defining the Form ID based on the current Category's Form ID.
589 - *
590 - * @since 2.4.9.1
591 - *
592 - * @param array $parsed_hooked_block The parsed block array for the given hooked block type, or null to suppress the block.
593 - * @return null|array
594 - */
595 - public function append_form_block_to_category_archive( $parsed_hooked_block ) {
596 -
597 - // Sanity check that we're still viewing a Category archive.
598 - if ( ! is_category() ) {
599 - // Returning null will unregister the Form block from displaying.
600 - return null;
601 - }
602 -
603 - // Get Category archive being viewed.
604 - $category = get_category( get_query_var( 'cat' ) );
605 -
606 - // Bail if the Category could be found.
607 - if ( is_wp_error( $category ) || is_null( $category ) ) {
608 - // Returning null will unregister the Form block from displaying.
609 - return null;
610 - }
611 -
612 - // Load Term Settings.
613 - $term_settings = new ConvertKit_Term( $category->term_id );
614 -
615 - // Bail if no Form specified for the Category.
616 - if ( ! $term_settings->has_form() ) {
617 - // Returning null will unregister the Form block from displaying.
618 - return null;
619 - }
620 -
621 - // Define the form block attributes to display the given Form ID.
622 - $parsed_hooked_block['attrs'] = array(
623 - 'id' => absint( $term_settings->get_form() ),
624 - );
625 -
626 - // Return the Form block with its attributes.
627 - return $parsed_hooked_block;
628 -
629 - }
630 -
631 - /**
632 270 * Returns the Post, Category or Plugin ConvertKit Form ID for the given Post.
633 271 *
634 272 * If the Post specifies a form to use, returns that Form ID.
635 273 * If the Post uses the 'Default' setting, and an assigned Category has a Form ID, uses the Category's Form ID.
@@ -695,53 +333,16 @@
695 333 // If a Form ID exists, return it now.
696 334 if ( $term_settings->has_form() ) {
697 335 return $term_settings->get_form();
698 336 }
699 -
700 - // If the Term specifies that no Form should be used, return false.
701 - if ( $term_settings->uses_no_form() ) {
702 - return false;
703 - }
704 337 }
705 338
706 - // If here, all Terms were set to display the Default Form.
707 - // Therefore use the Plugin's Default Form.
339 + // If here, use the Plugin's Default Form.
708 340 return $this->settings->get_default_form( get_post_type( $post_id ) );
709 341
710 342 }
711 343
712 344 /**
713 - * Returns the Form Position setting for the currently viewed Category.
714 - *
715 - * @since 2.4.9.1
716 - *
717 - * @return bool|string
718 - */
719 - private function get_term_form_position() {
720 -
721 - // Get Category archive being viewed.
722 - $category = get_category( get_query_var( 'cat' ) );
723 -
724 - // Bail if the Category could be found.
725 - if ( is_wp_error( $category ) || is_null( $category ) ) {
726 - return false;
727 - }
728 -
729 - // Load Term Settings.
730 - $term_settings = new ConvertKit_Term( $category->term_id );
731 -
732 - // Return false if no form position is defined i.e. we don't want to display
733 - // it on the Category archive.
734 - if ( ! $term_settings->has_form_position() ) {
735 - return false;
736 - }
737 -
738 - // Return form position.
739 - return $term_settings->get_form_position();
740 -
741 - }
742 -
743 - /**
744 345 * Enqueue scripts.
745 346 *
746 347 * @since 1.9.6
747 348 */
@@ -746,29 +347,49 @@
746 347 * @since 1.9.6
747 348 */
748 349 public function enqueue_scripts() {
749 350
750 - // Get ConvertKit Settings and Post's Settings.
751 - $settings = new ConvertKit_Settings();
351 + // Get Post.
352 + $post = get_post();
752 353
753 - // Bail if the no scripts setting is enabled.
754 - if ( $settings->scripts_disabled() ) {
354 + // Bail if no Post could be fetched.
355 + if ( ! $post ) {
755 356 return;
756 357 }
757 358
758 - // Enqueue frontend JS.
759 - convertkit_enqueue_frontend_js();
359 + // Get ConvertKit Settings and Post's Settings.
360 + $settings = new ConvertKit_Settings();
361 + $convertkit_post = new ConvertKit_Post( $post->ID );
760 362
761 - // Define variables.
363 + // Register scripts that we might use.
364 + wp_register_script(
365 + 'convertkit-js',
366 + CONVERTKIT_PLUGIN_URL . 'resources/frontend/js/convertkit.js',
367 + array( 'jquery' ),
368 + CONVERTKIT_PLUGIN_VERSION,
369 + true
370 + );
762 371 wp_localize_script(
763 372 'convertkit-js',
764 373 'convertkit',
765 374 array(
375 + 'ajaxurl' => admin_url( 'admin-ajax.php' ),
766 376 'debug' => $settings->debug_enabled(),
377 + 'nonce' => wp_create_nonce( 'convertkit' ),
767 378 'subscriber_id' => $this->subscriber_id,
379 + 'tag' => ( ( is_singular() && $convertkit_post->has_tag() ) ? $convertkit_post->get_tag() : false ),
380 + 'post_id' => $post->ID,
768 381 )
769 382 );
770 383
384 + // Bail if the no scripts setting is enabled.
385 + if ( $settings->scripts_disabled() ) {
386 + return;
387 + }
388 +
389 + // Enqueue.
390 + wp_enqueue_script( 'convertkit-js' );
391 +
771 392 }
772 393
773 394 /**
774 395 * Gets the subscriber ID from the request (either the cookie or the URL).
@@ -780,9 +401,9 @@
780 401 // Use ConvertKit_Subscriber class to fetch and validate the subscriber ID.
781 402 $subscriber = new ConvertKit_Subscriber();
782 403 $subscriber_id = $subscriber->get_subscriber_id();
783 404
784 - // If an error occurred, the subscriber ID in the request/cookie is not a valid subscriber.
405 + // If an error occured, the subscriber ID in the request/cookie is not a valid subscriber.
785 406 if ( is_wp_error( $subscriber_id ) ) {
786 407 return;
787 408 }
788 409
@@ -790,10 +411,10 @@
790 411
791 412 }
792 413
793 414 /**
794 - * Outputs a non-inline forms if defined in the Plugin's settings >
795 - * Default Forms (Site Wide) setting.
415 + * Outputs a non-inline form if defined in the Plugin's settings >
416 + * Default Non-Inline Form (Global) setting.
796 417 *
797 418 * @since 2.3.3
798 419 */
799 420 public function output_global_non_inline_form() {
@@ -807,48 +428,33 @@
807 428 if ( ! $this->settings->has_non_inline_form() ) {
808 429 return;
809 430 }
810 431
811 - // Bail if the Page, Post or Custom Post Type's Form setting is set to 'None'
812 - // and the Plugin is set to honor this setting.
813 - if ( $this->post_settings !== false && $this->post_settings->uses_no_form() && $this->settings->non_inline_form_honor_none_setting() ) {
432 + // Get form.
433 + $convertkit_forms = new ConvertKit_Resource_Forms();
434 + $form = $convertkit_forms->get_by_id( (int) $this->settings->get_non_inline_form() );
435 +
436 + // Bail if the Form doesn't exist (this shouldn't happen, but you never know).
437 + if ( ! $form ) {
814 438 return;
815 439 }
816 440
817 - // Determine if the Non-inline Form Limit per Session setting is enabled.
818 - $limit_per_session = $this->settings->non_inline_form_limit_per_session();
441 + // Add the form to the scripts array so it is included in the output.
442 + add_filter(
443 + 'convertkit_output_scripts_footer',
444 + function ( $scripts ) use ( $form ) {
819 445
820 - // Get form.
821 - $convertkit_forms = new ConvertKit_Resource_Forms();
446 + $scripts[] = array(
447 + 'async' => true,
448 + 'data-uid' => $form['uid'],
449 + 'src' => $form['embed_js'],
450 + );
822 451
823 - // Iterate through forms.
824 - foreach ( $this->settings->get_non_inline_form() as $form_id ) {
825 - // Get Form.
826 - $form = $convertkit_forms->get_by_id( (int) $form_id );
452 + return $scripts;
827 453
828 - // Bail if the Form doesn't exist (this shouldn't happen, but you never know).
829 - if ( ! $form ) {
830 - continue;
831 454 }
455 + );
832 456
833 - // Add the form to the scripts array so it is included in the output.
834 - add_filter(
835 - 'convertkit_output_scripts_footer',
836 - function ( $scripts ) use ( $form, $limit_per_session ) {
837 -
838 - $scripts[] = array(
839 - 'async' => true,
840 - 'data-uid' => $form['uid'],
841 - 'src' => $form['embed_js'],
842 - 'data-kit-limit-per-session' => $limit_per_session ? '1' : '0',
843 - );
844 -
845 - return $scripts;
846 -
847 - }
848 - );
849 - }
850 -
851 457 }
852 458
853 459 /**
854 460 * Outputs any JS <script> tags registered with the convertkit_output_scripts_footer
@@ -857,13 +463,8 @@
857 463 * @since 2.1.4
858 464 */
859 465 public function output_scripts_footer() {
860 466
861 - // Don't output scripts if the request is for a search page or 404.
862 - if ( is_search() || is_404() ) {
863 - return;
864 - }
865 -
866 467 // Define array of scripts.
867 468 $scripts = array();
868 469
869 470 /**
@@ -884,24 +485,10 @@
884 485 $output_scripts = array();
885 486
886 487 // Iterate through scripts, building the <script> tag for each.
887 488 foreach ( $scripts as $script ) {
888 - /**
889 - * Filter the form <script> key/value pairs immediately before the script is output.
890 - *
891 - * @since 2.4.5
892 - *
893 - * @param array $script Form script key/value pairs to output as <script> tag.
894 - */
895 - $script = apply_filters( 'convertkit_output_script_footer', $script );
489 + $output = '<script';
896 490
897 - // Skip script if it is limited by the Non-inline Form Limit per Session setting.
898 - if ( $this->is_script_output_limited_by_session( $script ) ) {
899 - continue;
900 - }
901 -
902 - // Build output.
903 - $output = '<script';
904 491 foreach ( $script as $attribute => $value ) {
905 492 // If the value is true, just output the attribute.
906 493 if ( $value === true ) {
907 494 $output .= ' ' . esc_attr( $attribute );
@@ -907,21 +494,11 @@
907 494 $output .= ' ' . esc_attr( $attribute );
908 495 continue;
909 496 }
910 497
911 - // Sanitize attribute and value.
912 - $attribute = esc_attr( $attribute );
913 - $value = ( $attribute === 'src' ? esc_url( $value ) : esc_attr( $value ) );
914 -
915 498 // Output the attribute and value.
916 - $output .= ' ' . $attribute;
917 -
918 - // Output the value, if it's not a blank string.
919 - if ( strlen( $value ) > 0 ) {
920 - $output .= '="' . $value . '"';
921 - }
499 + $output .= ' ' . esc_attr( $attribute ) . '="' . esc_attr( $value ) . '"';
922 500 }
923 -
924 501 $output .= '></script>';
925 502
926 503 // Add to array.
927 504 $output_scripts[] = $output;
@@ -936,38 +513,8 @@
936 513 // Output scripts.
937 514 foreach ( $output_scripts as $output_script ) {
938 515 echo $output_script . "\n"; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
939 516 }
940 -
941 - }
942 -
943 - /**
944 - * Checks if a script is limited by the Non-inline Form Limit per Session setting.
945 - *
946 - * @since 3.0.0
947 - *
948 - * @param array $script Script.
949 - * @return bool
950 - */
951 - private function is_script_output_limited_by_session( $script ) {
952 -
953 - // Get Settings, if they have not yet been loaded.
954 - if ( ! $this->settings ) {
955 - $this->settings = new ConvertKit_Settings();
956 - }
957 -
958 - // Display script if the "Display Limit" setting isn't enabled.
959 - if ( ! $this->settings->non_inline_form_limit_per_session() ) {
960 - return false;
961 - }
962 -
963 - // Display script if the "Display Limit" setting should not be applied to this script.
964 - if ( ! isset( $script['data-kit-limit-per-session'] ) ) {
965 - return false;
966 - }
967 -
968 - // Display script if this is the first time the visitor has seen any non-inline form.
969 - return isset( $_COOKIE['ck_non_inline_form_displayed'] );
970 517
971 518 }
972 519
973 520 }