PluginProbe
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages / 3.4.6
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages v3.4.6
3.4.6 3.4.5 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 All 199 releases
← All changes | admin/importers/class-convertkit-admin-importer.php +117 -40 3.3.3 → 3.4.6 View file →
@@ -32,8 +32,17 @@
32 32 */
33 33 public $title = '';
34 34
35 35 /**
36 + * Holds the importer description.
37 + *
38 + * @since 3.3.5
39 + *
40 + * @var string
41 + */
42 + public $description = '';
43 +
44 + /**
36 45 * Holds the shortcode name for the third party Form plugin.
37 46 *
38 47 * @since 3.1.0
39 48 *
@@ -41,13 +50,17 @@
41 50 */
42 51 public $shortcode_name = '';
43 52
44 53 /**
45 - * Holds the shortcode ID attribute name for the third party Form plugin.
54 + * Holds the shortcode ID attribute name(s) for the third party Form plugin.
46 55 *
56 + * Accepts a string for a single attribute (e.g. 'form'), or an array of
57 + * strings for plugins where the form ID may appear under multiple attribute
58 + * names (e.g. ['form', 'id']).
59 + *
47 60 * @since 3.1.0
48 61 *
49 - * @var bool|string
62 + * @var bool|string|array
50 63 */
51 64 public $shortcode_id_attribute = false;
52 65
53 66 /**
@@ -59,13 +72,17 @@
59 72 */
60 73 public $block_name = '';
61 74
62 75 /**
63 - * Holds the block ID attribute name for the third party Form plugin.
76 + * Holds the block ID attribute name(s) for the third party Form plugin.
64 77 *
78 + * Accepts a string for a single attribute (e.g. 'form'), or an array of
79 + * strings for plugins where the form ID may appear under multiple attribute
80 + * names (e.g. ['form', 'id']).
81 + *
65 82 * @since 3.1.6
66 83 *
67 - * @var bool|string
84 + * @var bool|string|array
68 85 */
69 86 public $block_id_attribute = false;
70 87
71 88 /**
@@ -98,11 +115,12 @@
98 115 }
99 116
100 117 // Add this importer to the list of importers.
101 118 $importers[ $this->name ] = array(
102 - 'name' => $this->name,
103 - 'title' => $this->title,
104 - 'forms' => $this->get_forms(),
119 + 'name' => $this->name,
120 + 'title' => $this->title,
121 + 'description' => $this->description,
122 + 'forms' => $this->get_forms(),
105 123 );
106 124
107 125 return $importers;
108 126
@@ -243,8 +261,11 @@
243 261
244 262 // Replace the third party Form Shortcode with the Kit Form Shortcode.
245 263 $post_content = $this->replace_shortcodes_in_content( $post_content, $third_party_form_id, $form_id );
246 264
265 + // Double escape backslashes so that wp_update_post doesn't remove them.
266 + $post_content = str_replace( '\\', '\\\\', $post_content );
267 +
247 268 // Update the Post content.
248 269 wp_update_post(
249 270 array(
250 271 'ID' => $post_id,
@@ -274,24 +295,41 @@
274 295 // If there's no shortcode ID attribute, match shortcodes with or without any attribute.
275 296 if ( ! $this->shortcode_id_attribute ) {
276 297 $pattern = '/\[' // Start regex with an opening square bracket.
277 298 . preg_quote( $this->shortcode_name, '/' ) // Match the shortcode name, escaping any regex special chars.
299 + . '(?=[\s\]\/])' // Ensure the shortcode name is complete, so e.g. [name_other] isn't matched.
278 300 . '[^\]]*?\]/i'; // Match any other characters (non-greedy) up to the closing square bracket, case-insensitive.
279 - } else {
301 +
302 + return preg_replace(
303 + $pattern,
304 + '[convertkit_form form="' . $form_id . '"]',
305 + $content
306 + );
307 + }
308 +
309 + // Normalise the shortcode ID attribute to an array, so importers can
310 + // declare a single attribute (string) or multiple attributes (array).
311 + $id_attributes = (array) $this->shortcode_id_attribute;
312 +
313 + // Run a replacement pass per attribute name.
314 + foreach ( $id_attributes as $id_attribute ) {
280 315 $pattern = '/\[' // Start regex with an opening square bracket.
281 316 . preg_quote( $this->shortcode_name, '/' ) // Match the shortcode name, escaping any regex special chars.
317 + . '(?=[\s\]\/])' // Ensure the shortcode name is complete, so e.g. [name_other] isn't matched.
282 318 . '[^\]]*?' // Match any characters that are not a closing square bracket, non-greedy.
283 - . '\b' . preg_quote( $this->shortcode_id_attribute, '/' ) // Match the id attribute word boundary and escape as needed.
319 + . '\s' . preg_quote( $id_attribute, '/' ) // Match the id attribute, preceded by whitespace so e.g. data-id isn't matched.
284 320 . '\s*=\s*' // Match optional whitespace around an equals sign.
285 - . '(?:"' . preg_quote( (string) $third_party_form_id, '/' ) . '"|\'' . preg_quote( (string) $third_party_form_id, '/' ) . '\'|' . preg_quote( (string) $third_party_form_id, '/' ) . ')' // Match the form ID, double quotes, single quotes or unquoted.
321 + . '(?:"' . preg_quote( (string) $third_party_form_id, '/' ) . '"|\'' . preg_quote( (string) $third_party_form_id, '/' ) . '\'|' . preg_quote( (string) $third_party_form_id, '/' ) . '(?=[\s\]\/]))' // Match the exact form ID, double quotes, single quotes or unquoted.
286 322 . '[^\]]*?\]/i'; // Match any other characters (non-greedy) up to the closing square bracket, case-insensitive.
323 +
324 + $content = preg_replace(
325 + $pattern,
326 + '[convertkit_form form="' . $form_id . '"]',
327 + $content
328 + );
287 329 }
288 330
289 - return preg_replace(
290 - $pattern,
291 - '[convertkit_form id="' . $form_id . '"]',
292 - $content
293 - );
331 + return $content;
294 332
295 333 }
296 334
297 335 /**
@@ -345,8 +383,9 @@
345 383 // If there's no shortcode ID attribute, match shortcodes with or without any attribute and treat any match as a single "form".
346 384 if ( ! $this->shortcode_id_attribute ) {
347 385 $pattern = '/\[' // Start regex with an opening square bracket.
348 386 . preg_quote( $this->shortcode_name, '/' ) // Match the shortcode name, escaping any regex special chars.
387 + . '(?=[\s\]\/])' // Ensure the shortcode name is complete, so e.g. [name_other] isn't matched.
349 388 . '(?:\s+[^\]]*)?' // Optionally match any attributes (key/value pairs), non-greedy.
350 389 . '[^\]]*?\]/i'; // Match up to closing bracket, case-insensitive.
351 390
352 391 preg_match_all( $pattern, $content, $matches );
@@ -358,31 +397,40 @@
358 397
359 398 return array();
360 399 }
361 400
362 - // Legacy: Extract where attribute is required.
363 - $pattern = '/\[' // Start regex with an opening square bracket.
364 - . preg_quote( $this->shortcode_name, '/' ) // Match the shortcode name, escaping any regex special chars.
365 - . '(?:\s+[^\]]*)?' // Optionally match any attributes (key/value pairs), non-greedy.
366 - . preg_quote( $this->shortcode_id_attribute, '/' ) // Match the id attribute name.
367 - . '\s*=\s*' // Optional whitespace, equals sign, optional whitespace.
368 - . '(?:"([^"]+)"|\'([^\']+)\'|([^\s\]]+))' // Capture double quoted, single quoted or unquoted value.
369 - . '[^\]]*?\]/i'; // Match up to closing bracket, case-insensitive.
401 + // Normalise the shortcode ID attribute to an array, so importers can
402 + // declare a single attribute (string) or multiple attributes (array).
403 + $id_attributes = (array) $this->shortcode_id_attribute;
370 404
371 - preg_match_all( $pattern, $content, $matches );
405 + // Extract form IDs, running a match pass per attribute name.
406 + $form_ids = array();
407 + foreach ( $id_attributes as $id_attribute ) {
408 + $pattern = '/\[' // Start regex with an opening square bracket.
409 + . preg_quote( $this->shortcode_name, '/' ) // Match the shortcode name, escaping any regex special chars.
410 + . '(?=[\s\]\/])' // Ensure the shortcode name is complete, so e.g. [name_other] isn't matched.
411 + . '(?:\s+[^\]]*)?' // Optionally match any attributes (key/value pairs), non-greedy.
412 + . preg_quote( $id_attribute, '/' ) // Match the id attribute name.
413 + . '\s*=\s*' // Optional whitespace, equals sign, optional whitespace.
414 + . '(?:"([^"]+)"|\'([^\']+)\'|([^\s\]]+))' // Capture double quoted, single quoted or unquoted value.
415 + . '[^\]]*?\]/i'; // Match up to closing bracket, case-insensitive.
372 416
373 - // Extract form IDs: They could be in either $matches[1] (double quoted), $matches[2] (single quoted) or $matches[3] (unquoted).
374 - $form_ids = array_values(
375 - array_filter(
376 - array_merge(
377 - isset( $matches[1] ) ? $matches[1] : array(),
378 - isset( $matches[2] ) ? $matches[2] : array(),
379 - isset( $matches[3] ) ? $matches[3] : array()
417 + preg_match_all( $pattern, $content, $matches );
418 +
419 + // Extract form IDs: They could be in either $matches[1] (double quoted), $matches[2] (single quoted) or $matches[3] (unquoted).
420 + $form_ids = array_merge(
421 + $form_ids,
422 + array_filter(
423 + array_merge(
424 + isset( $matches[1] ) ? $matches[1] : array(),
425 + isset( $matches[2] ) ? $matches[2] : array(),
426 + isset( $matches[3] ) ? $matches[3] : array()
427 + )
380 428 )
381 - )
382 - );
429 + );
430 + }
383 431
384 - return $form_ids;
432 + return array_values( array_unique( $form_ids ) );
385 433
386 434 }
387 435
388 436 /**
@@ -496,9 +544,9 @@
496 544 continue;
497 545 }
498 546
499 547 // Skip if not a third party form block.
500 - if ( strpos( $block['blockName'], $this->block_name ) === false ) {
548 + if ( $block['blockName'] !== $this->block_name ) {
501 549 continue;
502 550 }
503 551
504 552 // If the block ID attribute is not set, the third party Plugin doesn't use IDs,
@@ -503,15 +551,29 @@
503 551
504 552 // If the block ID attribute is not set, the third party Plugin doesn't use IDs,
505 553 // so there's no need to check the $third_party_form_id matches the block attribute.
506 554 if ( $this->block_id_attribute ) {
507 - // Skip if the attribute doesn't exist i.e. the block was not configured.
508 - if ( ! array_key_exists( $this->block_id_attribute, $block['attrs'] ) ) {
509 - continue;
555 + // Normalise the block ID attribute to an array, so importers can
556 + // declare a single attribute (string) or multiple attributes (array).
557 + $id_attributes = (array) $this->block_id_attribute;
558 +
559 + // Check if at least one attribute contains the third party form ID.
560 + $matched = false;
561 + foreach ( $id_attributes as $id_attribute ) {
562 + if ( ! array_key_exists( $id_attribute, $block['attrs'] ) ) {
563 + continue;
564 + }
565 +
566 + if ( ! $this->block_id_attribute_matches( $block['attrs'][ $id_attribute ], $third_party_form_id ) ) {
567 + continue;
568 + }
569 +
570 + $matched = true;
571 + break;
510 572 }
511 573
512 - // Skip if the third party form ID doesn't exist within the third party form block's attribute.
513 - if ( stripos( $block['attrs'][ $this->block_id_attribute ], (string) $third_party_form_id ) === false ) {
574 + // Skip if none of the configured ID attributes match.
575 + if ( ! $matched ) {
514 576 continue;
515 577 }
516 578 }
517 579
@@ -527,8 +589,23 @@
527 589 );
528 590 }
529 591
530 592 return $blocks;
593 +
594 + }
595 +
596 + /**
597 + * Returns whether the given block ID attribute value matches the third party form ID.
598 + *
599 + * @since 3.4.5
600 + *
601 + * @param mixed $value Block ID attribute value.
602 + * @param string|int $third_party_form_id Third Party Form ID.
603 + * @return bool
604 + */
605 + protected function block_id_attribute_matches( $value, $third_party_form_id ) {
606 +
607 + return (string) $value === (string) $third_party_form_id;
531 608
532 609 }
533 610
534 611 }